// 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) {
  assertNotNull(obj);
  return obj;
}

int assertInt(int obj) {
  assertNotNull(obj);
  return obj;
}

double assertDouble(double obj) {
  assertNotNull(obj);
  return obj;
}

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

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) {
  assertNotNull(obj);
  if (obj.isEmpty) throw 'expected non-zero length string';
  return obj;
}

vms.Success assertSuccess(vms.Success obj) {
  assertNotNull(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 == "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 == "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 == "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 == "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);
  assertString(obj.type);
  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.type);
  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.type);
  assertString(obj.id);
  assertInt(obj.breakpointNumber);
  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.type);
  assertString(obj.id);
  assertString(obj.name);
  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.type);
  assertString(obj.id);
  assertString(obj.name);
  assertBool(obj.isAbstract);
  assertBool(obj.isConst);
  assertLibraryRef(obj.library);
  assertListOfInstanceRef(obj.interfaces);
  assertListOfFieldRef(obj.fields);
  assertListOfFuncRef(obj.functions);
  assertListOfClassRef(obj.subclasses);
  return obj;
}

vms.ClassHeapStats assertClassHeapStats(vms.ClassHeapStats obj) {
  assertNotNull(obj);
  assertString(obj.type);
  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);
  assertString(obj.type);
  assertListOfClassRef(obj.classes);
  return obj;
}

vms.CodeRef assertCodeRef(vms.CodeRef obj) {
  assertNotNull(obj);
  assertString(obj.type);
  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.type);
  assertString(obj.id);
  assertString(obj.name);
  assertCodeKind(obj.kind);
  return obj;
}

vms.ContextRef assertContextRef(vms.ContextRef obj) {
  assertNotNull(obj);
  assertString(obj.type);
  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.type);
  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);
  assertString(obj.type);
  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.type);
  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.type);
  assertString(obj.id);
  assertErrorKind(obj.kind);
  assertString(obj.message);
  return obj;
}

vms.Event assertEvent(vms.Event obj) {
  assertNotNull(obj);
  assertString(obj.type);
  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.type);
  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.type);
  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);
  assertString(obj.type);
  assertListOfFlag(obj.flags);
  return obj;
}

vms.Frame assertFrame(vms.Frame obj) {
  assertNotNull(obj);
  assertString(obj.type);
  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.type);
  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);
  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.type);
  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);
  return obj;
}

vms.InstanceRef assertInstanceRef(vms.InstanceRef obj) {
  assertNotNull(obj);
  assertString(obj.type);
  assertString(obj.id);
  assertInstanceKind(obj.kind);
  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.type);
  assertString(obj.id);
  assertInstanceKind(obj.kind);
  assertClassRef(obj.classRef);
  return obj;
}

vms.IsolateRef assertIsolateRef(vms.IsolateRef obj) {
  assertNotNull(obj);
  assertString(obj.type);
  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.type);
  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.type);
  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.type);
  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);
  assertString(obj.type);
  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);
  assertString(obj.type);
  assertInt(obj.totalCount);
  assertListOfObjRef(obj.instances);
  return obj;
}

vms.LibraryRef assertLibraryRef(vms.LibraryRef obj) {
  assertNotNull(obj);
  assertString(obj.type);
  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.type);
  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);
  assertString(obj.type);
  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);
  assertString(obj.type);
  assertInt(obj.externalUsage);
  assertInt(obj.heapCapacity);
  assertInt(obj.heapUsage);
  return obj;
}

vms.Message assertMessage(vms.Message obj) {
  assertNotNull(obj);
  assertString(obj.type);
  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.type);
  assertString(obj.id);
  assertInstanceKind(obj.kind);
  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.type);
  assertString(obj.id);
  assertInstanceKind(obj.kind);
  assertClassRef(obj.classRef);
  assertString(obj.valueAsString);
  return obj;
}

vms.ObjRef assertObjRef(vms.ObjRef obj) {
  assertNotNull(obj);
  assertString(obj.type);
  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.type);
  assertString(obj.id);
  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);
  assertString(obj.type);
  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);
  assertString(obj.type);
  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);
  assertString(obj.type);
  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);
  assertString(obj.type);
  assertInt(obj.length);
  assertString(obj.gcRootType);
  assertListOfRetainingObject(obj.elements);
  return obj;
}

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

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

vms.ScriptRef assertScriptRef(vms.ScriptRef obj) {
  assertNotNull(obj);
  assertString(obj.type);
  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.type);
  assertString(obj.id);
  assertString(obj.uri);
  assertLibraryRef(obj.library);
  return obj;
}

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

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

vms.SourceReport assertSourceReport(vms.SourceReport obj) {
  assertNotNull(obj);
  assertString(obj.type);
  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);
  assertString(obj.type);
  assertListOfFrame(obj.frames);
  assertListOfMessage(obj.messages);
  return obj;
}

vms.Timeline assertTimeline(vms.Timeline obj) {
  assertNotNull(obj);
  assertString(obj.type);
  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.type);
  assertString(obj.recorderName);
  assertListOfString(obj.availableStreams);
  assertListOfString(obj.recordedStreams);
  return obj;
}

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

vms.TypeArgumentsRef assertTypeArgumentsRef(vms.TypeArgumentsRef obj) {
  assertNotNull(obj);
  assertString(obj.type);
  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.type);
  assertString(obj.id);
  assertString(obj.name);
  assertListOfInstanceRef(obj.types);
  return obj;
}

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

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

vms.VMRef assertVMRef(vms.VMRef obj) {
  assertNotNull(obj);
  assertString(obj.type);
  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.type);
  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;
}
