// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

// This is a generated file.

/// A library for asserting correct responses from the VM Service.

import 'package:vm_service/vm_service.dart' as vms;

dynamic assertNotNull(dynamic obj) {
  if (obj == null) throw 'assert failed';
  return obj;
}

bool assertBool(bool obj) {
  return obj;
}

int assertInt(int obj) {
  return obj;
}

double assertDouble(double obj) {
  return obj;
}

dynamic assertDynamic(dynamic obj) {
  assertNotNull(obj);
  return obj;
}

List<dynamic> assertListOfDynamic(List<dynamic> list) {
  return list;
}

List<int> assertListOfInt(List<int> list) {
  for (int elem in list) {
    assertInt(elem);
  }
  return list;
}

List<String> assertListOfString(List<String> list) {
  for (String elem in list) {
    assertString(elem);
  }
  return list;
}

List<vms.IsolateFlag> assertListOfIsolateFlag(List<vms.IsolateFlag> list) {
  for (vms.IsolateFlag elem in list) {
    assertIsolateFlag(elem);
  }
  return list;
}

String assertString(String obj) {
  if (obj.isEmpty) throw 'expected non-zero length string';
  return obj;
}

vms.Success assertSuccess(vms.Success obj) {
  if (obj.type != 'Success') throw 'expected Success';
  return obj;
}

/// Assert PauseStart, PauseExit, PauseBreakpoint, PauseInterrupted,
/// PauseException, Resume, BreakpointAdded, BreakpointResolved,
/// BreakpointRemoved, and Inspect events.
vms.Event assertDebugEvent(vms.Event event) {
  assertEvent(event);
  if (event.kind == vms.EventKind.kPauseBreakpoint ||
      event.kind == vms.EventKind.kBreakpointAdded ||
      event.kind == vms.EventKind.kBreakpointRemoved ||
      event.kind == vms.EventKind.kBreakpointResolved) {
    assertBreakpoint(event.breakpoint!);
  }
  if (event.kind == vms.EventKind.kPauseBreakpoint) {
    for (vms.Breakpoint elem in event.pauseBreakpoints!) {
      assertBreakpoint(elem);
    }
  }
  if (event.kind == vms.EventKind.kPauseBreakpoint ||
      event.kind == vms.EventKind.kPauseInterrupted ||
      event.kind == vms.EventKind.kPauseException ||
      event.kind == vms.EventKind.kResume) {
    // For PauseInterrupted events, there will be no top frame if the isolate is
    // idle (waiting in the message loop).
    // For the Resume event, the top frame is provided at all times except for
    // the initial resume event that is delivered when an isolate begins
    // execution.
    if (event.topFrame != null ||
        (event.kind != vms.EventKind.kPauseInterrupted &&
            event.kind != vms.EventKind.kResume)) {
      assertFrame(event.topFrame!);
    }
  }
  if (event.kind == vms.EventKind.kPauseException) {
    assertInstanceRef(event.exception!);
  }
  if (event.kind == vms.EventKind.kPauseBreakpoint ||
      event.kind == vms.EventKind.kPauseInterrupted) {
    assertBool(event.atAsyncSuspension!);
  }
  if (event.kind == vms.EventKind.kInspect) {
    assertInstanceRef(event.inspectee!);
  }
  return event;
}

/// Assert IsolateStart, IsolateRunnable, IsolateExit, IsolateUpdate,
/// and ServiceExtensionAdded events.
vms.Event assertIsolateEvent(vms.Event event) {
  assertEvent(event);
  if (event.kind == vms.EventKind.kServiceExtensionAdded) {
    assertString(event.extensionRPC!);
  }
  return event;
}

String assertCodeKind(String obj) {
  if (obj == "Collected") return obj;
  if (obj == "Dart") return obj;
  if (obj == "Native") return obj;
  if (obj == "Stub") return obj;
  if (obj == "Tag") return obj;
  throw "invalid CodeKind: $obj";
}

String assertErrorKind(String obj) {
  if (obj == "InternalError") return obj;
  if (obj == "LanguageError") return obj;
  if (obj == "TerminationError") return obj;
  if (obj == "UnhandledException") return obj;
  throw "invalid ErrorKind: $obj";
}

String assertEventKind(String obj) {
  if (obj == "BreakpointAdded") return obj;
  if (obj == "BreakpointRemoved") return obj;
  if (obj == "BreakpointResolved") return obj;
  if (obj == "BreakpointUpdated") return obj;
  if (obj == "CpuSamples") return obj;
  if (obj == "Extension") return obj;
  if (obj == "GC") return obj;
  if (obj == "Inspect") return obj;
  if (obj == "IsolateExit") return obj;
  if (obj == "IsolateReload") return obj;
  if (obj == "IsolateRunnable") return obj;
  if (obj == "IsolateStart") return obj;
  if (obj == "IsolateUpdate") return obj;
  if (obj == "Logging") return obj;
  if (obj == "None") return obj;
  if (obj == "PauseBreakpoint") return obj;
  if (obj == "PauseException") return obj;
  if (obj == "PauseExit") return obj;
  if (obj == "PauseInterrupted") return obj;
  if (obj == "PausePostRequest") return obj;
  if (obj == "PauseStart") return obj;
  if (obj == "Resume") return obj;
  if (obj == "ServiceExtensionAdded") return obj;
  if (obj == "ServiceRegistered") return obj;
  if (obj == "ServiceUnregistered") return obj;
  if (obj == "TimelineEvents") return obj;
  if (obj == "TimelineStreamSubscriptionsUpdate") return obj;
  if (obj == "UserTagChanged") return obj;
  if (obj == "VMFlagUpdate") return obj;
  if (obj == "VMUpdate") return obj;
  if (obj == "WriteEvent") return obj;
  throw "invalid EventKind: $obj";
}

String assertInstanceKind(String obj) {
  if (obj == "Bool") return obj;
  if (obj == "BoundedType") return obj;
  if (obj == "Closure") return obj;
  if (obj == "Double") return obj;
  if (obj == "Float32List") return obj;
  if (obj == "Float32x4") return obj;
  if (obj == "Float32x4List") return obj;
  if (obj == "Float64List") return obj;
  if (obj == "Float64x2") return obj;
  if (obj == "Float64x2List") return obj;
  if (obj == "FunctionType") return obj;
  if (obj == "Int") return obj;
  if (obj == "Int16List") return obj;
  if (obj == "Int32List") return obj;
  if (obj == "Int32x4") return obj;
  if (obj == "Int32x4List") return obj;
  if (obj == "Int64List") return obj;
  if (obj == "Int8List") return obj;
  if (obj == "List") return obj;
  if (obj == "Map") return obj;
  if (obj == "MirrorReference") return obj;
  if (obj == "Null") return obj;
  if (obj == "PlainInstance") return obj;
  if (obj == "ReceivePort") return obj;
  if (obj == "RegExp") return obj;
  if (obj == "StackTrace") return obj;
  if (obj == "String") return obj;
  if (obj == "Type") return obj;
  if (obj == "TypeParameter") return obj;
  if (obj == "TypeRef") return obj;
  if (obj == "Uint16List") return obj;
  if (obj == "Uint32List") return obj;
  if (obj == "Uint64List") return obj;
  if (obj == "Uint8ClampedList") return obj;
  if (obj == "Uint8List") return obj;
  if (obj == "WeakProperty") return obj;
  throw "invalid InstanceKind: $obj";
}

String assertSentinelKind(String obj) {
  if (obj == "BeingInitialized") return obj;
  if (obj == "Collected") return obj;
  if (obj == "Expired") return obj;
  if (obj == "Free") return obj;
  if (obj == "NotInitialized") return obj;
  if (obj == "OptimizedOut") return obj;
  throw "invalid SentinelKind: $obj";
}

String assertFrameKind(String obj) {
  if (obj == "AsyncActivation") return obj;
  if (obj == "AsyncCausal") return obj;
  if (obj == "AsyncSuspensionMarker") return obj;
  if (obj == "Regular") return obj;
  throw "invalid FrameKind: $obj";
}

String assertSourceReportKind(String obj) {
  if (obj == "BranchCoverage") return obj;
  if (obj == "Coverage") return obj;
  if (obj == "PossibleBreakpoints") return obj;
  throw "invalid SourceReportKind: $obj";
}

String assertExceptionPauseMode(String obj) {
  if (obj == "All") return obj;
  if (obj == "None") return obj;
  if (obj == "Unhandled") return obj;
  throw "invalid ExceptionPauseMode: $obj";
}

String assertStepOption(String obj) {
  if (obj == "Into") return obj;
  if (obj == "Out") return obj;
  if (obj == "Over") return obj;
  if (obj == "OverAsyncSuspension") return obj;
  if (obj == "Rewind") return obj;
  throw "invalid StepOption: $obj";
}

vms.AllocationProfile assertAllocationProfile(vms.AllocationProfile obj) {
  assertNotNull(obj);
  assertListOfClassHeapStats(obj.members!);
  assertMemoryUsage(obj.memoryUsage!);
  return obj;
}

vms.BoundField assertBoundField(vms.BoundField obj) {
  assertNotNull(obj);
  assertFieldRef(obj.decl!);
  if (obj.value is vms.InstanceRef) {
    assertInstanceRef(obj.value!);
  } else if (obj.value is vms.Sentinel) {
    assertSentinel(obj.value!);
  } else {
    throw "Unexpected value: ${obj.value}";
  }
  return obj;
}

vms.BoundVariable assertBoundVariable(vms.BoundVariable obj) {
  assertNotNull(obj);
  assertString(obj.name!);
  if (obj.value is vms.InstanceRef) {
    assertInstanceRef(obj.value!);
  } else if (obj.value is vms.TypeArgumentsRef) {
    assertTypeArgumentsRef(obj.value!);
  } else if (obj.value is vms.Sentinel) {
    assertSentinel(obj.value!);
  } else {
    throw "Unexpected value: ${obj.value}";
  }
  assertInt(obj.declarationTokenPos!);
  assertInt(obj.scopeStartTokenPos!);
  assertInt(obj.scopeEndTokenPos!);
  return obj;
}

List<vms.BoundVariable> assertListOfBoundVariable(
    List<vms.BoundVariable> list) {
  for (vms.BoundVariable elem in list) {
    assertBoundVariable(elem);
  }
  return list;
}

vms.Breakpoint assertBreakpoint(vms.Breakpoint obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertInt(obj.breakpointNumber!);
  assertBool(obj.enabled!);
  assertBool(obj.resolved!);
  if (obj.location is vms.SourceLocation) {
    assertSourceLocation(obj.location!);
  } else if (obj.location is vms.UnresolvedSourceLocation) {
    assertUnresolvedSourceLocation(obj.location!);
  } else {
    throw "Unexpected value: ${obj.location}";
  }
  return obj;
}

List<vms.Breakpoint> assertListOfBreakpoint(List<vms.Breakpoint> list) {
  for (vms.Breakpoint elem in list) {
    assertBreakpoint(elem);
  }
  return list;
}

vms.ClassRef assertClassRef(vms.ClassRef obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertString(obj.name!);
  assertLibraryRef(obj.library!);
  return obj;
}

List<vms.ClassRef> assertListOfClassRef(List<vms.ClassRef> list) {
  for (vms.ClassRef elem in list) {
    assertClassRef(elem);
  }
  return list;
}

vms.Class assertClass(vms.Class obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertString(obj.name!);
  assertLibraryRef(obj.library!);
  assertBool(obj.isAbstract!);
  assertBool(obj.isConst!);
  assertBool(obj.traceAllocations!);
  assertListOfInstanceRef(obj.interfaces!);
  assertListOfFieldRef(obj.fields!);
  assertListOfFuncRef(obj.functions!);
  assertListOfClassRef(obj.subclasses!);
  return obj;
}

vms.ClassHeapStats assertClassHeapStats(vms.ClassHeapStats obj) {
  assertNotNull(obj);
  assertClassRef(obj.classRef!);
  assertInt(obj.accumulatedSize!);
  assertInt(obj.bytesCurrent!);
  assertInt(obj.instancesAccumulated!);
  assertInt(obj.instancesCurrent!);
  return obj;
}

List<vms.ClassHeapStats> assertListOfClassHeapStats(
    List<vms.ClassHeapStats> list) {
  for (vms.ClassHeapStats elem in list) {
    assertClassHeapStats(elem);
  }
  return list;
}

vms.ClassList assertClassList(vms.ClassList obj) {
  assertNotNull(obj);
  assertListOfClassRef(obj.classes!);
  return obj;
}

vms.CodeRef assertCodeRef(vms.CodeRef obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertString(obj.name!);
  assertCodeKind(obj.kind!);
  return obj;
}

List<vms.CodeRef> assertListOfCodeRef(List<vms.CodeRef> list) {
  for (vms.CodeRef elem in list) {
    assertCodeRef(elem);
  }
  return list;
}

vms.Code assertCode(vms.Code obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertString(obj.name!);
  assertCodeKind(obj.kind!);
  return obj;
}

vms.ContextRef assertContextRef(vms.ContextRef obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertInt(obj.length!);
  return obj;
}

List<vms.ContextRef> assertListOfContextRef(List<vms.ContextRef> list) {
  for (vms.ContextRef elem in list) {
    assertContextRef(elem);
  }
  return list;
}

vms.Context assertContext(vms.Context obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertInt(obj.length!);
  assertListOfContextElement(obj.variables!);
  return obj;
}

vms.ContextElement assertContextElement(vms.ContextElement obj) {
  assertNotNull(obj);
  if (obj.value is vms.InstanceRef) {
    assertInstanceRef(obj.value!);
  } else if (obj.value is vms.Sentinel) {
    assertSentinel(obj.value!);
  } else {
    throw "Unexpected value: ${obj.value}";
  }
  return obj;
}

List<vms.ContextElement> assertListOfContextElement(
    List<vms.ContextElement> list) {
  for (vms.ContextElement elem in list) {
    assertContextElement(elem);
  }
  return list;
}

vms.CpuSamples assertCpuSamples(vms.CpuSamples obj) {
  assertNotNull(obj);
  assertInt(obj.samplePeriod!);
  assertInt(obj.maxStackDepth!);
  assertInt(obj.sampleCount!);
  assertInt(obj.timeSpan!);
  assertInt(obj.timeOriginMicros!);
  assertInt(obj.timeExtentMicros!);
  assertInt(obj.pid!);
  assertListOfProfileFunction(obj.functions!);
  assertListOfCpuSample(obj.samples!);
  return obj;
}

vms.CpuSamplesEvent assertCpuSamplesEvent(vms.CpuSamplesEvent obj) {
  assertNotNull(obj);
  assertInt(obj.samplePeriod!);
  assertInt(obj.maxStackDepth!);
  assertInt(obj.sampleCount!);
  assertInt(obj.timeSpan!);
  assertInt(obj.timeOriginMicros!);
  assertInt(obj.timeExtentMicros!);
  assertInt(obj.pid!);
  assertListOfDynamic(obj.functions!);
  assertListOfCpuSample(obj.samples!);
  return obj;
}

vms.CpuSample assertCpuSample(vms.CpuSample obj) {
  assertNotNull(obj);
  assertInt(obj.tid!);
  assertInt(obj.timestamp!);
  assertListOfInt(obj.stack!);
  return obj;
}

List<vms.CpuSample> assertListOfCpuSample(List<vms.CpuSample> list) {
  for (vms.CpuSample elem in list) {
    assertCpuSample(elem);
  }
  return list;
}

vms.ErrorRef assertErrorRef(vms.ErrorRef obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertErrorKind(obj.kind!);
  assertString(obj.message!);
  return obj;
}

List<vms.ErrorRef> assertListOfErrorRef(List<vms.ErrorRef> list) {
  for (vms.ErrorRef elem in list) {
    assertErrorRef(elem);
  }
  return list;
}

vms.Error assertError(vms.Error obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertErrorKind(obj.kind!);
  assertString(obj.message!);
  return obj;
}

vms.Event assertEvent(vms.Event obj) {
  assertNotNull(obj);
  assertEventKind(obj.kind!);
  assertInt(obj.timestamp!);
  return obj;
}

vms.ExtensionData assertExtensionData(vms.ExtensionData obj) {
  assertNotNull(obj);
  return obj;
}

vms.FieldRef assertFieldRef(vms.FieldRef obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertString(obj.name!);
  assertObjRef(obj.owner!);
  assertInstanceRef(obj.declaredType!);
  assertBool(obj.isConst!);
  assertBool(obj.isFinal!);
  assertBool(obj.isStatic!);
  return obj;
}

List<vms.FieldRef> assertListOfFieldRef(List<vms.FieldRef> list) {
  for (vms.FieldRef elem in list) {
    assertFieldRef(elem);
  }
  return list;
}

vms.Field assertField(vms.Field obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertString(obj.name!);
  assertObjRef(obj.owner!);
  assertInstanceRef(obj.declaredType!);
  assertBool(obj.isConst!);
  assertBool(obj.isFinal!);
  assertBool(obj.isStatic!);
  return obj;
}

vms.Flag assertFlag(vms.Flag obj) {
  assertNotNull(obj);
  assertString(obj.name!);
  assertString(obj.comment!);
  assertBool(obj.modified!);
  return obj;
}

List<vms.Flag> assertListOfFlag(List<vms.Flag> list) {
  for (vms.Flag elem in list) {
    assertFlag(elem);
  }
  return list;
}

vms.FlagList assertFlagList(vms.FlagList obj) {
  assertNotNull(obj);
  assertListOfFlag(obj.flags!);
  return obj;
}

vms.Frame assertFrame(vms.Frame obj) {
  assertNotNull(obj);
  assertInt(obj.index!);
  return obj;
}

List<vms.Frame> assertListOfFrame(List<vms.Frame> list) {
  for (vms.Frame elem in list) {
    assertFrame(elem);
  }
  return list;
}

vms.FuncRef assertFuncRef(vms.FuncRef obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertString(obj.name!);
  if (obj.owner is vms.LibraryRef) {
    assertLibraryRef(obj.owner!);
  } else if (obj.owner is vms.ClassRef) {
    assertClassRef(obj.owner!);
  } else if (obj.owner is vms.FuncRef) {
    assertFuncRef(obj.owner!);
  } else {
    throw "Unexpected value: ${obj.owner}";
  }
  assertBool(obj.isStatic!);
  assertBool(obj.isConst!);
  assertBool(obj.implicit!);
  return obj;
}

List<vms.FuncRef> assertListOfFuncRef(List<vms.FuncRef> list) {
  for (vms.FuncRef elem in list) {
    assertFuncRef(elem);
  }
  return list;
}

vms.Func assertFunc(vms.Func obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertString(obj.name!);
  if (obj.owner is vms.LibraryRef) {
    assertLibraryRef(obj.owner!);
  } else if (obj.owner is vms.ClassRef) {
    assertClassRef(obj.owner!);
  } else if (obj.owner is vms.FuncRef) {
    assertFuncRef(obj.owner!);
  } else {
    throw "Unexpected value: ${obj.owner}";
  }
  assertBool(obj.isStatic!);
  assertBool(obj.isConst!);
  assertBool(obj.implicit!);
  assertInstanceRef(obj.signature!);
  return obj;
}

vms.InstanceRef assertInstanceRef(vms.InstanceRef obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertInstanceKind(obj.kind!);
  assertInt(obj.identityHashCode!);
  assertClassRef(obj.classRef!);
  return obj;
}

List<vms.InstanceRef> assertListOfInstanceRef(List<vms.InstanceRef> list) {
  for (vms.InstanceRef elem in list) {
    assertInstanceRef(elem);
  }
  return list;
}

vms.Instance assertInstance(vms.Instance obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertInstanceKind(obj.kind!);
  assertInt(obj.identityHashCode!);
  assertClassRef(obj.classRef!);
  return obj;
}

vms.IsolateRef assertIsolateRef(vms.IsolateRef obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertString(obj.number!);
  assertString(obj.name!);
  assertBool(obj.isSystemIsolate!);
  return obj;
}

List<vms.IsolateRef> assertListOfIsolateRef(List<vms.IsolateRef> list) {
  for (vms.IsolateRef elem in list) {
    assertIsolateRef(elem);
  }
  return list;
}

vms.Isolate assertIsolate(vms.Isolate obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertString(obj.number!);
  assertString(obj.name!);
  assertBool(obj.isSystemIsolate!);
  assertListOfIsolateFlag(obj.isolateFlags!);
  assertInt(obj.startTime!);
  assertBool(obj.runnable!);
  assertInt(obj.livePorts!);
  assertBool(obj.pauseOnExit!);
  assertEvent(obj.pauseEvent!);
  assertListOfLibraryRef(obj.libraries!);
  assertListOfBreakpoint(obj.breakpoints!);
  assertExceptionPauseMode(obj.exceptionPauseMode!);
  return obj;
}

vms.IsolateFlag assertIsolateFlag(vms.IsolateFlag obj) {
  assertNotNull(obj);
  assertString(obj.name!);
  assertString(obj.valueAsString!);
  return obj;
}

vms.IsolateGroupRef assertIsolateGroupRef(vms.IsolateGroupRef obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertString(obj.number!);
  assertString(obj.name!);
  assertBool(obj.isSystemIsolateGroup!);
  return obj;
}

List<vms.IsolateGroupRef> assertListOfIsolateGroupRef(
    List<vms.IsolateGroupRef> list) {
  for (vms.IsolateGroupRef elem in list) {
    assertIsolateGroupRef(elem);
  }
  return list;
}

vms.IsolateGroup assertIsolateGroup(vms.IsolateGroup obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertString(obj.number!);
  assertString(obj.name!);
  assertBool(obj.isSystemIsolateGroup!);
  assertListOfIsolateRef(obj.isolates!);
  return obj;
}

vms.InboundReferences assertInboundReferences(vms.InboundReferences obj) {
  assertNotNull(obj);
  assertListOfInboundReference(obj.references!);
  return obj;
}

vms.InboundReference assertInboundReference(vms.InboundReference obj) {
  assertNotNull(obj);
  assertObjRef(obj.source!);
  return obj;
}

List<vms.InboundReference> assertListOfInboundReference(
    List<vms.InboundReference> list) {
  for (vms.InboundReference elem in list) {
    assertInboundReference(elem);
  }
  return list;
}

vms.InstanceSet assertInstanceSet(vms.InstanceSet obj) {
  assertNotNull(obj);
  assertInt(obj.totalCount!);
  assertListOfObjRef(obj.instances!);
  return obj;
}

vms.LibraryRef assertLibraryRef(vms.LibraryRef obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertString(obj.name!);
  assertString(obj.uri!);
  return obj;
}

List<vms.LibraryRef> assertListOfLibraryRef(List<vms.LibraryRef> list) {
  for (vms.LibraryRef elem in list) {
    assertLibraryRef(elem);
  }
  return list;
}

vms.Library assertLibrary(vms.Library obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertString(obj.name!);
  assertString(obj.uri!);
  assertBool(obj.debuggable!);
  assertListOfLibraryDependency(obj.dependencies!);
  assertListOfScriptRef(obj.scripts!);
  assertListOfFieldRef(obj.variables!);
  assertListOfFuncRef(obj.functions!);
  assertListOfClassRef(obj.classes!);
  return obj;
}

vms.LibraryDependency assertLibraryDependency(vms.LibraryDependency obj) {
  assertNotNull(obj);
  assertBool(obj.isImport!);
  assertBool(obj.isDeferred!);
  assertString(obj.prefix!);
  assertLibraryRef(obj.target!);
  return obj;
}

List<vms.LibraryDependency> assertListOfLibraryDependency(
    List<vms.LibraryDependency> list) {
  for (vms.LibraryDependency elem in list) {
    assertLibraryDependency(elem);
  }
  return list;
}

vms.LogRecord assertLogRecord(vms.LogRecord obj) {
  assertNotNull(obj);
  assertInstanceRef(obj.message!);
  assertInt(obj.time!);
  assertInt(obj.level!);
  assertInt(obj.sequenceNumber!);
  assertInstanceRef(obj.loggerName!);
  assertInstanceRef(obj.zone!);
  assertInstanceRef(obj.error!);
  assertInstanceRef(obj.stackTrace!);
  return obj;
}

vms.MapAssociation assertMapAssociation(vms.MapAssociation obj) {
  assertNotNull(obj);
  if (obj.key is vms.InstanceRef) {
    assertInstanceRef(obj.key!);
  } else if (obj.key is vms.Sentinel) {
    assertSentinel(obj.key!);
  } else {
    throw "Unexpected value: ${obj.key}";
  }
  if (obj.value is vms.InstanceRef) {
    assertInstanceRef(obj.value!);
  } else if (obj.value is vms.Sentinel) {
    assertSentinel(obj.value!);
  } else {
    throw "Unexpected value: ${obj.value}";
  }
  return obj;
}

vms.MemoryUsage assertMemoryUsage(vms.MemoryUsage obj) {
  assertNotNull(obj);
  assertInt(obj.externalUsage!);
  assertInt(obj.heapCapacity!);
  assertInt(obj.heapUsage!);
  return obj;
}

vms.Message assertMessage(vms.Message obj) {
  assertNotNull(obj);
  assertInt(obj.index!);
  assertString(obj.name!);
  assertString(obj.messageObjectId!);
  assertInt(obj.size!);
  return obj;
}

List<vms.Message> assertListOfMessage(List<vms.Message> list) {
  for (vms.Message elem in list) {
    assertMessage(elem);
  }
  return list;
}

vms.NativeFunction assertNativeFunction(vms.NativeFunction obj) {
  assertNotNull(obj);
  assertString(obj.name!);
  return obj;
}

vms.NullValRef assertNullValRef(vms.NullValRef obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertInstanceKind(obj.kind!);
  assertInt(obj.identityHashCode!);
  assertClassRef(obj.classRef!);
  assertString(obj.valueAsString!);
  return obj;
}

List<vms.NullValRef> assertListOfNullValRef(List<vms.NullValRef> list) {
  for (vms.NullValRef elem in list) {
    assertNullValRef(elem);
  }
  return list;
}

vms.NullVal assertNullVal(vms.NullVal obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertInstanceKind(obj.kind!);
  assertInt(obj.identityHashCode!);
  assertClassRef(obj.classRef!);
  assertString(obj.valueAsString!);
  return obj;
}

vms.ObjRef assertObjRef(vms.ObjRef obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  return obj;
}

List<vms.ObjRef> assertListOfObjRef(List<vms.ObjRef> list) {
  for (vms.ObjRef elem in list) {
    assertObjRef(elem);
  }
  return list;
}

vms.Obj assertObj(vms.Obj obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  return obj;
}

vms.Parameter assertParameter(vms.Parameter obj) {
  assertNotNull(obj);
  assertInstanceRef(obj.parameterType!);
  assertBool(obj.fixed!);
  return obj;
}

vms.PortList assertPortList(vms.PortList obj) {
  assertNotNull(obj);
  assertListOfInstanceRef(obj.ports!);
  return obj;
}

vms.ProfileFunction assertProfileFunction(vms.ProfileFunction obj) {
  assertNotNull(obj);
  assertString(obj.kind!);
  assertInt(obj.inclusiveTicks!);
  assertInt(obj.exclusiveTicks!);
  assertString(obj.resolvedUrl!);
  assertDynamic(obj.function!);
  return obj;
}

List<vms.ProfileFunction> assertListOfProfileFunction(
    List<vms.ProfileFunction> list) {
  for (vms.ProfileFunction elem in list) {
    assertProfileFunction(elem);
  }
  return list;
}

vms.ProtocolList assertProtocolList(vms.ProtocolList obj) {
  assertNotNull(obj);
  assertListOfProtocol(obj.protocols!);
  return obj;
}

vms.Protocol assertProtocol(vms.Protocol obj) {
  assertNotNull(obj);
  assertString(obj.protocolName!);
  assertInt(obj.major!);
  assertInt(obj.minor!);
  return obj;
}

List<vms.Protocol> assertListOfProtocol(List<vms.Protocol> list) {
  for (vms.Protocol elem in list) {
    assertProtocol(elem);
  }
  return list;
}

vms.ProcessMemoryUsage assertProcessMemoryUsage(vms.ProcessMemoryUsage obj) {
  assertNotNull(obj);
  assertProcessMemoryItem(obj.root!);
  return obj;
}

vms.ProcessMemoryItem assertProcessMemoryItem(vms.ProcessMemoryItem obj) {
  assertNotNull(obj);
  assertString(obj.name!);
  assertString(obj.description!);
  assertInt(obj.size!);
  assertListOfProcessMemoryItem(obj.children!);
  return obj;
}

List<vms.ProcessMemoryItem> assertListOfProcessMemoryItem(
    List<vms.ProcessMemoryItem> list) {
  for (vms.ProcessMemoryItem elem in list) {
    assertProcessMemoryItem(elem);
  }
  return list;
}

vms.ReloadReport assertReloadReport(vms.ReloadReport obj) {
  assertNotNull(obj);
  assertBool(obj.success!);
  return obj;
}

vms.RetainingObject assertRetainingObject(vms.RetainingObject obj) {
  assertNotNull(obj);
  assertObjRef(obj.value!);
  return obj;
}

List<vms.RetainingObject> assertListOfRetainingObject(
    List<vms.RetainingObject> list) {
  for (vms.RetainingObject elem in list) {
    assertRetainingObject(elem);
  }
  return list;
}

vms.RetainingPath assertRetainingPath(vms.RetainingPath obj) {
  assertNotNull(obj);
  assertInt(obj.length!);
  assertString(obj.gcRootType!);
  assertListOfRetainingObject(obj.elements!);
  return obj;
}

vms.Response assertResponse(vms.Response obj) {
  assertNotNull(obj);
  return obj;
}

vms.Sentinel assertSentinel(vms.Sentinel obj) {
  assertNotNull(obj);
  assertSentinelKind(obj.kind!);
  assertString(obj.valueAsString!);
  return obj;
}

vms.ScriptRef assertScriptRef(vms.ScriptRef obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertString(obj.uri!);
  return obj;
}

List<vms.ScriptRef> assertListOfScriptRef(List<vms.ScriptRef> list) {
  for (vms.ScriptRef elem in list) {
    assertScriptRef(elem);
  }
  return list;
}

vms.Script assertScript(vms.Script obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertString(obj.uri!);
  assertLibraryRef(obj.library!);
  return obj;
}

vms.ScriptList assertScriptList(vms.ScriptList obj) {
  assertNotNull(obj);
  assertListOfScriptRef(obj.scripts!);
  return obj;
}

vms.SourceLocation assertSourceLocation(vms.SourceLocation obj) {
  assertNotNull(obj);
  assertScriptRef(obj.script!);
  assertInt(obj.tokenPos!);
  return obj;
}

vms.SourceReport assertSourceReport(vms.SourceReport obj) {
  assertNotNull(obj);
  assertListOfSourceReportRange(obj.ranges!);
  assertListOfScriptRef(obj.scripts!);
  return obj;
}

vms.SourceReportCoverage assertSourceReportCoverage(
    vms.SourceReportCoverage obj) {
  assertNotNull(obj);
  assertListOfInt(obj.hits!);
  assertListOfInt(obj.misses!);
  return obj;
}

vms.SourceReportRange assertSourceReportRange(vms.SourceReportRange obj) {
  assertNotNull(obj);
  assertInt(obj.scriptIndex!);
  assertInt(obj.startPos!);
  assertInt(obj.endPos!);
  assertBool(obj.compiled!);
  return obj;
}

List<vms.SourceReportRange> assertListOfSourceReportRange(
    List<vms.SourceReportRange> list) {
  for (vms.SourceReportRange elem in list) {
    assertSourceReportRange(elem);
  }
  return list;
}

vms.Stack assertStack(vms.Stack obj) {
  assertNotNull(obj);
  assertListOfFrame(obj.frames!);
  assertListOfMessage(obj.messages!);
  assertBool(obj.truncated!);
  return obj;
}

vms.Timeline assertTimeline(vms.Timeline obj) {
  assertNotNull(obj);
  assertListOfTimelineEvent(obj.traceEvents!);
  assertInt(obj.timeOriginMicros!);
  assertInt(obj.timeExtentMicros!);
  return obj;
}

vms.TimelineEvent assertTimelineEvent(vms.TimelineEvent obj) {
  assertNotNull(obj);
  return obj;
}

List<vms.TimelineEvent> assertListOfTimelineEvent(
    List<vms.TimelineEvent> list) {
  for (vms.TimelineEvent elem in list) {
    assertTimelineEvent(elem);
  }
  return list;
}

vms.TimelineFlags assertTimelineFlags(vms.TimelineFlags obj) {
  assertNotNull(obj);
  assertString(obj.recorderName!);
  assertListOfString(obj.availableStreams!);
  assertListOfString(obj.recordedStreams!);
  return obj;
}

vms.Timestamp assertTimestamp(vms.Timestamp obj) {
  assertNotNull(obj);
  assertInt(obj.timestamp!);
  return obj;
}

vms.TypeArgumentsRef assertTypeArgumentsRef(vms.TypeArgumentsRef obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertString(obj.name!);
  return obj;
}

List<vms.TypeArgumentsRef> assertListOfTypeArgumentsRef(
    List<vms.TypeArgumentsRef> list) {
  for (vms.TypeArgumentsRef elem in list) {
    assertTypeArgumentsRef(elem);
  }
  return list;
}

vms.TypeArguments assertTypeArguments(vms.TypeArguments obj) {
  assertNotNull(obj);
  assertString(obj.id!);
  assertString(obj.name!);
  assertListOfInstanceRef(obj.types!);
  return obj;
}

vms.TypeParameters assertTypeParameters(vms.TypeParameters obj) {
  assertNotNull(obj);
  assertListOfString(obj.names!);
  assertTypeArgumentsRef(obj.bounds!);
  assertTypeArgumentsRef(obj.defaults!);
  return obj;
}

vms.UnresolvedSourceLocation assertUnresolvedSourceLocation(
    vms.UnresolvedSourceLocation obj) {
  assertNotNull(obj);
  return obj;
}

vms.UriList assertUriList(vms.UriList obj) {
  assertNotNull(obj);
  assertListOfDynamic(obj.uris!);
  return obj;
}

vms.Version assertVersion(vms.Version obj) {
  assertNotNull(obj);
  assertInt(obj.major!);
  assertInt(obj.minor!);
  return obj;
}

vms.VMRef assertVMRef(vms.VMRef obj) {
  assertNotNull(obj);
  assertString(obj.name!);
  return obj;
}

List<vms.VMRef> assertListOfVMRef(List<vms.VMRef> list) {
  for (vms.VMRef elem in list) {
    assertVMRef(elem);
  }
  return list;
}

vms.VM assertVM(vms.VM obj) {
  assertNotNull(obj);
  assertString(obj.name!);
  assertInt(obj.architectureBits!);
  assertString(obj.hostCPU!);
  assertString(obj.operatingSystem!);
  assertString(obj.targetCPU!);
  assertString(obj.version!);
  assertInt(obj.pid!);
  assertInt(obj.startTime!);
  assertListOfIsolateRef(obj.isolates!);
  assertListOfIsolateGroupRef(obj.isolateGroups!);
  assertListOfIsolateRef(obj.systemIsolates!);
  assertListOfIsolateGroupRef(obj.systemIsolateGroups!);
  return obj;
}
