// 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 == "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.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;
}
