// 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 to access the VM Service API.
///
/// The main entry-point for this library is the [VmService] class.

import 'dart:async';
import 'dart:convert' show base64, jsonDecode, jsonEncode, utf8;
import 'dart:typed_data';

import 'package:meta/meta.dart';

import 'service_extension_registry.dart';

export 'service_extension_registry.dart' show ServiceExtensionRegistry;
export 'snapshot_graph.dart'
    show
        HeapSnapshotClass,
        HeapSnapshotExternalProperty,
        HeapSnapshotField,
        HeapSnapshotGraph,
        HeapSnapshotObject,
        HeapSnapshotObjectLengthData,
        HeapSnapshotObjectNoData,
        HeapSnapshotObjectNullData;

const String vmServiceVersion = '3.29.0';

/// @optional
const String optional = 'optional';

/// Decode a string in Base64 encoding into the equivalent non-encoded string.
/// This is useful for handling the results of the Stdout or Stderr events.
String decodeBase64(String str) => utf8.decode(base64.decode(str));

// Returns true if a response is the Dart `null` instance.
bool _isNullInstance(Map json) =>
    ((json['type'] == '@Instance') && (json['kind'] == 'Null'));

Object createServiceObject(dynamic json, List<String> expectedTypes) {
  if (json == null) return null;

  if (json is List) {
    return json.map((e) => createServiceObject(e, expectedTypes)).toList();
  } else if (json is Map) {
    String type = json['type'];

    // Not a Response type.
    if (type == null) {
      // If there's only one expected type, we'll just use that type.
      if (expectedTypes.length == 1) {
        type = expectedTypes.first;
      } else {
        return null;
      }
    } else if (_isNullInstance(json) && (!expectedTypes.contains(type))) {
      // Replace null instances with null when we don't expect an instance to
      // be returned.
      return null;
    }
    if (_typeFactories[type] == null) {
      return null;
    } else {
      return _typeFactories[type](json);
    }
  } else {
    // Handle simple types.
    return json;
  }
}

dynamic _createSpecificObject(
    dynamic json, dynamic creator(Map<String, dynamic> map)) {
  if (json == null) return null;

  if (json is List) {
    return json.map((e) => creator(e)).toList();
  } else if (json is Map) {
    Map<String, dynamic> map = {};
    for (dynamic key in json.keys) {
      map[key as String] = json[key];
    }
    return creator(map);
  } else {
    // Handle simple types.
    return json;
  }
}

void _setIfNotNull(Map<String, Object> json, String key, Object value) {
  if (value == null) return;
  json[key] = value;
}

Future<T> extensionCallHelper<T>(VmService service, String method, Map args) {
  return service._call(method, args);
}

typedef ServiceCallback = Future<Map<String, dynamic>> Function(
    Map<String, dynamic> params);

void addTypeFactory(String name, Function factory) {
  if (_typeFactories.containsKey(name)) {
    throw StateError('Factory already registered for $name');
  }
  _typeFactories[name] = factory;
}

Map<String, Function> _typeFactories = {
  'AllocationProfile': AllocationProfile.parse,
  'BoundField': BoundField.parse,
  'BoundVariable': BoundVariable.parse,
  'Breakpoint': Breakpoint.parse,
  '@Class': ClassRef.parse,
  'Class': Class.parse,
  'ClassHeapStats': ClassHeapStats.parse,
  'ClassList': ClassList.parse,
  'ClientName': ClientName.parse,
  '@Code': CodeRef.parse,
  'Code': Code.parse,
  '@Context': ContextRef.parse,
  'Context': Context.parse,
  'ContextElement': ContextElement.parse,
  'CpuSamples': CpuSamples.parse,
  'CpuSample': CpuSample.parse,
  '@Error': ErrorRef.parse,
  'Error': Error.parse,
  'Event': Event.parse,
  'ExtensionData': ExtensionData.parse,
  '@Field': FieldRef.parse,
  'Field': Field.parse,
  'Flag': Flag.parse,
  'FlagList': FlagList.parse,
  'Frame': Frame.parse,
  '@Function': FuncRef.parse,
  'Function': Func.parse,
  '@Instance': InstanceRef.parse,
  'Instance': Instance.parse,
  '@Isolate': IsolateRef.parse,
  'Isolate': Isolate.parse,
  '@IsolateGroup': IsolateGroupRef.parse,
  'IsolateGroup': IsolateGroup.parse,
  'InboundReferences': InboundReferences.parse,
  'InboundReference': InboundReference.parse,
  'InstanceSet': InstanceSet.parse,
  '@Library': LibraryRef.parse,
  'Library': Library.parse,
  'LibraryDependency': LibraryDependency.parse,
  'LogRecord': LogRecord.parse,
  'MapAssociation': MapAssociation.parse,
  'MemoryUsage': MemoryUsage.parse,
  'Message': Message.parse,
  'NativeFunction': NativeFunction.parse,
  '@Null': NullValRef.parse,
  'Null': NullVal.parse,
  '@Object': ObjRef.parse,
  'Object': Obj.parse,
  'ProfileFunction': ProfileFunction.parse,
  'ReloadReport': ReloadReport.parse,
  'RetainingObject': RetainingObject.parse,
  'RetainingPath': RetainingPath.parse,
  'Response': Response.parse,
  'Sentinel': Sentinel.parse,
  '@Script': ScriptRef.parse,
  'Script': Script.parse,
  'ScriptList': ScriptList.parse,
  'SourceLocation': SourceLocation.parse,
  'SourceReport': SourceReport.parse,
  'SourceReportCoverage': SourceReportCoverage.parse,
  'SourceReportRange': SourceReportRange.parse,
  'Stack': Stack.parse,
  'Success': Success.parse,
  'Timeline': Timeline.parse,
  'TimelineEvent': TimelineEvent.parse,
  'TimelineFlags': TimelineFlags.parse,
  'Timestamp': Timestamp.parse,
  '@TypeArguments': TypeArgumentsRef.parse,
  'TypeArguments': TypeArguments.parse,
  'UnresolvedSourceLocation': UnresolvedSourceLocation.parse,
  'Version': Version.parse,
  '@VM': VMRef.parse,
  'VM': VM.parse,
};

Map<String, List<String>> _methodReturnTypes = {
  'addBreakpoint': const ['Breakpoint'],
  'addBreakpointWithScriptUri': const ['Breakpoint'],
  'addBreakpointAtEntry': const ['Breakpoint'],
  'clearCpuSamples': const ['Success'],
  'clearVMTimeline': const ['Success'],
  'invoke': const ['InstanceRef', 'ErrorRef', 'Sentinel'],
  'evaluate': const ['InstanceRef', 'ErrorRef', 'Sentinel'],
  'evaluateInFrame': const ['InstanceRef', 'ErrorRef', 'Sentinel'],
  'getAllocationProfile': const ['AllocationProfile'],
  'getClientName': const ['ClientName'],
  'getCpuSamples': const ['CpuSamples'],
  'getFlagList': const ['FlagList'],
  'getInboundReferences': const ['InboundReferences', 'Sentinel'],
  'getInstances': const ['InstanceSet'],
  'getIsolate': const ['Isolate', 'Sentinel'],
  'getIsolateGroup': const ['IsolateGroup', 'Sentinel'],
  'getMemoryUsage': const ['MemoryUsage', 'Sentinel'],
  'getIsolateGroupMemoryUsage': const ['MemoryUsage', 'Sentinel'],
  'getScripts': const ['ScriptList'],
  'getObject': const ['Obj', 'Sentinel'],
  'getRetainingPath': const ['RetainingPath'],
  'getStack': const ['Stack'],
  'getSourceReport': const ['SourceReport'],
  'getVersion': const ['Version'],
  'getVM': const ['VM'],
  'getVMTimeline': const ['Timeline'],
  'getVMTimelineFlags': const ['TimelineFlags'],
  'getVMTimelineMicros': const ['Timestamp'],
  'pause': const ['Success'],
  'kill': const ['Success'],
  'registerService': const ['Success'],
  'reloadSources': const ['ReloadReport'],
  'removeBreakpoint': const ['Success'],
  'requestHeapSnapshot': const ['Success'],
  'requirePermissionToResume': const ['Success'],
  'resume': const ['Success'],
  'setClientName': const ['Success'],
  'setExceptionPauseMode': const ['Success'],
  'setFlag': const ['Success', 'Error'],
  'setLibraryDebuggable': const ['Success'],
  'setName': const ['Success'],
  'setVMName': const ['Success'],
  'setVMTimelineFlags': const ['Success'],
  'streamCancel': const ['Success'],
  'streamListen': const ['Success'],
};

/// A class representation of the Dart VM Service Protocol.
///
/// Both clients and servers should implement this interface.
abstract class VmServiceInterface {
  /// Returns the stream for a given stream id.
  ///
  /// This is not a part of the spec, but is needed for both the client and
  /// server to get access to the real event streams.
  Stream<Event> onEvent(String streamId);

  /// Handler for calling extra service extensions.
  Future<Response> callServiceExtension(String method,
      {String isolateId, Map args});

  /// The `addBreakpoint` RPC is used to add a breakpoint at a specific line of
  /// some script.
  ///
  /// The `scriptId` parameter is used to specify the target script.
  ///
  /// The `line` parameter is used to specify the target line for the
  /// breakpoint. If there are multiple possible breakpoints on the target line,
  /// then the VM will place the breakpoint at the location which would execute
  /// soonest. If it is not possible to set a breakpoint at the target line, the
  /// breakpoint will be added at the next possible breakpoint location within
  /// the same function.
  ///
  /// The `column` parameter may be optionally specified. This is useful for
  /// targeting a specific breakpoint on a line with multiple possible
  /// breakpoints.
  ///
  /// If no breakpoint is possible at that line, the `102` (Cannot add
  /// breakpoint) error code is returned.
  ///
  /// Note that breakpoints are added and removed on a per-isolate basis.
  ///
  /// See [Breakpoint].
  Future<Breakpoint> addBreakpoint(
    String isolateId,
    String scriptId,
    int line, {
    int column,
  });

  /// The `addBreakpoint` RPC is used to add a breakpoint at a specific line of
  /// some script. This RPC is useful when a script has not yet been assigned an
  /// id, for example, if a script is in a deferred library which has not yet
  /// been loaded.
  ///
  /// The `scriptUri` parameter is used to specify the target script.
  ///
  /// The `line` parameter is used to specify the target line for the
  /// breakpoint. If there are multiple possible breakpoints on the target line,
  /// then the VM will place the breakpoint at the location which would execute
  /// soonest. If it is not possible to set a breakpoint at the target line, the
  /// breakpoint will be added at the next possible breakpoint location within
  /// the same function.
  ///
  /// The `column` parameter may be optionally specified. This is useful for
  /// targeting a specific breakpoint on a line with multiple possible
  /// breakpoints.
  ///
  /// If no breakpoint is possible at that line, the `102` (Cannot add
  /// breakpoint) error code is returned.
  ///
  /// Note that breakpoints are added and removed on a per-isolate basis.
  ///
  /// See [Breakpoint].
  Future<Breakpoint> addBreakpointWithScriptUri(
    String isolateId,
    String scriptUri,
    int line, {
    int column,
  });

  /// The `addBreakpointAtEntry` RPC is used to add a breakpoint at the
  /// entrypoint of some function.
  ///
  /// If no breakpoint is possible at the function entry, the `102` (Cannot add
  /// breakpoint) error code is returned.
  ///
  /// See [Breakpoint].
  ///
  /// Note that breakpoints are added and removed on a per-isolate basis.
  Future<Breakpoint> addBreakpointAtEntry(String isolateId, String functionId);

  /// Clears all CPU profiling samples.
  ///
  /// See [Success].
  Future<Success> clearCpuSamples(String isolateId);

  /// Clears all VM timeline events.
  ///
  /// See [Success].
  Future<Success> clearVMTimeline();

  /// The `invoke` RPC is used to perform regular method invocation on some
  /// receiver, as if by dart:mirror's ObjectMirror.invoke. Note this does not
  /// provide a way to perform getter, setter or constructor invocation.
  ///
  /// `targetId` may refer to a [Library], [Class], or [Instance].
  ///
  /// Each elements of `argumentId` may refer to an [Instance].
  ///
  /// If `disableBreakpoints` is provided and set to true, any breakpoints hit
  /// as a result of this invocation are ignored, including pauses resulting
  /// from a call to `debugger()` from `dart:developer`. Defaults to false if
  /// not provided.
  ///
  /// If `targetId` or any element of `argumentIds` is a temporary id which has
  /// expired, then the `Expired` [Sentinel] is returned.
  ///
  /// If `targetId` or any element of `argumentIds` refers to an object which
  /// has been collected by the VM's garbage collector, then the `Collected`
  /// [Sentinel] is returned.
  ///
  /// If invocation triggers a failed compilation then [rpc error] 113
  /// "Expression compilation error" is returned.
  ///
  /// If an runtime error occurs while evaluating the invocation, an [ErrorRef]
  /// reference will be returned.
  ///
  /// If the invocation is evaluated successfully, an [InstanceRef] reference
  /// will be returned.
  ///
  /// The return value can be one of [InstanceRef], [ErrorRef] or [Sentinel].
  Future<dynamic> invoke(
    String isolateId,
    String targetId,
    String selector,
    List<String> argumentIds, {
    bool disableBreakpoints,
  });

  /// The `evaluate` RPC is used to evaluate an expression in the context of
  /// some target.
  ///
  /// `targetId` may refer to a [Library], [Class], or [Instance].
  ///
  /// If `targetId` is a temporary id which has expired, then the `Expired`
  /// [Sentinel] is returned.
  ///
  /// If `targetId` refers to an object which has been collected by the VM's
  /// garbage collector, then the `Collected` [Sentinel] is returned.
  ///
  /// If `scope` is provided, it should be a map from identifiers to object ids.
  /// These bindings will be added to the scope in which the expression is
  /// evaluated, which is a child scope of the class or library for
  /// instance/class or library targets respectively. This means bindings
  /// provided in `scope` may shadow instance members, class members and
  /// top-level members.
  ///
  /// If `disableBreakpoints` is provided and set to true, any breakpoints hit
  /// as a result of this evaluation are ignored. Defaults to false if not
  /// provided.
  ///
  /// If the expression fails to parse and compile, then [rpc error] 113
  /// "Expression compilation error" is returned.
  ///
  /// If an error occurs while evaluating the expression, an [ErrorRef]
  /// reference will be returned.
  ///
  /// If the expression is evaluated successfully, an [InstanceRef] reference
  /// will be returned.
  ///
  /// The return value can be one of [InstanceRef], [ErrorRef] or [Sentinel].
  Future<dynamic> evaluate(
    String isolateId,
    String targetId,
    String expression, {
    Map<String, String> scope,
    bool disableBreakpoints,
  });

  /// The `evaluateInFrame` RPC is used to evaluate an expression in the context
  /// of a particular stack frame. `frameIndex` is the index of the desired
  /// [Frame], with an index of `0` indicating the top (most recent) frame.
  ///
  /// If `scope` is provided, it should be a map from identifiers to object ids.
  /// These bindings will be added to the scope in which the expression is
  /// evaluated, which is a child scope of the frame's current scope. This means
  /// bindings provided in `scope` may shadow instance members, class members,
  /// top-level members, parameters and locals.
  ///
  /// If `disableBreakpoints` is provided and set to true, any breakpoints hit
  /// as a result of this evaluation are ignored. Defaults to false if not
  /// provided.
  ///
  /// If the expression fails to parse and compile, then [rpc error] 113
  /// "Expression compilation error" is returned.
  ///
  /// If an error occurs while evaluating the expression, an [ErrorRef]
  /// reference will be returned.
  ///
  /// If the expression is evaluated successfully, an [InstanceRef] reference
  /// will be returned.
  ///
  /// The return value can be one of [InstanceRef], [ErrorRef] or [Sentinel].
  Future<dynamic> evaluateInFrame(
    String isolateId,
    int frameIndex,
    String expression, {
    Map<String, String> scope,
    bool disableBreakpoints,
  });

  /// The `getAllocationProfile` RPC is used to retrieve allocation information
  /// for a given isolate.
  ///
  /// If `reset` is provided and is set to true, the allocation accumulators
  /// will be reset before collecting allocation information.
  ///
  /// If `gc` is provided and is set to true, a garbage collection will be
  /// attempted before collecting allocation information. There is no guarantee
  /// that a garbage collection will be actually be performed.
  Future<AllocationProfile> getAllocationProfile(String isolateId,
      {bool reset, bool gc});

  /// The `getClientName` RPC is used to retrieve the name associated with the
  /// currently connected VM service client. If no name was previously set
  /// through the [setClientName] RPC, a default name will be returned.
  ///
  /// See [ClientName].
  Future<ClientName> getClientName();

  /// The `getCpuSamples` RPC is used to retrieve samples collected by the CPU
  /// profiler. Only samples collected in the time range `[timeOriginMicros,
  /// timeOriginMicros + timeExtentMicros]` will be reported.
  ///
  /// If the profiler is disabled, an error response will be returned.
  ///
  /// See [CpuSamples].
  Future<CpuSamples> getCpuSamples(
      String isolateId, int timeOriginMicros, int timeExtentMicros);

  /// The `getFlagList` RPC returns a list of all command line flags in the VM
  /// along with their current values.
  ///
  /// See [FlagList].
  Future<FlagList> getFlagList();

  /// Returns a set of inbound references to the object specified by `targetId`.
  /// Up to `limit` references will be returned.
  ///
  /// The order of the references is undefined (i.e., not related to allocation
  /// order) and unstable (i.e., multiple invocations of this method against the
  /// same object can give different answers even if no Dart code has executed
  /// between the invocations).
  ///
  /// The references may include multiple `objectId`s that designate the same
  /// object.
  ///
  /// The references may include objects that are unreachable but have not yet
  /// been garbage collected.
  ///
  /// If `targetId` is a temporary id which has expired, then the `Expired`
  /// [Sentinel] is returned.
  ///
  /// If `targetId` refers to an object which has been collected by the VM's
  /// garbage collector, then the `Collected` [Sentinel] is returned.
  ///
  /// See [InboundReferences].
  ///
  /// The return value can be one of [InboundReferences] or [Sentinel].
  Future<dynamic> getInboundReferences(
      String isolateId, String targetId, int limit);

  /// The `getInstances` RPC is used to retrieve a set of instances which are of
  /// a specific class. This does not include instances of subclasses of the
  /// given class.
  ///
  /// The order of the instances is undefined (i.e., not related to allocation
  /// order) and unstable (i.e., multiple invocations of this method against the
  /// same class can give different answers even if no Dart code has executed
  /// between the invocations).
  ///
  /// The set of instances may include objects that are unreachable but have not
  /// yet been garbage collected.
  ///
  /// `objectId` is the ID of the `Class` to retrieve instances for. `objectId`
  /// must be the ID of a `Class`, otherwise an error is returned.
  ///
  /// `limit` is the maximum number of instances to be returned.
  ///
  /// See [InstanceSet].
  Future<InstanceSet> getInstances(
      String isolateId, String objectId, int limit);

  /// The `getIsolate` RPC is used to lookup an `Isolate` object by its `id`.
  ///
  /// If `isolateId` refers to an isolate which has exited, then the `Collected`
  /// [Sentinel] is returned.
  ///
  /// See [Isolate].
  ///
  /// The return value can be one of [Isolate] or [Sentinel].
  Future<dynamic> getIsolate(String isolateId);

  /// The `getIsolateGroup` RPC is used to lookup an `IsolateGroup` object by
  /// its `id`.
  ///
  /// If `isolateGroupId` refers to an isolate group which has exited, then the
  /// `Expired` [Sentinel] is returned.
  ///
  /// `IsolateGroup` `id` is an opaque identifier that can be fetched from an
  /// `IsolateGroup`. List of active `IsolateGroup`'s, for example, is available
  /// on `VM` object.
  ///
  /// See [IsolateGroup], [VM].
  ///
  /// The return value can be one of [IsolateGroup] or [Sentinel].
  Future<dynamic> getIsolateGroup(String isolateGroupId);

  /// The `getMemoryUsage` RPC is used to lookup an isolate's memory usage
  /// statistics by its `id`.
  ///
  /// If `isolateId` refers to an isolate which has exited, then the `Collected`
  /// [Sentinel] is returned.
  ///
  /// See [Isolate].
  ///
  /// The return value can be one of [MemoryUsage] or [Sentinel].
  Future<dynamic> getMemoryUsage(String isolateId);

  /// The `getIsolateGroupMemoryUsage` RPC is used to lookup an isolate group's
  /// memory usage statistics by its `id`.
  ///
  /// If `isolateGroupId` refers to an isolate group which has exited, then the
  /// `Expired` [Sentinel] is returned.
  ///
  /// See [IsolateGroup].
  ///
  /// The return value can be one of [MemoryUsage] or [Sentinel].
  Future<dynamic> getIsolateGroupMemoryUsage(String isolateGroupId);

  /// The `getScripts` RPC is used to retrieve a `ScriptList` containing all
  /// scripts for an isolate based on the isolate's `isolateId`.
  ///
  /// See [ScriptList].
  Future<ScriptList> getScripts(String isolateId);

  /// The `getObject` RPC is used to lookup an `object` from some isolate by its
  /// `id`.
  ///
  /// If `objectId` is a temporary id which has expired, then the `Expired`
  /// [Sentinel] is returned.
  ///
  /// If `objectId` refers to a heap object which has been collected by the VM's
  /// garbage collector, then the `Collected` [Sentinel] is returned.
  ///
  /// If `objectId` refers to a non-heap object which has been deleted, then the
  /// `Collected` [Sentinel] is returned.
  ///
  /// If the object handle has not expired and the object has not been
  /// collected, then an [Obj] will be returned.
  ///
  /// The `offset` and `count` parameters are used to request subranges of
  /// Instance objects with the kinds: String, List, Map, Uint8ClampedList,
  /// Uint8List, Uint16List, Uint32List, Uint64List, Int8List, Int16List,
  /// Int32List, Int64List, Flooat32List, Float64List, Inst32x3List,
  /// Float32x4List, and Float64x2List. These parameters are otherwise ignored.
  ///
  /// The return value can be one of [Obj] or [Sentinel].
  Future<dynamic> getObject(
    String isolateId,
    String objectId, {
    int offset,
    int count,
  });

  /// The `getRetainingPath` RPC is used to lookup a path from an object
  /// specified by `targetId` to a GC root (i.e., the object which is preventing
  /// this object from being garbage collected).
  ///
  /// If `targetId` refers to a heap object which has been collected by the VM's
  /// garbage collector, then the `Collected` [Sentinel] is returned.
  ///
  /// If `targetId` refers to a non-heap object which has been deleted, then the
  /// `Collected` [Sentinel] is returned.
  ///
  /// If the object handle has not expired and the object has not been
  /// collected, then an [RetainingPath] will be returned.
  ///
  /// The `limit` parameter specifies the maximum path length to be reported as
  /// part of the retaining path. If a path is longer than `limit`, it will be
  /// truncated at the root end of the path.
  ///
  /// See [RetainingPath].
  Future<RetainingPath> getRetainingPath(
      String isolateId, String targetId, int limit);

  /// The `getStack` RPC is used to retrieve the current execution stack and
  /// message queue for an isolate. The isolate does not need to be paused.
  ///
  /// See [Stack].
  Future<Stack> getStack(String isolateId);

  /// The `getSourceReport` RPC is used to generate a set of reports tied to
  /// source locations in an isolate.
  ///
  /// The `reports` parameter is used to specify which reports should be
  /// generated. The `reports` parameter is a list, which allows multiple
  /// reports to be generated simultaneously from a consistent isolate state.
  /// The `reports` parameter is allowed to be empty (this might be used to
  /// force compilation of a particular subrange of some script).
  ///
  /// The available report kinds are:
  ///
  /// report kind | meaning
  /// ----------- | -------
  /// Coverage | Provide code coverage information
  /// PossibleBreakpoints | Provide a list of token positions which correspond
  /// to possible breakpoints.
  ///
  /// The `scriptId` parameter is used to restrict the report to a particular
  /// script. When analyzing a particular script, either or both of the
  /// `tokenPos` and `endTokenPos` parameters may be provided to restrict the
  /// analysis to a subrange of a script (for example, these can be used to
  /// restrict the report to the range of a particular class or function).
  ///
  /// If the `scriptId` parameter is not provided then the reports are generated
  /// for all loaded scripts and the `tokenPos` and `endTokenPos` parameters are
  /// disallowed.
  ///
  /// The `forceCompilation` parameter can be used to force compilation of all
  /// functions in the range of the report. Forcing compilation can cause a
  /// compilation error, which could terminate the running Dart program. If this
  /// parameter is not provided, it is considered to have the value `false`.
  ///
  /// See [SourceReport].
  Future<SourceReport> getSourceReport(
    String isolateId,
    /*List<SourceReportKind>*/
    List<String> reports, {
    String scriptId,
    int tokenPos,
    int endTokenPos,
    bool forceCompile,
  });

  /// The `getVersion` RPC is used to determine what version of the Service
  /// Protocol is served by a VM.
  ///
  /// See [Version].
  Future<Version> getVersion();

  /// The `getVM` RPC returns global information about a Dart virtual machine.
  ///
  /// See [VM].
  Future<VM> getVM();

  /// The `getVMTimeline` RPC is used to retrieve an object which contains VM
  /// timeline events.
  ///
  /// The `timeOriginMicros` parameter is the beginning of the time range used
  /// to filter timeline events. It uses the same monotonic clock as
  /// dart:developer's `Timeline.now` and the VM embedding API's
  /// `Dart_TimelineGetMicros`. See [getVMTimelineMicros] for access to this
  /// clock through the service protocol.
  ///
  /// The `timeExtentMicros` parameter specifies how large the time range used
  /// to filter timeline events should be.
  ///
  /// For example, given `timeOriginMicros` and `timeExtentMicros`, only
  /// timeline events from the following time range will be returned:
  /// `(timeOriginMicros, timeOriginMicros + timeExtentMicros)`.
  ///
  /// If `getVMTimeline` is invoked while the current recorder is one of Fuchsia
  /// or Macos or Systrace, the `114` error code, invalid timeline request, will
  /// be returned as timeline events are handled by the OS in these modes.
  Future<Timeline> getVMTimeline({int timeOriginMicros, int timeExtentMicros});

  /// The `getVMTimelineFlags` RPC returns information about the current VM
  /// timeline configuration.
  ///
  /// To change which timeline streams are currently enabled, see
  /// [setVMTimelineFlags].
  ///
  /// See [TimelineFlags].
  Future<TimelineFlags> getVMTimelineFlags();

  /// The `getVMTimelineMicros` RPC returns the current time stamp from the
  /// clock used by the timeline, similar to `Timeline.now` in `dart:developer`
  /// and `Dart_TimelineGetMicros` in the VM embedding API.
  ///
  /// See [Timestamp] and [getVMTimeline].
  Future<Timestamp> getVMTimelineMicros();

  /// The `pause` RPC is used to interrupt a running isolate. The RPC enqueues
  /// the interrupt request and potentially returns before the isolate is
  /// paused.
  ///
  /// When the isolate is paused an event will be sent on the `Debug` stream.
  ///
  /// See [Success].
  Future<Success> pause(String isolateId);

  /// The `kill` RPC is used to kill an isolate as if by dart:isolate's
  /// `Isolate.kill(IMMEDIATE)`.
  ///
  /// The isolate is killed regardless of whether it is paused or running.
  ///
  /// See [Success].
  Future<Success> kill(String isolateId);

  /// Registers a service that can be invoked by other VM service clients, where
  /// `service` is the name of the service to advertise and `alias` is an
  /// alternative name for the registered service.
  ///
  /// Requests made to the new service will be forwarded to the client which
  /// originally registered the service.
  ///
  /// See [Success].
  Future<Success> registerService(String service, String alias);

  /// The `reloadSources` RPC is used to perform a hot reload of an Isolate's
  /// sources.
  ///
  /// if the `force` parameter is provided, it indicates that all of the
  /// Isolate's sources should be reloaded regardless of modification time.
  ///
  /// if the `pause` parameter is provided, the isolate will pause immediately
  /// after the reload.
  ///
  /// if the `rootLibUri` parameter is provided, it indicates the new uri to the
  /// Isolate's root library.
  ///
  /// if the `packagesUri` parameter is provided, it indicates the new uri to
  /// the Isolate's package map (.packages) file.
  Future<ReloadReport> reloadSources(
    String isolateId, {
    bool force,
    bool pause,
    String rootLibUri,
    String packagesUri,
  });

  /// The `removeBreakpoint` RPC is used to remove a breakpoint by its `id`.
  ///
  /// Note that breakpoints are added and removed on a per-isolate basis.
  ///
  /// See [Success].
  Future<Success> removeBreakpoint(String isolateId, String breakpointId);

  /// Requests a dump of the Dart heap of the given isolate.
  ///
  /// This method immediately returns success. The VM will then begin delivering
  /// binary events on the `HeapSnapshot` event stream. The binary data in these
  /// events, when concatenated together, conforms to the [SnapshotGraph] type.
  /// The splitting of the SnapshotGraph into events can happen at any byte
  /// offset.
  Future<Success> requestHeapSnapshot(String isolateId);

  /// The `requirePermissionToResume` RPC is used to change the pause/resume
  /// behavior of isolates by providing a way for the VM service to wait for
  /// approval to resume from some set of clients. This is useful for clients
  /// which want to perform some operation on an isolate after a pause without
  /// it being resumed by another client.
  ///
  /// If the `onPauseStart` parameter is `true`, isolates will not resume after
  /// pausing on start until the client sends a `resume` request and all other
  /// clients which need to provide resume approval for this pause type have
  /// done so.
  ///
  /// If the `onPauseReload` parameter is `true`, isolates will not resume after
  /// pausing after a reload until the client sends a `resume` request and all
  /// other clients which need to provide resume approval for this pause type
  /// have done so.
  ///
  /// If the `onPauseExit` parameter is `true`, isolates will not resume after
  /// pausing on exit until the client sends a `resume` request and all other
  /// clients which need to provide resume approval for this pause type have
  /// done so.
  ///
  /// Important Notes:<strong>Important Notes:</strong>
  Future<Success> requirePermissionToResume(
      {bool onPauseStart, bool onPauseReload, bool onPauseExit});

  /// The `resume` RPC is used to resume execution of a paused isolate.
  ///
  /// If the `step` parameter is not provided, the program will resume regular
  /// execution.
  ///
  /// If the `step` parameter is provided, it indicates what form of
  /// single-stepping to use.
  ///
  /// step | meaning
  /// ---- | -------
  /// Into | Single step, entering function calls
  /// Over | Single step, skipping over function calls
  /// Out | Single step until the current function exits
  /// Rewind | Immediately exit the top frame(s) without executing any code.
  /// Isolate will be paused at the call of the last exited function.
  ///
  /// The `frameIndex` parameter is only used when the `step` parameter is
  /// Rewind. It specifies the stack frame to rewind to. Stack frame 0 is the
  /// currently executing function, so `frameIndex` must be at least 1.
  ///
  /// If the `frameIndex` parameter is not provided, it defaults to 1.
  ///
  /// See [Success], [StepOption].
  Future<Success> resume(String isolateId,
      {/*StepOption*/ String step, int frameIndex});

  /// The `setClientName` RPC is used to set a name to be associated with the
  /// currently connected VM service client. If the `name` parameter is a
  /// non-empty string, `name` will become the new name associated with the
  /// client. If `name` is an empty string, the client's name will be reset to
  /// its default name.
  ///
  /// See [Success].
  Future<Success> setClientName(String name);

  /// The `setExceptionPauseMode` RPC is used to control if an isolate pauses
  /// when an exception is thrown.
  ///
  /// mode | meaning
  /// ---- | -------
  /// None | Do not pause isolate on thrown exceptions
  /// Unhandled | Pause isolate on unhandled exceptions
  /// All  | Pause isolate on all thrown exceptions
  Future<Success> setExceptionPauseMode(
      String isolateId, /*ExceptionPauseMode*/ String mode);

  /// The `setFlag` RPC is used to set a VM flag at runtime. Returns an error if
  /// the named flag does not exist, the flag may not be set at runtime, or the
  /// value is of the wrong type for the flag.
  ///
  /// The following flags may be set at runtime:
  ///
  /// The return value can be one of [Success] or [Error].
  Future<dynamic> setFlag(String name, String value);

  /// The `setLibraryDebuggable` RPC is used to enable or disable whether
  /// breakpoints and stepping work for a given library.
  ///
  /// See [Success].
  Future<Success> setLibraryDebuggable(
      String isolateId, String libraryId, bool isDebuggable);

  /// The `setName` RPC is used to change the debugging name for an isolate.
  ///
  /// See [Success].
  Future<Success> setName(String isolateId, String name);

  /// The `setVMName` RPC is used to change the debugging name for the vm.
  ///
  /// See [Success].
  Future<Success> setVMName(String name);

  /// The `setVMTimelineFlags` RPC is used to set which timeline streams are
  /// enabled.
  ///
  /// The `recordedStreams` parameter is the list of all timeline streams which
  /// are to be enabled. Streams not explicitly specified will be disabled.
  /// Invalid stream names are ignored.
  ///
  /// To get the list of currently enabled timeline streams, see
  /// [getVMTimelineFlags].
  ///
  /// See [Success].
  Future<Success> setVMTimelineFlags(List<String> recordedStreams);

  /// The `streamCancel` RPC cancels a stream subscription in the VM.
  ///
  /// If the client is not subscribed to the stream, the `104` (Stream not
  /// subscribed) error code is returned.
  ///
  /// See [Success].
  Future<Success> streamCancel(String streamId);

  /// The `streamListen` RPC subscribes to a stream in the VM. Once subscribed,
  /// the client will begin receiving events from the stream.
  ///
  /// If the client is already subscribed to the stream, the `103` (Stream
  /// already subscribed) error code is returned.
  ///
  /// The `streamId` parameter may have the following published values:
  ///
  /// streamId | event types provided
  /// -------- | -----------
  /// VM | VMUpdate, VMFlagUpdate
  /// Isolate | IsolateStart, IsolateRunnable, IsolateExit, IsolateUpdate,
  /// IsolateReload, ServiceExtensionAdded
  /// Debug | PauseStart, PauseExit, PauseBreakpoint, PauseInterrupted,
  /// PauseException, PausePostRequest, Resume, BreakpointAdded,
  /// BreakpointResolved, BreakpointRemoved, Inspect, None
  /// GC | GC
  /// Extension | Extension
  /// Timeline | TimelineEvents
  /// Logging | Logging
  /// Service | ServiceRegistered, ServiceUnregistered
  /// HeapSnapshot | HeapSnapshot
  ///
  /// Additionally, some embedders provide the `Stdout` and `Stderr` streams.
  /// These streams allow the client to subscribe to writes to stdout and
  /// stderr.
  ///
  /// streamId | event types provided
  /// -------- | -----------
  /// Stdout | WriteEvent
  /// Stderr | WriteEvent
  ///
  /// It is considered a `backwards compatible` change to add a new type of
  /// event to an existing stream. Clients should be written to handle this
  /// gracefully, perhaps by warning and ignoring.
  ///
  /// See [Success].
  Future<Success> streamListen(String streamId);
}

/// A Dart VM Service Protocol connection that delegates requests to a
/// [VmServiceInterface] implementation.
///
/// One of these should be created for each client, but they should generally
/// share the same [VmServiceInterface] and [ServiceExtensionRegistry]
/// instances.
class VmServerConnection {
  final Stream<Map<String, Object>> _requestStream;
  final StreamSink<Map<String, Object>> _responseSink;
  final ServiceExtensionRegistry _serviceExtensionRegistry;
  final VmServiceInterface _serviceImplementation;

  /// Used to create unique ids when acting as a proxy between clients.
  int _nextServiceRequestId = 0;

  /// Manages streams for `streamListen` and `streamCancel` requests.
  final _streamSubscriptions = <String, StreamSubscription>{};

  /// Completes when [_requestStream] is done.
  Future get done => _doneCompleter.future;
  final _doneCompleter = Completer<Null>();

  /// Pending service extension requests to this client by id.
  final _pendingServiceExtensionRequests =
      <String, Completer<Map<String, Object>>>{};

  VmServerConnection(this._requestStream, this._responseSink,
      this._serviceExtensionRegistry, this._serviceImplementation) {
    _requestStream.listen(_delegateRequest, onDone: _doneCompleter.complete);
    done.then(
        (_) => _streamSubscriptions.values.forEach((sub) => sub.cancel()));
  }

  /// Invoked when the current client has registered some extension, and
  /// another client sends an RPC request for that extension.
  ///
  /// We don't attempt to do any serialization or deserialization of the
  /// request or response in this case
  Future<Map<String, Object>> _forwardServiceExtensionRequest(
      Map<String, Object> request) {
    var originalId = request['id'];
    request = Map.of(request);
    // Modify the request ID to ensure we don't have conflicts between
    // multiple clients ids.
    var newId = '${_nextServiceRequestId++}:$originalId';
    request['id'] = newId;
    var responseCompleter = Completer<Map<String, Object>>();
    _pendingServiceExtensionRequests[newId] = responseCompleter;
    _responseSink.add(request);
    return responseCompleter.future;
  }

  void _delegateRequest(Map<String, Object> request) async {
    try {
      var id = request['id'] as String;
      // Check if this is actually a response to a pending request.
      if (_pendingServiceExtensionRequests.containsKey(id)) {
        // Restore the original request ID.
        var originalId = id.substring(id.indexOf(':') + 1);
        _pendingServiceExtensionRequests[id]
            .complete(Map.of(request)..['id'] = originalId);
        return;
      }
      var method = request['method'] as String;
      if (method == null) {
        throw RPCError(null, -32600, 'Invalid Request', request);
      }
      var params = request['params'] as Map;
      Response response;

      switch (method) {
        case 'registerService':
          _serviceExtensionRegistry.registerExtension(params['service'], this);
          response = Success();
          break;
        case 'addBreakpoint':
          response = await _serviceImplementation.addBreakpoint(
            params['isolateId'],
            params['scriptId'],
            params['line'],
            column: params['column'],
          );
          break;
        case 'addBreakpointWithScriptUri':
          response = await _serviceImplementation.addBreakpointWithScriptUri(
            params['isolateId'],
            params['scriptUri'],
            params['line'],
            column: params['column'],
          );
          break;
        case 'addBreakpointAtEntry':
          response = await _serviceImplementation.addBreakpointAtEntry(
            params['isolateId'],
            params['functionId'],
          );
          break;
        case 'clearCpuSamples':
          response = await _serviceImplementation.clearCpuSamples(
            params['isolateId'],
          );
          break;
        case 'clearVMTimeline':
          response = await _serviceImplementation.clearVMTimeline();
          break;
        case 'invoke':
          response = await _serviceImplementation.invoke(
            params['isolateId'],
            params['targetId'],
            params['selector'],
            List<String>.from(params['argumentIds'] ?? []),
            disableBreakpoints: params['disableBreakpoints'],
          );
          break;
        case 'evaluate':
          response = await _serviceImplementation.evaluate(
            params['isolateId'],
            params['targetId'],
            params['expression'],
            scope: params['scope']?.cast<String, String>(),
            disableBreakpoints: params['disableBreakpoints'],
          );
          break;
        case 'evaluateInFrame':
          response = await _serviceImplementation.evaluateInFrame(
            params['isolateId'],
            params['frameIndex'],
            params['expression'],
            scope: params['scope']?.cast<String, String>(),
            disableBreakpoints: params['disableBreakpoints'],
          );
          break;
        case 'getAllocationProfile':
          response = await _serviceImplementation.getAllocationProfile(
            params['isolateId'],
            reset: params['reset'],
            gc: params['gc'],
          );
          break;
        case 'getClientName':
          response = await _serviceImplementation.getClientName();
          break;
        case 'getCpuSamples':
          response = await _serviceImplementation.getCpuSamples(
            params['isolateId'],
            params['timeOriginMicros'],
            params['timeExtentMicros'],
          );
          break;
        case 'getFlagList':
          response = await _serviceImplementation.getFlagList();
          break;
        case 'getInboundReferences':
          response = await _serviceImplementation.getInboundReferences(
            params['isolateId'],
            params['targetId'],
            params['limit'],
          );
          break;
        case 'getInstances':
          response = await _serviceImplementation.getInstances(
            params['isolateId'],
            params['objectId'],
            params['limit'],
          );
          break;
        case 'getIsolate':
          response = await _serviceImplementation.getIsolate(
            params['isolateId'],
          );
          break;
        case 'getIsolateGroup':
          response = await _serviceImplementation.getIsolateGroup(
            params['isolateGroupId'],
          );
          break;
        case 'getMemoryUsage':
          response = await _serviceImplementation.getMemoryUsage(
            params['isolateId'],
          );
          break;
        case 'getIsolateGroupMemoryUsage':
          response = await _serviceImplementation.getIsolateGroupMemoryUsage(
            params['isolateGroupId'],
          );
          break;
        case 'getScripts':
          response = await _serviceImplementation.getScripts(
            params['isolateId'],
          );
          break;
        case 'getObject':
          response = await _serviceImplementation.getObject(
            params['isolateId'],
            params['objectId'],
            offset: params['offset'],
            count: params['count'],
          );
          break;
        case 'getRetainingPath':
          response = await _serviceImplementation.getRetainingPath(
            params['isolateId'],
            params['targetId'],
            params['limit'],
          );
          break;
        case 'getStack':
          response = await _serviceImplementation.getStack(
            params['isolateId'],
          );
          break;
        case 'getSourceReport':
          response = await _serviceImplementation.getSourceReport(
            params['isolateId'],
            List<String>.from(params['reports'] ?? []),
            scriptId: params['scriptId'],
            tokenPos: params['tokenPos'],
            endTokenPos: params['endTokenPos'],
            forceCompile: params['forceCompile'],
          );
          break;
        case 'getVersion':
          response = await _serviceImplementation.getVersion();
          break;
        case 'getVM':
          response = await _serviceImplementation.getVM();
          break;
        case 'getVMTimeline':
          response = await _serviceImplementation.getVMTimeline(
            timeOriginMicros: params['timeOriginMicros'],
            timeExtentMicros: params['timeExtentMicros'],
          );
          break;
        case 'getVMTimelineFlags':
          response = await _serviceImplementation.getVMTimelineFlags();
          break;
        case 'getVMTimelineMicros':
          response = await _serviceImplementation.getVMTimelineMicros();
          break;
        case 'pause':
          response = await _serviceImplementation.pause(
            params['isolateId'],
          );
          break;
        case 'kill':
          response = await _serviceImplementation.kill(
            params['isolateId'],
          );
          break;
        case 'reloadSources':
          response = await _serviceImplementation.reloadSources(
            params['isolateId'],
            force: params['force'],
            pause: params['pause'],
            rootLibUri: params['rootLibUri'],
            packagesUri: params['packagesUri'],
          );
          break;
        case 'removeBreakpoint':
          response = await _serviceImplementation.removeBreakpoint(
            params['isolateId'],
            params['breakpointId'],
          );
          break;
        case 'requestHeapSnapshot':
          response = await _serviceImplementation.requestHeapSnapshot(
            params['isolateId'],
          );
          break;
        case 'requirePermissionToResume':
          response = await _serviceImplementation.requirePermissionToResume(
            onPauseStart: params['onPauseStart'],
            onPauseReload: params['onPauseReload'],
            onPauseExit: params['onPauseExit'],
          );
          break;
        case 'resume':
          response = await _serviceImplementation.resume(
            params['isolateId'],
            step: params['step'],
            frameIndex: params['frameIndex'],
          );
          break;
        case 'setClientName':
          response = await _serviceImplementation.setClientName(
            params['name'],
          );
          break;
        case 'setExceptionPauseMode':
          response = await _serviceImplementation.setExceptionPauseMode(
            params['isolateId'],
            params['mode'],
          );
          break;
        case 'setFlag':
          response = await _serviceImplementation.setFlag(
            params['name'],
            params['value'],
          );
          break;
        case 'setLibraryDebuggable':
          response = await _serviceImplementation.setLibraryDebuggable(
            params['isolateId'],
            params['libraryId'],
            params['isDebuggable'],
          );
          break;
        case 'setName':
          response = await _serviceImplementation.setName(
            params['isolateId'],
            params['name'],
          );
          break;
        case 'setVMName':
          response = await _serviceImplementation.setVMName(
            params['name'],
          );
          break;
        case 'setVMTimelineFlags':
          response = await _serviceImplementation.setVMTimelineFlags(
            List<String>.from(params['recordedStreams'] ?? []),
          );
          break;
        case 'streamCancel':
          var id = params['streamId'];
          var existing = _streamSubscriptions.remove(id);
          if (existing == null) {
            throw RPCError('streamCancel', 104, 'Stream not subscribed', {
              'details': "The stream '$id' is not subscribed",
            });
          }
          await existing.cancel();
          response = Success();
          break;
        case 'streamListen':
          var id = params['streamId'];
          if (_streamSubscriptions.containsKey(id)) {
            throw RPCError('streamListen', 103, 'Stream already subscribed', {
              'details': "The stream '$id' is already subscribed",
            });
          }

          var stream = id == 'Service'
              ? _serviceExtensionRegistry.onExtensionEvent
              : _serviceImplementation.onEvent(id);
          _streamSubscriptions[id] = stream.listen((e) {
            _responseSink.add({
              'jsonrpc': '2.0',
              'method': 'streamNotify',
              'params': {
                'streamId': id,
                'event': e.toJson(),
              },
            });
          });
          response = Success();
          break;
        default:
          var registeredClient = _serviceExtensionRegistry.clientFor(method);
          if (registeredClient != null) {
            // Check for any client which has registered this extension, if we
            // have one then delegate the request to that client.
            _responseSink.add(await registeredClient
                ._forwardServiceExtensionRequest(request));
            // Bail out early in this case, we are just acting as a proxy and
            // never get a `Response` instance.
            return;
          } else if (method.startsWith('ext.')) {
            // Remaining methods with `ext.` are assumed to be registered via
            // dart:developer, which the service implementation handles.
            var args = params == null ? null : Map.of(params);
            var isolateId = args?.remove('isolateId');
            response = await _serviceImplementation.callServiceExtension(method,
                isolateId: isolateId, args: args);
          } else {
            throw RPCError(method, -32601, 'Method not found', request);
          }
      }
      if (response == null) {
        throw StateError('Invalid null response from service');
      }
      _responseSink.add({
        'jsonrpc': '2.0',
        'id': id,
        'result': response.toJson(),
      });
    } catch (e, st) {
      var error = e is RPCError
          ? {'code': e.code, 'data': e.data, 'message': e.message}
          : {'code': -32603, 'message': '$e\n$st'};
      _responseSink.add({
        'jsonrpc': '2.0',
        'id': request['id'],
        'error': error,
      });
    }
  }
}

class VmService implements VmServiceInterface {
  StreamSubscription _streamSub;
  Function _writeMessage;
  int _id = 0;
  Map<String, Completer> _completers = {};
  Map<String, String> _methodCalls = {};
  Map<String, ServiceCallback> _services = {};
  Log _log;

  StreamController<String> _onSend = StreamController.broadcast(sync: true);
  StreamController<String> _onReceive = StreamController.broadcast(sync: true);

  final Completer _onDoneCompleter = Completer();

  Map<String, StreamController<Event>> _eventControllers = {};

  StreamController<Event> _getEventController(String eventName) {
    StreamController<Event> controller = _eventControllers[eventName];
    if (controller == null) {
      controller = StreamController.broadcast();
      _eventControllers[eventName] = controller;
    }
    return controller;
  }

  DisposeHandler _disposeHandler;

  VmService(
    Stream<dynamic> /*String|List<int>*/ inStream,
    void writeMessage(String message), {
    Log log,
    DisposeHandler disposeHandler,
    Future streamClosed,
  }) {
    _streamSub = inStream.listen(_processMessage,
        onDone: () => _onDoneCompleter.complete());
    _writeMessage = writeMessage;
    _log = log == null ? _NullLog() : log;
    _disposeHandler = disposeHandler;
    streamClosed?.then((_) {
      if (!_onDoneCompleter.isCompleted) {
        _onDoneCompleter.complete();
      }
    });
  }

  @override
  Stream<Event> onEvent(String streamId) =>
      _getEventController(streamId).stream;

  // VMUpdate, VMFlagUpdate
  Stream<Event> get onVMEvent => _getEventController('VM').stream;

  // IsolateStart, IsolateRunnable, IsolateExit, IsolateUpdate, IsolateReload, ServiceExtensionAdded
  Stream<Event> get onIsolateEvent => _getEventController('Isolate').stream;

  // PauseStart, PauseExit, PauseBreakpoint, PauseInterrupted, PauseException, PausePostRequest, Resume, BreakpointAdded, BreakpointResolved, BreakpointRemoved, Inspect, None
  Stream<Event> get onDebugEvent => _getEventController('Debug').stream;

  // GC
  Stream<Event> get onGCEvent => _getEventController('GC').stream;

  // Extension
  Stream<Event> get onExtensionEvent => _getEventController('Extension').stream;

  // TimelineEvents
  Stream<Event> get onTimelineEvent => _getEventController('Timeline').stream;

  // Logging
  Stream<Event> get onLoggingEvent => _getEventController('Logging').stream;

  // ServiceRegistered, ServiceUnregistered
  Stream<Event> get onServiceEvent => _getEventController('Service').stream;

  // HeapSnapshot
  Stream<Event> get onHeapSnapshotEvent =>
      _getEventController('HeapSnapshot').stream;

  // WriteEvent
  Stream<Event> get onStdoutEvent => _getEventController('Stdout').stream;

  // WriteEvent
  Stream<Event> get onStderrEvent => _getEventController('Stderr').stream;

  @override
  Future<Breakpoint> addBreakpoint(
    String isolateId,
    String scriptId,
    int line, {
    int column,
  }) {
    Map m = {'isolateId': isolateId, 'scriptId': scriptId, 'line': line};
    if (column != null) {
      m['column'] = column;
    }
    return _call('addBreakpoint', m);
  }

  @override
  Future<Breakpoint> addBreakpointWithScriptUri(
    String isolateId,
    String scriptUri,
    int line, {
    int column,
  }) {
    Map m = {'isolateId': isolateId, 'scriptUri': scriptUri, 'line': line};
    if (column != null) {
      m['column'] = column;
    }
    return _call('addBreakpointWithScriptUri', m);
  }

  @override
  Future<Breakpoint> addBreakpointAtEntry(String isolateId, String functionId) {
    return _call('addBreakpointAtEntry',
        {'isolateId': isolateId, 'functionId': functionId});
  }

  @override
  Future<Success> clearCpuSamples(String isolateId) {
    return _call('clearCpuSamples', {'isolateId': isolateId});
  }

  @override
  Future<Success> clearVMTimeline() => _call('clearVMTimeline');

  @override
  Future<dynamic> invoke(
    String isolateId,
    String targetId,
    String selector,
    List<String> argumentIds, {
    bool disableBreakpoints,
  }) {
    Map m = {
      'isolateId': isolateId,
      'targetId': targetId,
      'selector': selector,
      'argumentIds': argumentIds
    };
    if (disableBreakpoints != null) {
      m['disableBreakpoints'] = disableBreakpoints;
    }
    return _call('invoke', m);
  }

  @override
  Future<dynamic> evaluate(
    String isolateId,
    String targetId,
    String expression, {
    Map<String, String> scope,
    bool disableBreakpoints,
  }) {
    Map m = {
      'isolateId': isolateId,
      'targetId': targetId,
      'expression': expression
    };
    if (scope != null) {
      m['scope'] = scope;
    }
    if (disableBreakpoints != null) {
      m['disableBreakpoints'] = disableBreakpoints;
    }
    return _call('evaluate', m);
  }

  @override
  Future<dynamic> evaluateInFrame(
    String isolateId,
    int frameIndex,
    String expression, {
    Map<String, String> scope,
    bool disableBreakpoints,
  }) {
    Map m = {
      'isolateId': isolateId,
      'frameIndex': frameIndex,
      'expression': expression
    };
    if (scope != null) {
      m['scope'] = scope;
    }
    if (disableBreakpoints != null) {
      m['disableBreakpoints'] = disableBreakpoints;
    }
    return _call('evaluateInFrame', m);
  }

  @override
  Future<AllocationProfile> getAllocationProfile(String isolateId,
      {bool reset, bool gc}) {
    Map m = {'isolateId': isolateId};
    if (reset != null && reset) {
      m['reset'] = reset;
    }
    if (gc != null && gc) {
      m['gc'] = gc;
    }
    return _call('getAllocationProfile', m);
  }

  @override
  Future<ClientName> getClientName() => _call('getClientName');

  @override
  Future<CpuSamples> getCpuSamples(
      String isolateId, int timeOriginMicros, int timeExtentMicros) {
    return _call('getCpuSamples', {
      'isolateId': isolateId,
      'timeOriginMicros': timeOriginMicros,
      'timeExtentMicros': timeExtentMicros
    });
  }

  @override
  Future<FlagList> getFlagList() => _call('getFlagList');

  @override
  Future<dynamic> getInboundReferences(
      String isolateId, String targetId, int limit) {
    return _call('getInboundReferences',
        {'isolateId': isolateId, 'targetId': targetId, 'limit': limit});
  }

  @override
  Future<InstanceSet> getInstances(
      String isolateId, String objectId, int limit) {
    return _call('getInstances',
        {'isolateId': isolateId, 'objectId': objectId, 'limit': limit});
  }

  @override
  Future<dynamic> getIsolate(String isolateId) {
    return _call('getIsolate', {'isolateId': isolateId});
  }

  @override
  Future<dynamic> getIsolateGroup(String isolateGroupId) {
    return _call('getIsolateGroup', {'isolateGroupId': isolateGroupId});
  }

  @override
  Future<dynamic> getMemoryUsage(String isolateId) {
    return _call('getMemoryUsage', {'isolateId': isolateId});
  }

  @override
  Future<dynamic> getIsolateGroupMemoryUsage(String isolateGroupId) {
    return _call(
        'getIsolateGroupMemoryUsage', {'isolateGroupId': isolateGroupId});
  }

  @override
  Future<ScriptList> getScripts(String isolateId) {
    return _call('getScripts', {'isolateId': isolateId});
  }

  @override
  Future<dynamic> getObject(
    String isolateId,
    String objectId, {
    int offset,
    int count,
  }) {
    Map m = {'isolateId': isolateId, 'objectId': objectId};
    if (offset != null) {
      m['offset'] = offset;
    }
    if (count != null) {
      m['count'] = count;
    }
    return _call('getObject', m);
  }

  @override
  Future<RetainingPath> getRetainingPath(
      String isolateId, String targetId, int limit) {
    return _call('getRetainingPath',
        {'isolateId': isolateId, 'targetId': targetId, 'limit': limit});
  }

  @override
  Future<Stack> getStack(String isolateId) {
    return _call('getStack', {'isolateId': isolateId});
  }

  @override
  Future<SourceReport> getSourceReport(
    String isolateId,
    /*List<SourceReportKind>*/
    List<String> reports, {
    String scriptId,
    int tokenPos,
    int endTokenPos,
    bool forceCompile,
  }) {
    Map m = {'isolateId': isolateId, 'reports': reports};
    if (scriptId != null) {
      m['scriptId'] = scriptId;
    }
    if (tokenPos != null) {
      m['tokenPos'] = tokenPos;
    }
    if (endTokenPos != null) {
      m['endTokenPos'] = endTokenPos;
    }
    if (forceCompile != null) {
      m['forceCompile'] = forceCompile;
    }
    return _call('getSourceReport', m);
  }

  @override
  Future<Version> getVersion() => _call('getVersion');

  @override
  Future<VM> getVM() => _call('getVM');

  @override
  Future<Timeline> getVMTimeline({int timeOriginMicros, int timeExtentMicros}) {
    Map m = {};
    if (timeOriginMicros != null) {
      m['timeOriginMicros'] = timeOriginMicros;
    }
    if (timeExtentMicros != null) {
      m['timeExtentMicros'] = timeExtentMicros;
    }
    return _call('getVMTimeline', m);
  }

  @override
  Future<TimelineFlags> getVMTimelineFlags() => _call('getVMTimelineFlags');

  @override
  Future<Timestamp> getVMTimelineMicros() => _call('getVMTimelineMicros');

  @override
  Future<Success> pause(String isolateId) {
    return _call('pause', {'isolateId': isolateId});
  }

  @override
  Future<Success> kill(String isolateId) {
    return _call('kill', {'isolateId': isolateId});
  }

  @override
  Future<Success> registerService(String service, String alias) {
    return _call('registerService', {'service': service, 'alias': alias});
  }

  @override
  Future<ReloadReport> reloadSources(
    String isolateId, {
    bool force,
    bool pause,
    String rootLibUri,
    String packagesUri,
  }) {
    Map m = {'isolateId': isolateId};
    if (force != null) {
      m['force'] = force;
    }
    if (pause != null) {
      m['pause'] = pause;
    }
    if (rootLibUri != null) {
      m['rootLibUri'] = rootLibUri;
    }
    if (packagesUri != null) {
      m['packagesUri'] = packagesUri;
    }
    return _call('reloadSources', m);
  }

  @override
  Future<Success> removeBreakpoint(String isolateId, String breakpointId) {
    return _call('removeBreakpoint',
        {'isolateId': isolateId, 'breakpointId': breakpointId});
  }

  @override
  Future<Success> requestHeapSnapshot(String isolateId) {
    return _call('requestHeapSnapshot', {'isolateId': isolateId});
  }

  @override
  Future<Success> requirePermissionToResume(
      {bool onPauseStart, bool onPauseReload, bool onPauseExit}) {
    Map m = {};
    if (onPauseStart != null) {
      m['onPauseStart'] = onPauseStart;
    }
    if (onPauseReload != null) {
      m['onPauseReload'] = onPauseReload;
    }
    if (onPauseExit != null) {
      m['onPauseExit'] = onPauseExit;
    }
    return _call('requirePermissionToResume', m);
  }

  @override
  Future<Success> resume(String isolateId,
      {/*StepOption*/ String step, int frameIndex}) {
    Map m = {'isolateId': isolateId};
    if (step != null) {
      m['step'] = step;
    }
    if (frameIndex != null) {
      m['frameIndex'] = frameIndex;
    }
    return _call('resume', m);
  }

  @override
  Future<Success> setClientName(String name) {
    return _call('setClientName', {'name': name});
  }

  @override
  Future<Success> setExceptionPauseMode(
      String isolateId, /*ExceptionPauseMode*/ String mode) {
    return _call(
        'setExceptionPauseMode', {'isolateId': isolateId, 'mode': mode});
  }

  @override
  Future<dynamic> setFlag(String name, String value) {
    return _call('setFlag', {'name': name, 'value': value});
  }

  @override
  Future<Success> setLibraryDebuggable(
      String isolateId, String libraryId, bool isDebuggable) {
    return _call('setLibraryDebuggable', {
      'isolateId': isolateId,
      'libraryId': libraryId,
      'isDebuggable': isDebuggable
    });
  }

  @override
  Future<Success> setName(String isolateId, String name) {
    return _call('setName', {'isolateId': isolateId, 'name': name});
  }

  @override
  Future<Success> setVMName(String name) {
    return _call('setVMName', {'name': name});
  }

  @override
  Future<Success> setVMTimelineFlags(List<String> recordedStreams) {
    return _call('setVMTimelineFlags', {'recordedStreams': recordedStreams});
  }

  @override
  Future<Success> streamCancel(String streamId) {
    return _call('streamCancel', {'streamId': streamId});
  }

  @override
  Future<Success> streamListen(String streamId) {
    return _call('streamListen', {'streamId': streamId});
  }

  /// Call an arbitrary service protocol method. This allows clients to call
  /// methods not explicitly exposed by this library.
  Future<Response> callMethod(String method, {String isolateId, Map args}) {
    return callServiceExtension(method, isolateId: isolateId, args: args);
  }

  /// Invoke a specific service protocol extension method.
  ///
  /// See https://api.dartlang.org/stable/dart-developer/dart-developer-library.html.
  @override
  Future<Response> callServiceExtension(String method,
      {String isolateId, Map args}) {
    if (args == null && isolateId == null) {
      return _call(method);
    } else if (args == null) {
      return _call(method, {'isolateId': isolateId});
    } else {
      args = Map.from(args);
      if (isolateId != null) {
        args['isolateId'] = isolateId;
      }
      return _call(method, args);
    }
  }

  Stream<String> get onSend => _onSend.stream;

  Stream<String> get onReceive => _onReceive.stream;

  void dispose() {
    _streamSub.cancel();
    _completers.forEach((id, c) {
      final method = _methodCalls[id];
      return c.completeError(
          RPCError(method, -32000, 'Service connection disposed'));
    });
    _completers.clear();
    if (_disposeHandler != null) {
      _disposeHandler();
    }
    if (!_onDoneCompleter.isCompleted) {
      _onDoneCompleter.complete();
    }
  }

  Future get onDone => _onDoneCompleter.future;

  Future<T> _call<T>(String method, [Map args]) {
    String id = '${++_id}';
    Completer<T> completer = Completer<T>();
    _completers[id] = completer;
    _methodCalls[id] = method;
    Map m = {'id': id, 'method': method};
    if (args != null) m['params'] = args;
    String message = jsonEncode(m);
    _onSend.add(message);
    _writeMessage(message);
    return completer.future;
  }

  /// Register a service for invocation.
  void registerServiceCallback(String service, ServiceCallback cb) {
    if (_services.containsKey(service)) {
      throw Exception('Service \'${service}\' already registered');
    }
    _services[service] = cb;
  }

  void _processMessage(dynamic message) {
    // Expect a String, an int[], or a ByteData.

    if (message is String) {
      _processMessageStr(message);
    } else if (message is List<int>) {
      Uint8List list = Uint8List.fromList(message);
      _processMessageByteData(ByteData.view(list.buffer));
    } else if (message is ByteData) {
      _processMessageByteData(message);
    } else {
      _log.warning('unknown message type: ${message.runtimeType}');
    }
  }

  void _processMessageByteData(ByteData bytes) {
    final int metaOffset = 4;
    final int dataOffset = bytes.getUint32(0, Endian.little);
    final metaLength = dataOffset - metaOffset;
    final dataLength = bytes.lengthInBytes - dataOffset;
    final meta = utf8.decode(Uint8List.view(
        bytes.buffer, bytes.offsetInBytes + metaOffset, metaLength));
    final data = ByteData.view(
        bytes.buffer, bytes.offsetInBytes + dataOffset, dataLength);
    dynamic map = jsonDecode(meta);
    if (map != null && map['method'] == 'streamNotify') {
      String streamId = map['params']['streamId'];
      Map event = map['params']['event'];
      event['data'] = data;
      _getEventController(streamId)
          .add(createServiceObject(event, const ['Event']));
    }
  }

  void _processMessageStr(String message) {
    var json;
    try {
      _onReceive.add(message);

      json = jsonDecode(message);
    } catch (e, s) {
      _log.severe('unable to decode message: ${message}, ${e}\n${s}');
      return;
    }

    if (json.containsKey('method')) {
      if (json.containsKey('id')) {
        _processRequest(json);
      } else {
        _processNotification(json);
      }
    } else if (json.containsKey('id') &&
        (json.containsKey('result') || json.containsKey('error'))) {
      _processResponse(json);
    } else {
      _log.severe('unknown message type: ${message}');
    }
  }

  void _processResponse(Map<String, dynamic> json) {
    Completer completer = _completers.remove(json['id']);
    String methodName = _methodCalls.remove(json['id']);
    List<String> returnTypes = _methodReturnTypes[methodName];
    if (completer == null) {
      _log.severe('unmatched request response: ${jsonEncode(json)}');
    } else if (json['error'] != null) {
      completer.completeError(RPCError.parse(methodName, json['error']));
    } else {
      Map<String, dynamic> result = json['result'] as Map<String, dynamic>;
      String type = result['type'];
      if (_typeFactories[type] == null) {
        completer.complete(Response.parse(result));
      } else {
        completer.complete(createServiceObject(result, returnTypes));
      }
    }
  }

  Future _processRequest(Map<String, dynamic> json) async {
    final Map m = await _routeRequest(json['method'], json['params']);
    m['id'] = json['id'];
    m['jsonrpc'] = '2.0';
    String message = jsonEncode(m);
    _onSend.add(message);
    _writeMessage(message);
  }

  Future _processNotification(Map<String, dynamic> json) async {
    final String method = json['method'];
    final Map params = json['params'];
    if (method == 'streamNotify') {
      String streamId = params['streamId'];
      _getEventController(streamId)
          .add(createServiceObject(params['event'], const ['Event']));
    } else {
      await _routeRequest(method, params);
    }
  }

  Future<Map> _routeRequest(String method, Map params) async {
    try {
      if (_services.containsKey(method)) {
        return await _services[method](params);
      }
      return {
        'error': {
          'code': -32601, // Method not found
          'message': 'Method not found \'$method\''
        }
      };
    } catch (e, st) {
      return {
        'error': {
          'code': -32000, // SERVER ERROR
          'message': 'Unexpected Server Error $e\n$st'
        }
      };
    }
  }
}

typedef DisposeHandler = Future Function();

class RPCError {
  static RPCError parse(String callingMethod, dynamic json) {
    return RPCError(callingMethod, json['code'], json['message'], json['data']);
  }

  final String callingMethod;
  final int code;
  final String message;
  final Map data;

  RPCError(this.callingMethod, this.code, this.message, [this.data]);

  String get details => data == null ? null : data['details'];

  String toString() {
    if (details == null) {
      return '${message} (${code}) from ${callingMethod}()';
    } else {
      return '${message} (${code}) from ${callingMethod}():\n${details}';
    }
  }
}

/// An `ExtensionData` is an arbitrary map that can have any contents.
class ExtensionData {
  static ExtensionData parse(Map json) =>
      json == null ? null : ExtensionData._fromJson(json);

  final Map data;

  ExtensionData() : data = {};

  ExtensionData._fromJson(this.data);

  String toString() => '[ExtensionData ${data}]';
}

/// A logging handler you can pass to a [VmService] instance in order to get
/// notifications of non-fatal service protocol warnings and errors.
abstract class Log {
  /// Log a warning level message.
  void warning(String message);

  /// Log an error level message.
  void severe(String message);
}

class _NullLog implements Log {
  void warning(String message) {}
  void severe(String message) {}
}
// enums

class CodeKind {
  CodeKind._();

  static const String kDart = 'Dart';
  static const String kNative = 'Native';
  static const String kStub = 'Stub';
  static const String kTag = 'Tag';
  static const String kCollected = 'Collected';
}

class ErrorKind {
  ErrorKind._();

  /// The isolate has encountered an unhandled Dart exception.
  static const String kUnhandledException = 'UnhandledException';

  /// The isolate has encountered a Dart language error in the program.
  static const String kLanguageError = 'LanguageError';

  /// The isolate has encountered an internal error. These errors should be
  /// reported as bugs.
  static const String kInternalError = 'InternalError';

  /// The isolate has been terminated by an external source.
  static const String kTerminationError = 'TerminationError';
}

/// An enum of available event streams.
class EventStreams {
  EventStreams._();

  static const String kVM = 'VM';
  static const String kIsolate = 'Isolate';
  static const String kDebug = 'Debug';
  static const String kGC = 'GC';
  static const String kExtension = 'Extension';
  static const String kTimeline = 'Timeline';
  static const String kLogging = 'Logging';
  static const String kService = 'Service';
  static const String kHeapSnapshot = 'HeapSnapshot';
  static const String kStdout = 'Stdout';
  static const String kStderr = 'Stderr';
}

/// Adding new values to `EventKind` is considered a backwards compatible
/// change. Clients should ignore unrecognized events.
class EventKind {
  EventKind._();

  /// Notification that VM identifying information has changed. Currently used
  /// to notify of changes to the VM debugging name via setVMName.
  static const String kVMUpdate = 'VMUpdate';

  /// Notification that a VM flag has been changed via the service protocol.
  static const String kVMFlagUpdate = 'VMFlagUpdate';

  /// Notification that a new isolate has started.
  static const String kIsolateStart = 'IsolateStart';

  /// Notification that an isolate is ready to run.
  static const String kIsolateRunnable = 'IsolateRunnable';

  /// Notification that an isolate has exited.
  static const String kIsolateExit = 'IsolateExit';

  /// Notification that isolate identifying information has changed. Currently
  /// used to notify of changes to the isolate debugging name via setName.
  static const String kIsolateUpdate = 'IsolateUpdate';

  /// Notification that an isolate has been reloaded.
  static const String kIsolateReload = 'IsolateReload';

  /// Notification that an extension RPC was registered on an isolate.
  static const String kServiceExtensionAdded = 'ServiceExtensionAdded';

  /// An isolate has paused at start, before executing code.
  static const String kPauseStart = 'PauseStart';

  /// An isolate has paused at exit, before terminating.
  static const String kPauseExit = 'PauseExit';

  /// An isolate has paused at a breakpoint or due to stepping.
  static const String kPauseBreakpoint = 'PauseBreakpoint';

  /// An isolate has paused due to interruption via pause.
  static const String kPauseInterrupted = 'PauseInterrupted';

  /// An isolate has paused due to an exception.
  static const String kPauseException = 'PauseException';

  /// An isolate has paused after a service request.
  static const String kPausePostRequest = 'PausePostRequest';

  /// An isolate has started or resumed execution.
  static const String kResume = 'Resume';

  /// Indicates an isolate is not yet runnable. Only appears in an Isolate's
  /// pauseEvent. Never sent over a stream.
  static const String kNone = 'None';

  /// A breakpoint has been added for an isolate.
  static const String kBreakpointAdded = 'BreakpointAdded';

  /// An unresolved breakpoint has been resolved for an isolate.
  static const String kBreakpointResolved = 'BreakpointResolved';

  /// A breakpoint has been removed.
  static const String kBreakpointRemoved = 'BreakpointRemoved';

  /// A garbage collection event.
  static const String kGC = 'GC';

  /// Notification of bytes written, for example, to stdout/stderr.
  static const String kWriteEvent = 'WriteEvent';

  /// Notification from dart:developer.inspect.
  static const String kInspect = 'Inspect';

  /// Event from dart:developer.postEvent.
  static const String kExtension = 'Extension';

  /// Event from dart:developer.log.
  static const String kLogging = 'Logging';

  /// Notification that a Service has been registered into the Service Protocol
  /// from another client.
  static const String kServiceRegistered = 'ServiceRegistered';

  /// Notification that a Service has been removed from the Service Protocol
  /// from another client.
  static const String kServiceUnregistered = 'ServiceUnregistered';
}

/// Adding new values to `InstanceKind` is considered a backwards compatible
/// change. Clients should treat unrecognized instance kinds as `PlainInstance`.
class InstanceKind {
  InstanceKind._();

  /// A general instance of the Dart class Object.
  static const String kPlainInstance = 'PlainInstance';

  /// null instance.
  static const String kNull = 'Null';

  /// true or false.
  static const String kBool = 'Bool';

  /// An instance of the Dart class double.
  static const String kDouble = 'Double';

  /// An instance of the Dart class int.
  static const String kInt = 'Int';

  /// An instance of the Dart class String.
  static const String kString = 'String';

  /// An instance of the built-in VM List implementation. User-defined Lists
  /// will be PlainInstance.
  static const String kList = 'List';

  /// An instance of the built-in VM Map implementation. User-defined Maps will
  /// be PlainInstance.
  static const String kMap = 'Map';

  /// Vector instance kinds.
  static const String kFloat32x4 = 'Float32x4';
  static const String kFloat64x2 = 'Float64x2';
  static const String kInt32x4 = 'Int32x4';

  /// An instance of the built-in VM TypedData implementations. User-defined
  /// TypedDatas will be PlainInstance.
  static const String kUint8ClampedList = 'Uint8ClampedList';
  static const String kUint8List = 'Uint8List';
  static const String kUint16List = 'Uint16List';
  static const String kUint32List = 'Uint32List';
  static const String kUint64List = 'Uint64List';
  static const String kInt8List = 'Int8List';
  static const String kInt16List = 'Int16List';
  static const String kInt32List = 'Int32List';
  static const String kInt64List = 'Int64List';
  static const String kFloat32List = 'Float32List';
  static const String kFloat64List = 'Float64List';
  static const String kInt32x4List = 'Int32x4List';
  static const String kFloat32x4List = 'Float32x4List';
  static const String kFloat64x2List = 'Float64x2List';

  /// An instance of the Dart class StackTrace.
  static const String kStackTrace = 'StackTrace';

  /// An instance of the built-in VM Closure implementation. User-defined
  /// Closures will be PlainInstance.
  static const String kClosure = 'Closure';

  /// An instance of the Dart class MirrorReference.
  static const String kMirrorReference = 'MirrorReference';

  /// An instance of the Dart class RegExp.
  static const String kRegExp = 'RegExp';

  /// An instance of the Dart class WeakProperty.
  static const String kWeakProperty = 'WeakProperty';

  /// An instance of the Dart class Type.
  static const String kType = 'Type';

  /// An instance of the Dart class TypeParameter.
  static const String kTypeParameter = 'TypeParameter';

  /// An instance of the Dart class TypeRef.
  static const String kTypeRef = 'TypeRef';

  /// An instance of the Dart class BoundedType.
  static const String kBoundedType = 'BoundedType';
}

/// A `SentinelKind` is used to distinguish different kinds of `Sentinel`
/// objects.
///
/// Adding new values to `SentinelKind` is considered a backwards compatible
/// change. Clients must handle this gracefully.
class SentinelKind {
  SentinelKind._();

  /// Indicates that the object referred to has been collected by the GC.
  static const String kCollected = 'Collected';

  /// Indicates that an object id has expired.
  static const String kExpired = 'Expired';

  /// Indicates that a variable or field has not been initialized.
  static const String kNotInitialized = 'NotInitialized';

  /// Indicates that a variable or field is in the process of being initialized.
  static const String kBeingInitialized = 'BeingInitialized';

  /// Indicates that a variable has been eliminated by the optimizing compiler.
  static const String kOptimizedOut = 'OptimizedOut';

  /// Reserved for future use.
  static const String kFree = 'Free';
}

/// A `FrameKind` is used to distinguish different kinds of `Frame` objects.
class FrameKind {
  FrameKind._();

  static const String kRegular = 'Regular';
  static const String kAsyncCausal = 'AsyncCausal';
  static const String kAsyncSuspensionMarker = 'AsyncSuspensionMarker';
  static const String kAsyncActivation = 'AsyncActivation';
}

class SourceReportKind {
  SourceReportKind._();

  /// Used to request a code coverage information.
  static const String kCoverage = 'Coverage';

  /// Used to request a list of token positions of possible breakpoints.
  static const String kPossibleBreakpoints = 'PossibleBreakpoints';
}

/// An `ExceptionPauseMode` indicates how the isolate pauses when an exception
/// is thrown.
class ExceptionPauseMode {
  ExceptionPauseMode._();

  static const String kNone = 'None';
  static const String kUnhandled = 'Unhandled';
  static const String kAll = 'All';
}

/// A `StepOption` indicates which form of stepping is requested in a [resume]
/// RPC.
class StepOption {
  StepOption._();

  static const String kInto = 'Into';
  static const String kOver = 'Over';
  static const String kOverAsyncSuspension = 'OverAsyncSuspension';
  static const String kOut = 'Out';
  static const String kRewind = 'Rewind';
}

// types

class AllocationProfile extends Response {
  static AllocationProfile parse(Map<String, dynamic> json) =>
      json == null ? null : AllocationProfile._fromJson(json);

  /// Allocation information for all class types.
  List<ClassHeapStats> members;

  /// Information about memory usage for the isolate.
  MemoryUsage memoryUsage;

  /// The timestamp of the last accumulator reset.
  ///
  /// If the accumulators have not been reset, this field is not present.
  @optional
  int dateLastAccumulatorReset;

  /// The timestamp of the last manually triggered GC.
  ///
  /// If a GC has not been triggered manually, this field is not present.
  @optional
  int dateLastServiceGC;

  AllocationProfile({
    @required this.members,
    @required this.memoryUsage,
    this.dateLastAccumulatorReset,
    this.dateLastServiceGC,
  });
  AllocationProfile._fromJson(Map<String, dynamic> json)
      : super._fromJson(json) {
    members = List<ClassHeapStats>.from(
        createServiceObject(json['members'], const ['ClassHeapStats']) ?? []);
    memoryUsage =
        createServiceObject(json['memoryUsage'], const ['MemoryUsage']);
    dateLastAccumulatorReset = json['dateLastAccumulatorReset'] is String
        ? int.parse(json['dateLastAccumulatorReset'])
        : json['dateLastAccumulatorReset'];
    dateLastServiceGC = json['dateLastServiceGC'] is String
        ? int.parse(json['dateLastServiceGC'])
        : json['dateLastServiceGC'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'AllocationProfile';
    json.addAll({
      'members': members.map((f) => f.toJson()).toList(),
      'memoryUsage': memoryUsage.toJson(),
    });
    _setIfNotNull(json, 'dateLastAccumulatorReset', dateLastAccumulatorReset);
    _setIfNotNull(json, 'dateLastServiceGC', dateLastServiceGC);
    return json;
  }

  String toString() => '[AllocationProfile ' //
      'type: ${type}, members: ${members}, memoryUsage: ${memoryUsage}]';
}

/// A `BoundField` represents a field bound to a particular value in an
/// `Instance`.
///
/// If the field is uninitialized, the `value` will be the `NotInitialized`
/// [Sentinel].
///
/// If the field is being initialized, the `value` will be the
/// `BeingInitialized` [Sentinel].
class BoundField {
  static BoundField parse(Map<String, dynamic> json) =>
      json == null ? null : BoundField._fromJson(json);

  FieldRef decl;

  /// [value] can be one of [InstanceRef] or [Sentinel].
  dynamic value;

  BoundField({
    @required this.decl,
    @required this.value,
  });
  BoundField._fromJson(Map<String, dynamic> json) {
    decl = createServiceObject(json['decl'], const ['FieldRef']);
    value =
        createServiceObject(json['value'], const ['InstanceRef', 'Sentinel']);
  }

  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json.addAll({
      'decl': decl.toJson(),
      'value': value.toJson(),
    });
    return json;
  }

  String toString() => '[BoundField decl: ${decl}, value: ${value}]';
}

/// A `BoundVariable` represents a local variable bound to a particular value in
/// a `Frame`.
///
/// If the variable is uninitialized, the `value` will be the `NotInitialized`
/// [Sentinel].
///
/// If the variable is being initialized, the `value` will be the
/// `BeingInitialized` [Sentinel].
///
/// If the variable has been optimized out by the compiler, the `value` will be
/// the `OptimizedOut` [Sentinel].
class BoundVariable extends Response {
  static BoundVariable parse(Map<String, dynamic> json) =>
      json == null ? null : BoundVariable._fromJson(json);

  String name;

  /// [value] can be one of [InstanceRef], [TypeArgumentsRef] or [Sentinel].
  dynamic value;

  /// The token position where this variable was declared.
  int declarationTokenPos;

  /// The first token position where this variable is visible to the scope.
  int scopeStartTokenPos;

  /// The last token position where this variable is visible to the scope.
  int scopeEndTokenPos;

  BoundVariable({
    @required this.name,
    @required this.value,
    @required this.declarationTokenPos,
    @required this.scopeStartTokenPos,
    @required this.scopeEndTokenPos,
  });
  BoundVariable._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    name = json['name'];
    value = createServiceObject(
        json['value'], const ['InstanceRef', 'TypeArgumentsRef', 'Sentinel']);
    declarationTokenPos = json['declarationTokenPos'];
    scopeStartTokenPos = json['scopeStartTokenPos'];
    scopeEndTokenPos = json['scopeEndTokenPos'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'BoundVariable';
    json.addAll({
      'name': name,
      'value': value.toJson(),
      'declarationTokenPos': declarationTokenPos,
      'scopeStartTokenPos': scopeStartTokenPos,
      'scopeEndTokenPos': scopeEndTokenPos,
    });
    return json;
  }

  String toString() => '[BoundVariable ' //
      'type: ${type}, name: ${name}, value: ${value}, declarationTokenPos: ${declarationTokenPos}, ' //
      'scopeStartTokenPos: ${scopeStartTokenPos}, scopeEndTokenPos: ${scopeEndTokenPos}]';
}

/// A `Breakpoint` describes a debugger breakpoint.
///
/// A breakpoint is `resolved` when it has been assigned to a specific program
/// location. A breakpoint my remain unresolved when it is in code which has not
/// yet been compiled or in a library which has not been loaded (i.e. a deferred
/// library).
class Breakpoint extends Obj {
  static Breakpoint parse(Map<String, dynamic> json) =>
      json == null ? null : Breakpoint._fromJson(json);

  /// A number identifying this breakpoint to the user.
  int breakpointNumber;

  /// Has this breakpoint been assigned to a specific program location?
  bool resolved;

  /// Is this a breakpoint that was added synthetically as part of a step
  /// OverAsyncSuspension resume command?
  @optional
  bool isSyntheticAsyncContinuation;

  /// SourceLocation when breakpoint is resolved, UnresolvedSourceLocation when
  /// a breakpoint is not resolved.
  ///
  /// [location] can be one of [SourceLocation] or [UnresolvedSourceLocation].
  dynamic location;

  Breakpoint({
    @required this.breakpointNumber,
    @required this.resolved,
    @required this.location,
    this.isSyntheticAsyncContinuation,
  });
  Breakpoint._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    breakpointNumber = json['breakpointNumber'];
    resolved = json['resolved'];
    isSyntheticAsyncContinuation = json['isSyntheticAsyncContinuation'];
    location = createServiceObject(
        json['location'], const ['SourceLocation', 'UnresolvedSourceLocation']);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = super.toJson();
    json['type'] = 'Breakpoint';
    json.addAll({
      'breakpointNumber': breakpointNumber,
      'resolved': resolved,
      'location': location.toJson(),
    });
    _setIfNotNull(
        json, 'isSyntheticAsyncContinuation', isSyntheticAsyncContinuation);
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is Breakpoint && id == other.id;

  String toString() => '[Breakpoint ' //
      'type: ${type}, id: ${id}, breakpointNumber: ${breakpointNumber}, ' //
      'resolved: ${resolved}, location: ${location}]';
}

/// `ClassRef` is a reference to a `Class`.
class ClassRef extends ObjRef {
  static ClassRef parse(Map<String, dynamic> json) =>
      json == null ? null : ClassRef._fromJson(json);

  /// The name of this class.
  String name;

  ClassRef({
    @required this.name,
  });
  ClassRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    name = json['name'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = super.toJson();
    json['type'] = '@Class';
    json.addAll({
      'name': name,
    });
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is ClassRef && id == other.id;

  String toString() => '[ClassRef type: ${type}, id: ${id}, name: ${name}]';
}

/// A `Class` provides information about a Dart language class.
class Class extends Obj {
  static Class parse(Map<String, dynamic> json) =>
      json == null ? null : Class._fromJson(json);

  /// The name of this class.
  String name;

  /// The error which occurred during class finalization, if it exists.
  @optional
  ErrorRef error;

  /// Is this an abstract class?
  bool isAbstract;

  /// Is this a const class?
  bool isConst;

  /// The library which contains this class.
  LibraryRef library;

  /// The location of this class in the source code.
  @optional
  SourceLocation location;

  /// The superclass of this class, if any.
  @optional
  ClassRef superClass;

  /// The supertype for this class, if any.
  ///
  /// The value will be of the kind: Type.
  @optional
  InstanceRef superType;

  /// A list of interface types for this class.
  ///
  /// The values will be of the kind: Type.
  List<InstanceRef> interfaces;

  /// The mixin type for this class, if any.
  ///
  /// The value will be of the kind: Type.
  @optional
  InstanceRef mixin;

  /// A list of fields in this class. Does not include fields from superclasses.
  List<FieldRef> fields;

  /// A list of functions in this class. Does not include functions from
  /// superclasses.
  List<FuncRef> functions;

  /// A list of subclasses of this class.
  List<ClassRef> subclasses;

  Class({
    @required this.name,
    @required this.isAbstract,
    @required this.isConst,
    @required this.library,
    @required this.interfaces,
    @required this.fields,
    @required this.functions,
    @required this.subclasses,
    this.error,
    this.location,
    this.superClass,
    this.superType,
    this.mixin,
  });
  Class._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    name = json['name'];
    error = createServiceObject(json['error'], const ['ErrorRef']);
    isAbstract = json['abstract'];
    isConst = json['const'];
    library = createServiceObject(json['library'], const ['LibraryRef']);
    location = createServiceObject(json['location'], const ['SourceLocation']);
    superClass = createServiceObject(json['super'], const ['ClassRef']);
    superType = createServiceObject(json['superType'], const ['InstanceRef']);
    interfaces = List<InstanceRef>.from(
        createServiceObject(json['interfaces'], const ['InstanceRef']) ?? []);
    mixin = createServiceObject(json['mixin'], const ['InstanceRef']);
    fields = List<FieldRef>.from(
        createServiceObject(json['fields'], const ['FieldRef']) ?? []);
    functions = List<FuncRef>.from(
        createServiceObject(json['functions'], const ['FuncRef']) ?? []);
    subclasses = List<ClassRef>.from(
        createServiceObject(json['subclasses'], const ['ClassRef']) ?? []);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = super.toJson();
    json['type'] = 'Class';
    json.addAll({
      'name': name,
      'abstract': isAbstract,
      'const': isConst,
      'library': library.toJson(),
      'interfaces': interfaces.map((f) => f.toJson()).toList(),
      'fields': fields.map((f) => f.toJson()).toList(),
      'functions': functions.map((f) => f.toJson()).toList(),
      'subclasses': subclasses.map((f) => f.toJson()).toList(),
    });
    _setIfNotNull(json, 'error', error?.toJson());
    _setIfNotNull(json, 'location', location?.toJson());
    _setIfNotNull(json, 'super', superClass?.toJson());
    _setIfNotNull(json, 'superType', superType?.toJson());
    _setIfNotNull(json, 'mixin', mixin?.toJson());
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is Class && id == other.id;

  String toString() => '[Class]';
}

class ClassHeapStats extends Response {
  static ClassHeapStats parse(Map<String, dynamic> json) =>
      json == null ? null : ClassHeapStats._fromJson(json);

  /// The class for which this memory information is associated.
  ClassRef classRef;

  /// The number of bytes allocated for instances of class since the accumulator
  /// was last reset.
  int accumulatedSize;

  /// The number of bytes currently allocated for instances of class.
  int bytesCurrent;

  /// The number of instances of class which have been allocated since the
  /// accumulator was last reset.
  int instancesAccumulated;

  /// The number of instances of class which are currently alive.
  int instancesCurrent;

  ClassHeapStats({
    @required this.classRef,
    @required this.accumulatedSize,
    @required this.bytesCurrent,
    @required this.instancesAccumulated,
    @required this.instancesCurrent,
  });
  ClassHeapStats._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    classRef = createServiceObject(json['class'], const ['ClassRef']);
    accumulatedSize = json['accumulatedSize'];
    bytesCurrent = json['bytesCurrent'];
    instancesAccumulated = json['instancesAccumulated'];
    instancesCurrent = json['instancesCurrent'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'ClassHeapStats';
    json.addAll({
      'class': classRef.toJson(),
      'accumulatedSize': accumulatedSize,
      'bytesCurrent': bytesCurrent,
      'instancesAccumulated': instancesAccumulated,
      'instancesCurrent': instancesCurrent,
    });
    return json;
  }

  String toString() => '[ClassHeapStats ' //
      'type: ${type}, classRef: ${classRef}, accumulatedSize: ${accumulatedSize}, ' //
      'bytesCurrent: ${bytesCurrent}, instancesAccumulated: ${instancesAccumulated}, instancesCurrent: ${instancesCurrent}]';
}

class ClassList extends Response {
  static ClassList parse(Map<String, dynamic> json) =>
      json == null ? null : ClassList._fromJson(json);

  List<ClassRef> classes;

  ClassList({
    @required this.classes,
  });
  ClassList._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    classes = List<ClassRef>.from(
        createServiceObject(json['classes'], const ['ClassRef']) ?? []);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'ClassList';
    json.addAll({
      'classes': classes.map((f) => f.toJson()).toList(),
    });
    return json;
  }

  String toString() => '[ClassList type: ${type}, classes: ${classes}]';
}

/// See [getClientName] and [setClientName].
class ClientName extends Response {
  static ClientName parse(Map<String, dynamic> json) =>
      json == null ? null : ClientName._fromJson(json);

  /// The name of the currently connected VM service client.
  String name;

  ClientName({
    @required this.name,
  });
  ClientName._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    name = json['name'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'ClientName';
    json.addAll({
      'name': name,
    });
    return json;
  }

  String toString() => '[ClientName type: ${type}, name: ${name}]';
}

/// `CodeRef` is a reference to a `Code` object.
class CodeRef extends ObjRef {
  static CodeRef parse(Map<String, dynamic> json) =>
      json == null ? null : CodeRef._fromJson(json);

  /// A name for this code object.
  String name;

  /// What kind of code object is this?
  /*CodeKind*/ String kind;

  CodeRef({
    @required this.name,
    @required this.kind,
  });
  CodeRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    name = json['name'];
    kind = json['kind'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = super.toJson();
    json['type'] = '@Code';
    json.addAll({
      'name': name,
      'kind': kind,
    });
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is CodeRef && id == other.id;

  String toString() =>
      '[CodeRef type: ${type}, id: ${id}, name: ${name}, kind: ${kind}]';
}

/// A `Code` object represents compiled code in the Dart VM.
class Code extends ObjRef {
  static Code parse(Map<String, dynamic> json) =>
      json == null ? null : Code._fromJson(json);

  /// A name for this code object.
  String name;

  /// What kind of code object is this?
  /*CodeKind*/ String kind;

  Code({
    @required this.name,
    @required this.kind,
  });
  Code._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    name = json['name'];
    kind = json['kind'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = super.toJson();
    json['type'] = 'Code';
    json.addAll({
      'name': name,
      'kind': kind,
    });
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is Code && id == other.id;

  String toString() =>
      '[Code type: ${type}, id: ${id}, name: ${name}, kind: ${kind}]';
}

class ContextRef extends ObjRef {
  static ContextRef parse(Map<String, dynamic> json) =>
      json == null ? null : ContextRef._fromJson(json);

  /// The number of variables in this context.
  int length;

  ContextRef({
    @required this.length,
  });
  ContextRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    length = json['length'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = super.toJson();
    json['type'] = '@Context';
    json.addAll({
      'length': length,
    });
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is ContextRef && id == other.id;

  String toString() =>
      '[ContextRef type: ${type}, id: ${id}, length: ${length}]';
}

/// A `Context` is a data structure which holds the captured variables for some
/// closure.
class Context extends Obj {
  static Context parse(Map<String, dynamic> json) =>
      json == null ? null : Context._fromJson(json);

  /// The number of variables in this context.
  int length;

  /// The enclosing context for this context.
  @optional
  Context parent;

  /// The variables in this context object.
  List<ContextElement> variables;

  Context({
    @required this.length,
    @required this.variables,
    this.parent,
  });
  Context._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    length = json['length'];
    parent = createServiceObject(json['parent'], const ['Context']);
    variables = List<ContextElement>.from(
        createServiceObject(json['variables'], const ['ContextElement']) ?? []);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = super.toJson();
    json['type'] = 'Context';
    json.addAll({
      'length': length,
      'variables': variables.map((f) => f.toJson()).toList(),
    });
    _setIfNotNull(json, 'parent', parent?.toJson());
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is Context && id == other.id;

  String toString() => '[Context ' //
      'type: ${type}, id: ${id}, length: ${length}, variables: ${variables}]';
}

class ContextElement {
  static ContextElement parse(Map<String, dynamic> json) =>
      json == null ? null : ContextElement._fromJson(json);

  /// [value] can be one of [InstanceRef] or [Sentinel].
  dynamic value;

  ContextElement({
    @required this.value,
  });
  ContextElement._fromJson(Map<String, dynamic> json) {
    value =
        createServiceObject(json['value'], const ['InstanceRef', 'Sentinel']);
  }

  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json.addAll({
      'value': value.toJson(),
    });
    return json;
  }

  String toString() => '[ContextElement value: ${value}]';
}

/// See [getCpuSamples] and [CpuSample].
class CpuSamples extends Response {
  static CpuSamples parse(Map<String, dynamic> json) =>
      json == null ? null : CpuSamples._fromJson(json);

  /// The sampling rate for the profiler in microseconds.
  int samplePeriod;

  /// The maximum possible stack depth for samples.
  int maxStackDepth;

  /// The number of samples returned.
  int sampleCount;

  /// The timespan the set of returned samples covers, in microseconds.
  int timeSpan;

  /// The start of the period of time in which the returned samples were
  /// collected.
  int timeOriginMicros;

  /// The duration of time covered by the returned samples.
  int timeExtentMicros;

  /// The process ID for the VM.
  int pid;

  /// A list of functions seen in the relevant samples. These references can be
  /// looked up using the indicies provided in a `CpuSample` `stack` to
  /// determine which function was on the stack.
  List<ProfileFunction> functions;

  /// A list of samples collected in the range `[timeOriginMicros,
  /// timeOriginMicros + timeExtentMicros]`
  List<CpuSample> samples;

  CpuSamples({
    @required this.samplePeriod,
    @required this.maxStackDepth,
    @required this.sampleCount,
    @required this.timeSpan,
    @required this.timeOriginMicros,
    @required this.timeExtentMicros,
    @required this.pid,
    @required this.functions,
    @required this.samples,
  });
  CpuSamples._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    samplePeriod = json['samplePeriod'];
    maxStackDepth = json['maxStackDepth'];
    sampleCount = json['sampleCount'];
    timeSpan = json['timeSpan'];
    timeOriginMicros = json['timeOriginMicros'];
    timeExtentMicros = json['timeExtentMicros'];
    pid = json['pid'];
    functions = List<ProfileFunction>.from(
        createServiceObject(json['functions'], const ['ProfileFunction']) ??
            []);
    samples = List<CpuSample>.from(
        createServiceObject(json['samples'], const ['CpuSample']) ?? []);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'CpuSamples';
    json.addAll({
      'samplePeriod': samplePeriod,
      'maxStackDepth': maxStackDepth,
      'sampleCount': sampleCount,
      'timeSpan': timeSpan,
      'timeOriginMicros': timeOriginMicros,
      'timeExtentMicros': timeExtentMicros,
      'pid': pid,
      'functions': functions.map((f) => f.toJson()).toList(),
      'samples': samples.map((f) => f.toJson()).toList(),
    });
    return json;
  }

  String toString() => '[CpuSamples]';
}

/// See [getCpuSamples] and [CpuSamples].
class CpuSample {
  static CpuSample parse(Map<String, dynamic> json) =>
      json == null ? null : CpuSample._fromJson(json);

  /// The thread ID representing the thread on which this sample was collected.
  int tid;

  /// The time this sample was collected in microseconds.
  int timestamp;

  /// The name of VM tag set when this sample was collected. Omitted if the VM
  /// tag for the sample is not considered valid.
  @optional
  String vmTag;

  /// The name of the User tag set when this sample was collected. Omitted if no
  /// User tag was set when this sample was collected.
  @optional
  String userTag;

  /// Provided and set to true if the sample's stack was truncated. This can
  /// happen if the stack is deeper than the `stackDepth` in the `CpuSamples`
  /// response.
  @optional
  bool truncated;

  /// The call stack at the time this sample was collected. The stack is to be
  /// interpreted as top to bottom. Each element in this array is a key into the
  /// `functions` array in `CpuSamples`.
  ///
  /// Example:
  ///
  /// `functions[stack[0]] = @Function(bar())` `functions[stack[1]] =
  /// @Function(foo())` `functions[stack[2]] = @Function(main())`
  List<int> stack;

  CpuSample({
    @required this.tid,
    @required this.timestamp,
    @required this.stack,
    this.vmTag,
    this.userTag,
    this.truncated,
  });
  CpuSample._fromJson(Map<String, dynamic> json) {
    tid = json['tid'];
    timestamp = json['timestamp'];
    vmTag = json['vmTag'];
    userTag = json['userTag'];
    truncated = json['truncated'];
    stack = List<int>.from(json['stack']);
  }

  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json.addAll({
      'tid': tid,
      'timestamp': timestamp,
      'stack': stack.map((f) => f).toList(),
    });
    _setIfNotNull(json, 'vmTag', vmTag);
    _setIfNotNull(json, 'userTag', userTag);
    _setIfNotNull(json, 'truncated', truncated);
    return json;
  }

  String toString() =>
      '[CpuSample tid: ${tid}, timestamp: ${timestamp}, stack: ${stack}]';
}

/// `ErrorRef` is a reference to an `Error`.
class ErrorRef extends ObjRef {
  static ErrorRef parse(Map<String, dynamic> json) =>
      json == null ? null : ErrorRef._fromJson(json);

  /// What kind of error is this?
  /*ErrorKind*/ String kind;

  /// A description of the error.
  String message;

  ErrorRef({
    @required this.kind,
    @required this.message,
  });
  ErrorRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    kind = json['kind'];
    message = json['message'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = super.toJson();
    json['type'] = '@Error';
    json.addAll({
      'kind': kind,
      'message': message,
    });
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is ErrorRef && id == other.id;

  String toString() =>
      '[ErrorRef type: ${type}, id: ${id}, kind: ${kind}, message: ${message}]';
}

/// An `Error` represents a Dart language level error. This is distinct from an
/// [rpc error].
class Error extends Obj {
  static Error parse(Map<String, dynamic> json) =>
      json == null ? null : Error._fromJson(json);

  /// What kind of error is this?
  /*ErrorKind*/ String kind;

  /// A description of the error.
  String message;

  /// If this error is due to an unhandled exception, this is the exception
  /// thrown.
  @optional
  InstanceRef exception;

  /// If this error is due to an unhandled exception, this is the stacktrace
  /// object.
  @optional
  InstanceRef stacktrace;

  Error({
    @required this.kind,
    @required this.message,
    this.exception,
    this.stacktrace,
  });
  Error._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    kind = json['kind'];
    message = json['message'];
    exception = createServiceObject(json['exception'], const ['InstanceRef']);
    stacktrace = createServiceObject(json['stacktrace'], const ['InstanceRef']);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = super.toJson();
    json['type'] = 'Error';
    json.addAll({
      'kind': kind,
      'message': message,
    });
    _setIfNotNull(json, 'exception', exception?.toJson());
    _setIfNotNull(json, 'stacktrace', stacktrace?.toJson());
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is Error && id == other.id;

  String toString() =>
      '[Error type: ${type}, id: ${id}, kind: ${kind}, message: ${message}]';
}

/// An `Event` is an asynchronous notification from the VM. It is delivered only
/// when the client has subscribed to an event stream using the [streamListen]
/// RPC.
///
/// For more information, see [events].
class Event extends Response {
  static Event parse(Map<String, dynamic> json) =>
      json == null ? null : Event._fromJson(json);

  /// What kind of event is this?
  /*EventKind*/ String kind;

  /// The isolate with which this event is associated.
  ///
  /// This is provided for all event kinds except for:
  ///  - VMUpdate, VMFlagUpdate
  @optional
  IsolateRef isolate;

  /// The vm with which this event is associated.
  ///
  /// This is provided for the event kind:
  ///  - VMUpdate, VMFlagUpdate
  @optional
  VMRef vm;

  /// The timestamp (in milliseconds since the epoch) associated with this
  /// event. For some isolate pause events, the timestamp is from when the
  /// isolate was paused. For other events, the timestamp is from when the event
  /// was created.
  int timestamp;

  /// The breakpoint which was added, removed, or resolved.
  ///
  /// This is provided for the event kinds:
  ///  - PauseBreakpoint
  ///  - BreakpointAdded
  ///  - BreakpointRemoved
  ///  - BreakpointResolved
  @optional
  Breakpoint breakpoint;

  /// The list of breakpoints at which we are currently paused for a
  /// PauseBreakpoint event.
  ///
  /// This list may be empty. For example, while single-stepping, the VM sends a
  /// PauseBreakpoint event with no breakpoints.
  ///
  /// If there is more than one breakpoint set at the program position, then all
  /// of them will be provided.
  ///
  /// This is provided for the event kinds:
  ///  - PauseBreakpoint
  @optional
  List<Breakpoint> pauseBreakpoints;

  /// The top stack frame associated with this event, if applicable.
  ///
  /// This is provided for the event kinds:
  ///  - PauseBreakpoint
  ///  - PauseInterrupted
  ///  - PauseException
  ///
  /// 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.
  @optional
  Frame topFrame;

  /// The exception associated with this event, if this is a PauseException
  /// event.
  @optional
  InstanceRef exception;

  /// An array of bytes, encoded as a base64 string.
  ///
  /// This is provided for the WriteEvent event.
  @optional
  String bytes;

  /// The argument passed to dart:developer.inspect.
  ///
  /// This is provided for the Inspect event.
  @optional
  InstanceRef inspectee;

  /// The RPC name of the extension that was added.
  ///
  /// This is provided for the ServiceExtensionAdded event.
  @optional
  String extensionRPC;

  /// The extension event kind.
  ///
  /// This is provided for the Extension event.
  @optional
  String extensionKind;

  /// The extension event data.
  ///
  /// This is provided for the Extension event.
  @optional
  ExtensionData extensionData;

  /// An array of TimelineEvents
  ///
  /// This is provided for the TimelineEvents event.
  @optional
  List<TimelineEvent> timelineEvents;

  /// Is the isolate paused at an await, yield, or yield* statement?
  ///
  /// This is provided for the event kinds:
  ///  - PauseBreakpoint
  ///  - PauseInterrupted
  @optional
  bool atAsyncSuspension;

  /// The status (success or failure) related to the event. This is provided for
  /// the event kinds:
  ///  - IsolateReloaded
  ///  - IsolateSpawn
  @optional
  String status;

  /// LogRecord data.
  ///
  /// This is provided for the Logging event.
  @optional
  LogRecord logRecord;

  /// The service identifier.
  ///
  /// This is provided for the event kinds:
  ///  - ServiceRegistered
  ///  - ServiceUnregistered
  @optional
  String service;

  /// The RPC method that should be used to invoke the service.
  ///
  /// This is provided for the event kinds:
  ///  - ServiceRegistered
  ///  - ServiceUnregistered
  @optional
  String method;

  /// The alias of the registered service.
  ///
  /// This is provided for the event kinds:
  ///  - ServiceRegistered
  @optional
  String alias;

  /// The name of the changed flag.
  ///
  /// This is provided for the event kinds:
  ///  - VMFlagUpdate
  @optional
  String flag;

  /// The new value of the changed flag.
  ///
  /// This is provided for the event kinds:
  ///  - VMFlagUpdate
  @optional
  String newValue;

  /// Specifies whether this event is the last of a group of events.
  ///
  /// This is provided for the event kinds:
  ///  - HeapSnapshot
  @optional
  bool last;

  /// Binary data associated with the event.
  ///
  /// This is provided for the event kinds:
  ///   - HeapSnapshot
  @optional
  ByteData data;

  Event({
    @required this.kind,
    @required this.timestamp,
    this.isolate,
    this.vm,
    this.breakpoint,
    this.pauseBreakpoints,
    this.topFrame,
    this.exception,
    this.bytes,
    this.inspectee,
    this.extensionRPC,
    this.extensionKind,
    this.extensionData,
    this.timelineEvents,
    this.atAsyncSuspension,
    this.status,
    this.logRecord,
    this.service,
    this.method,
    this.alias,
    this.flag,
    this.newValue,
    this.last,
    this.data,
  });
  Event._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    kind = json['kind'];
    isolate = createServiceObject(json['isolate'], const ['IsolateRef']);
    vm = createServiceObject(json['vm'], const ['VMRef']);
    timestamp = json['timestamp'];
    breakpoint = createServiceObject(json['breakpoint'], const ['Breakpoint']);
    pauseBreakpoints = json['pauseBreakpoints'] == null
        ? null
        : List<Breakpoint>.from(createServiceObject(
            json['pauseBreakpoints'], const ['Breakpoint']));
    topFrame = createServiceObject(json['topFrame'], const ['Frame']);
    exception = createServiceObject(json['exception'], const ['InstanceRef']);
    bytes = json['bytes'];
    inspectee = createServiceObject(json['inspectee'], const ['InstanceRef']);
    extensionRPC = json['extensionRPC'];
    extensionKind = json['extensionKind'];
    extensionData = ExtensionData.parse(json['extensionData']);
    timelineEvents = json['timelineEvents'] == null
        ? null
        : List<TimelineEvent>.from(createServiceObject(
            json['timelineEvents'], const ['TimelineEvent']));
    atAsyncSuspension = json['atAsyncSuspension'];
    status = json['status'];
    logRecord = createServiceObject(json['logRecord'], const ['LogRecord']);
    service = json['service'];
    method = json['method'];
    alias = json['alias'];
    flag = json['flag'];
    newValue = json['newValue'];
    last = json['last'];
    data = json['data'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'Event';
    json.addAll({
      'kind': kind,
      'timestamp': timestamp,
    });
    _setIfNotNull(json, 'isolate', isolate?.toJson());
    _setIfNotNull(json, 'vm', vm?.toJson());
    _setIfNotNull(json, 'breakpoint', breakpoint?.toJson());
    _setIfNotNull(json, 'pauseBreakpoints',
        pauseBreakpoints?.map((f) => f?.toJson())?.toList());
    _setIfNotNull(json, 'topFrame', topFrame?.toJson());
    _setIfNotNull(json, 'exception', exception?.toJson());
    _setIfNotNull(json, 'bytes', bytes);
    _setIfNotNull(json, 'inspectee', inspectee?.toJson());
    _setIfNotNull(json, 'extensionRPC', extensionRPC);
    _setIfNotNull(json, 'extensionKind', extensionKind);
    _setIfNotNull(json, 'extensionData', extensionData?.data);
    _setIfNotNull(json, 'timelineEvents',
        timelineEvents?.map((f) => f?.toJson())?.toList());
    _setIfNotNull(json, 'atAsyncSuspension', atAsyncSuspension);
    _setIfNotNull(json, 'status', status);
    _setIfNotNull(json, 'logRecord', logRecord?.toJson());
    _setIfNotNull(json, 'service', service);
    _setIfNotNull(json, 'method', method);
    _setIfNotNull(json, 'alias', alias);
    _setIfNotNull(json, 'flag', flag);
    _setIfNotNull(json, 'newValue', newValue);
    _setIfNotNull(json, 'last', last);
    _setIfNotNull(json, 'data', data);
    return json;
  }

  String toString() =>
      '[Event type: ${type}, kind: ${kind}, timestamp: ${timestamp}]';
}

/// An `FieldRef` is a reference to a `Field`.
class FieldRef extends ObjRef {
  static FieldRef parse(Map<String, dynamic> json) =>
      json == null ? null : FieldRef._fromJson(json);

  /// The name of this field.
  String name;

  /// The owner of this field, which can be either a Library or a Class.
  ObjRef owner;

  /// The declared type of this field.
  ///
  /// The value will always be of one of the kinds: Type, TypeRef,
  /// TypeParameter, BoundedType.
  InstanceRef declaredType;

  /// Is this field const?
  bool isConst;

  /// Is this field final?
  bool isFinal;

  /// Is this field static?
  bool isStatic;

  FieldRef({
    @required this.name,
    @required this.owner,
    @required this.declaredType,
    @required this.isConst,
    @required this.isFinal,
    @required this.isStatic,
  });
  FieldRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    name = json['name'];
    owner = createServiceObject(json['owner'], const ['ObjRef']);
    declaredType =
        createServiceObject(json['declaredType'], const ['InstanceRef']);
    isConst = json['const'];
    isFinal = json['final'];
    isStatic = json['static'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = super.toJson();
    json['type'] = '@Field';
    json.addAll({
      'name': name,
      'owner': owner.toJson(),
      'declaredType': declaredType.toJson(),
      'const': isConst,
      'final': isFinal,
      'static': isStatic,
    });
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is FieldRef && id == other.id;

  String toString() => '[FieldRef]';
}

/// A `Field` provides information about a Dart language field or variable.
class Field extends Obj {
  static Field parse(Map<String, dynamic> json) =>
      json == null ? null : Field._fromJson(json);

  /// The name of this field.
  String name;

  /// The owner of this field, which can be either a Library or a Class.
  ObjRef owner;

  /// The declared type of this field.
  ///
  /// The value will always be of one of the kinds: Type, TypeRef,
  /// TypeParameter, BoundedType.
  InstanceRef declaredType;

  /// Is this field const?
  bool isConst;

  /// Is this field final?
  bool isFinal;

  /// Is this field static?
  bool isStatic;

  /// The value of this field, if the field is static.
  @optional
  InstanceRef staticValue;

  /// The location of this field in the source code.
  @optional
  SourceLocation location;

  Field({
    @required this.name,
    @required this.owner,
    @required this.declaredType,
    @required this.isConst,
    @required this.isFinal,
    @required this.isStatic,
    this.staticValue,
    this.location,
  });
  Field._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    name = json['name'];
    owner = createServiceObject(json['owner'], const ['ObjRef']);
    declaredType =
        createServiceObject(json['declaredType'], const ['InstanceRef']);
    isConst = json['const'];
    isFinal = json['final'];
    isStatic = json['static'];
    staticValue =
        createServiceObject(json['staticValue'], const ['InstanceRef']);
    location = createServiceObject(json['location'], const ['SourceLocation']);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = super.toJson();
    json['type'] = 'Field';
    json.addAll({
      'name': name,
      'owner': owner.toJson(),
      'declaredType': declaredType.toJson(),
      'const': isConst,
      'final': isFinal,
      'static': isStatic,
    });
    _setIfNotNull(json, 'staticValue', staticValue?.toJson());
    _setIfNotNull(json, 'location', location?.toJson());
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is Field && id == other.id;

  String toString() => '[Field]';
}

/// A `Flag` represents a single VM command line flag.
class Flag {
  static Flag parse(Map<String, dynamic> json) =>
      json == null ? null : Flag._fromJson(json);

  /// The name of the flag.
  String name;

  /// A description of the flag.
  String comment;

  /// Has this flag been modified from its default setting?
  bool modified;

  /// The value of this flag as a string.
  ///
  /// If this property is absent, then the value of the flag was NULL.
  @optional
  String valueAsString;

  Flag({
    @required this.name,
    @required this.comment,
    @required this.modified,
    this.valueAsString,
  });
  Flag._fromJson(Map<String, dynamic> json) {
    name = json['name'];
    comment = json['comment'];
    modified = json['modified'];
    valueAsString = json['valueAsString'];
  }

  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json.addAll({
      'name': name,
      'comment': comment,
      'modified': modified,
    });
    _setIfNotNull(json, 'valueAsString', valueAsString);
    return json;
  }

  String toString() =>
      '[Flag name: ${name}, comment: ${comment}, modified: ${modified}]';
}

/// A `FlagList` represents the complete set of VM command line flags.
class FlagList extends Response {
  static FlagList parse(Map<String, dynamic> json) =>
      json == null ? null : FlagList._fromJson(json);

  /// A list of all flags in the VM.
  List<Flag> flags;

  FlagList({
    @required this.flags,
  });
  FlagList._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    flags = List<Flag>.from(
        createServiceObject(json['flags'], const ['Flag']) ?? []);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'FlagList';
    json.addAll({
      'flags': flags.map((f) => f.toJson()).toList(),
    });
    return json;
  }

  String toString() => '[FlagList type: ${type}, flags: ${flags}]';
}

class Frame extends Response {
  static Frame parse(Map<String, dynamic> json) =>
      json == null ? null : Frame._fromJson(json);

  int index;

  @optional
  FuncRef function;

  @optional
  CodeRef code;

  @optional
  SourceLocation location;

  @optional
  List<BoundVariable> vars;

  @optional
  /*FrameKind*/
  String kind;

  Frame({
    @required this.index,
    this.function,
    this.code,
    this.location,
    this.vars,
    this.kind,
  });
  Frame._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    index = json['index'];
    function = createServiceObject(json['function'], const ['FuncRef']);
    code = createServiceObject(json['code'], const ['CodeRef']);
    location = createServiceObject(json['location'], const ['SourceLocation']);
    vars = json['vars'] == null
        ? null
        : List<BoundVariable>.from(
            createServiceObject(json['vars'], const ['BoundVariable']));
    kind = json['kind'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'Frame';
    json.addAll({
      'index': index,
    });
    _setIfNotNull(json, 'function', function?.toJson());
    _setIfNotNull(json, 'code', code?.toJson());
    _setIfNotNull(json, 'location', location?.toJson());
    _setIfNotNull(json, 'vars', vars?.map((f) => f?.toJson())?.toList());
    _setIfNotNull(json, 'kind', kind);
    return json;
  }

  String toString() => '[Frame type: ${type}, index: ${index}]';
}

/// An `FuncRef` is a reference to a `Func`.
class FuncRef extends ObjRef {
  static FuncRef parse(Map<String, dynamic> json) =>
      json == null ? null : FuncRef._fromJson(json);

  /// The name of this function.
  String name;

  /// The owner of this function, which can be a Library, Class, or a Function.
  ///
  /// [owner] can be one of [LibraryRef], [ClassRef] or [FuncRef].
  dynamic owner;

  /// Is this function static?
  bool isStatic;

  /// Is this function const?
  bool isConst;

  FuncRef({
    @required this.name,
    @required this.owner,
    @required this.isStatic,
    @required this.isConst,
  });
  FuncRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    name = json['name'];
    owner = createServiceObject(
        json['owner'], const ['LibraryRef', 'ClassRef', 'FuncRef']);
    isStatic = json['static'];
    isConst = json['const'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = super.toJson();
    json['type'] = '@Function';
    json.addAll({
      'name': name,
      'owner': owner.toJson(),
      'static': isStatic,
      'const': isConst,
    });
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is FuncRef && id == other.id;

  String toString() => '[FuncRef ' //
      'type: ${type}, id: ${id}, name: ${name}, owner: ${owner}, ' //
      'isStatic: ${isStatic}, isConst: ${isConst}]';
}

/// A `Func` represents a Dart language function.
class Func extends Obj {
  static Func parse(Map<String, dynamic> json) =>
      json == null ? null : Func._fromJson(json);

  /// The name of this function.
  String name;

  /// The owner of this function, which can be a Library, Class, or a Function.
  ///
  /// [owner] can be one of [LibraryRef], [ClassRef] or [FuncRef].
  dynamic owner;

  /// The location of this function in the source code.
  @optional
  SourceLocation location;

  /// The compiled code associated with this function.
  @optional
  CodeRef code;

  Func({
    @required this.name,
    @required this.owner,
    this.location,
    this.code,
  });
  Func._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    name = json['name'];
    owner = createServiceObject(
        json['owner'], const ['LibraryRef', 'ClassRef', 'FuncRef']);
    location = createServiceObject(json['location'], const ['SourceLocation']);
    code = createServiceObject(json['code'], const ['CodeRef']);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = super.toJson();
    json['type'] = 'Function';
    json.addAll({
      'name': name,
      'owner': owner.toJson(),
    });
    _setIfNotNull(json, 'location', location?.toJson());
    _setIfNotNull(json, 'code', code?.toJson());
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is Func && id == other.id;

  String toString() =>
      '[Func type: ${type}, id: ${id}, name: ${name}, owner: ${owner}]';
}

/// `InstanceRef` is a reference to an `Instance`.
class InstanceRef extends ObjRef {
  static InstanceRef parse(Map<String, dynamic> json) =>
      json == null ? null : InstanceRef._fromJson(json);

  /// What kind of instance is this?
  /*InstanceKind*/ String kind;

  /// Instance references always include their class.
  ClassRef classRef;

  /// The value of this instance as a string.
  ///
  /// Provided for the instance kinds:
  ///  - Null (null)
  ///  - Bool (true or false)
  ///  - Double (suitable for passing to Double.parse())
  ///  - Int (suitable for passing to int.parse())
  ///  - String (value may be truncated)
  ///  - Float32x4
  ///  - Float64x2
  ///  - Int32x4
  ///  - StackTrace
  @optional
  String valueAsString;

  /// The valueAsString for String references may be truncated. If so, this
  /// property is added with the value 'true'.
  ///
  /// New code should use 'length' and 'count' instead.
  @optional
  bool valueAsStringIsTruncated;

  /// The length of a List or the number of associations in a Map or the number
  /// of codeunits in a String.
  ///
  /// Provided for instance kinds:
  ///  - String
  ///  - List
  ///  - Map
  ///  - Uint8ClampedList
  ///  - Uint8List
  ///  - Uint16List
  ///  - Uint32List
  ///  - Uint64List
  ///  - Int8List
  ///  - Int16List
  ///  - Int32List
  ///  - Int64List
  ///  - Float32List
  ///  - Float64List
  ///  - Int32x4List
  ///  - Float32x4List
  ///  - Float64x2List
  @optional
  int length;

  /// The name of a Type instance.
  ///
  /// Provided for instance kinds:
  ///  - Type
  @optional
  String name;

  /// The corresponding Class if this Type has a resolved typeClass.
  ///
  /// Provided for instance kinds:
  ///  - Type
  @optional
  ClassRef typeClass;

  /// The parameterized class of a type parameter:
  ///
  /// Provided for instance kinds:
  ///  - TypeParameter
  @optional
  ClassRef parameterizedClass;

  /// The pattern of a RegExp instance.
  ///
  /// The pattern is always an instance of kind String.
  ///
  /// Provided for instance kinds:
  ///  - RegExp
  @optional
  InstanceRef pattern;

  /// The function associated with a Closure instance.
  ///
  /// Provided for instance kinds:
  ///  - Closure
  @optional
  FuncRef closureFunction;

  /// The context associated with a Closure instance.
  ///
  /// Provided for instance kinds:
  ///  - Closure
  @optional
  ContextRef closureContext;

  InstanceRef({
    @required this.kind,
    @required this.classRef,
    this.valueAsString,
    this.valueAsStringIsTruncated,
    this.length,
    this.name,
    this.typeClass,
    this.parameterizedClass,
    this.pattern,
    this.closureFunction,
    this.closureContext,
  });
  InstanceRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    kind = json['kind'];
    classRef = createServiceObject(json['class'], const ['ClassRef']);
    valueAsString = json['valueAsString'];
    valueAsStringIsTruncated = json['valueAsStringIsTruncated'] ?? false;
    length = json['length'];
    name = json['name'];
    typeClass = createServiceObject(json['typeClass'], const ['ClassRef']);
    parameterizedClass =
        createServiceObject(json['parameterizedClass'], const ['ClassRef']);
    pattern = createServiceObject(json['pattern'], const ['InstanceRef']);
    closureFunction =
        createServiceObject(json['closureFunction'], const ['FuncRef']);
    closureContext =
        createServiceObject(json['closureContext'], const ['ContextRef']);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = super.toJson();
    json['type'] = '@Instance';
    json.addAll({
      'kind': kind,
      'class': classRef.toJson(),
    });
    _setIfNotNull(json, 'valueAsString', valueAsString);
    _setIfNotNull(
        json, 'valueAsStringIsTruncated', valueAsStringIsTruncated ?? false);
    _setIfNotNull(json, 'length', length);
    _setIfNotNull(json, 'name', name);
    _setIfNotNull(json, 'typeClass', typeClass?.toJson());
    _setIfNotNull(json, 'parameterizedClass', parameterizedClass?.toJson());
    _setIfNotNull(json, 'pattern', pattern?.toJson());
    _setIfNotNull(json, 'closureFunction', closureFunction?.toJson());
    _setIfNotNull(json, 'closureContext', closureContext?.toJson());
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is InstanceRef && id == other.id;

  String toString() => '[InstanceRef ' //
      'type: ${type}, id: ${id}, kind: ${kind}, classRef: ${classRef}]';
}

/// An `Instance` represents an instance of the Dart language class `Obj`.
class Instance extends Obj {
  static Instance parse(Map<String, dynamic> json) =>
      json == null ? null : Instance._fromJson(json);

  /// What kind of instance is this?
  /*InstanceKind*/ String kind;

  /// Instance references always include their class.
  @override
  ClassRef classRef;

  /// The value of this instance as a string.
  ///
  /// Provided for the instance kinds:
  ///  - Bool (true or false)
  ///  - Double (suitable for passing to Double.parse())
  ///  - Int (suitable for passing to int.parse())
  ///  - String (value may be truncated)
  @optional
  String valueAsString;

  /// The valueAsString for String references may be truncated. If so, this
  /// property is added with the value 'true'.
  ///
  /// New code should use 'length' and 'count' instead.
  @optional
  bool valueAsStringIsTruncated;

  /// The length of a List or the number of associations in a Map or the number
  /// of codeunits in a String.
  ///
  /// Provided for instance kinds:
  ///  - String
  ///  - List
  ///  - Map
  ///  - Uint8ClampedList
  ///  - Uint8List
  ///  - Uint16List
  ///  - Uint32List
  ///  - Uint64List
  ///  - Int8List
  ///  - Int16List
  ///  - Int32List
  ///  - Int64List
  ///  - Float32List
  ///  - Float64List
  ///  - Int32x4List
  ///  - Float32x4List
  ///  - Float64x2List
  @optional
  int length;

  /// The index of the first element or association or codeunit returned. This
  /// is only provided when it is non-zero.
  ///
  /// Provided for instance kinds:
  ///  - String
  ///  - List
  ///  - Map
  ///  - Uint8ClampedList
  ///  - Uint8List
  ///  - Uint16List
  ///  - Uint32List
  ///  - Uint64List
  ///  - Int8List
  ///  - Int16List
  ///  - Int32List
  ///  - Int64List
  ///  - Float32List
  ///  - Float64List
  ///  - Int32x4List
  ///  - Float32x4List
  ///  - Float64x2List
  @optional
  int offset;

  /// The number of elements or associations or codeunits returned. This is only
  /// provided when it is less than length.
  ///
  /// Provided for instance kinds:
  ///  - String
  ///  - List
  ///  - Map
  ///  - Uint8ClampedList
  ///  - Uint8List
  ///  - Uint16List
  ///  - Uint32List
  ///  - Uint64List
  ///  - Int8List
  ///  - Int16List
  ///  - Int32List
  ///  - Int64List
  ///  - Float32List
  ///  - Float64List
  ///  - Int32x4List
  ///  - Float32x4List
  ///  - Float64x2List
  @optional
  int count;

  /// The name of a Type instance.
  ///
  /// Provided for instance kinds:
  ///  - Type
  @optional
  String name;

  /// The corresponding Class if this Type is canonical.
  ///
  /// Provided for instance kinds:
  ///  - Type
  @optional
  ClassRef typeClass;

  /// The parameterized class of a type parameter:
  ///
  /// Provided for instance kinds:
  ///  - TypeParameter
  @optional
  ClassRef parameterizedClass;

  /// The fields of this Instance.
  @optional
  List<BoundField> fields;

  /// The elements of a List instance.
  ///
  /// Provided for instance kinds:
  ///  - List
  @optional
  List<dynamic> elements;

  /// The elements of a Map instance.
  ///
  /// Provided for instance kinds:
  ///  - Map
  @optional
  List<MapAssociation> associations;

  /// The bytes of a TypedData instance.
  ///
  /// The data is provided as a Base64 encoded string.
  ///
  /// Provided for instance kinds:
  ///  - Uint8ClampedList
  ///  - Uint8List
  ///  - Uint16List
  ///  - Uint32List
  ///  - Uint64List
  ///  - Int8List
  ///  - Int16List
  ///  - Int32List
  ///  - Int64List
  ///  - Float32List
  ///  - Float64List
  ///  - Int32x4List
  ///  - Float32x4List
  ///  - Float64x2List
  @optional
  String bytes;

  /// The referent of a MirrorReference instance.
  ///
  /// Provided for instance kinds:
  ///  - MirrorReference
  @optional
  InstanceRef mirrorReferent;

  /// The pattern of a RegExp instance.
  ///
  /// Provided for instance kinds:
  ///  - RegExp
  @optional
  String pattern;

  /// Whether this regular expression is case sensitive.
  ///
  /// Provided for instance kinds:
  ///  - RegExp
  @optional
  bool isCaseSensitive;

  /// Whether this regular expression matches multiple lines.
  ///
  /// Provided for instance kinds:
  ///  - RegExp
  @optional
  bool isMultiLine;

  /// The key for a WeakProperty instance.
  ///
  /// Provided for instance kinds:
  ///  - WeakProperty
  @optional
  InstanceRef propertyKey;

  /// The key for a WeakProperty instance.
  ///
  /// Provided for instance kinds:
  ///  - WeakProperty
  @optional
  InstanceRef propertyValue;

  /// The type arguments for this type.
  ///
  /// Provided for instance kinds:
  ///  - Type
  @optional
  TypeArgumentsRef typeArguments;

  /// The index of a TypeParameter instance.
  ///
  /// Provided for instance kinds:
  ///  - TypeParameter
  @optional
  int parameterIndex;

  /// The type bounded by a BoundedType instance - or - the referent of a
  /// TypeRef instance.
  ///
  /// The value will always be of one of the kinds: Type, TypeRef,
  /// TypeParameter, BoundedType.
  ///
  /// Provided for instance kinds:
  ///  - BoundedType
  ///  - TypeRef
  @optional
  InstanceRef targetType;

  /// The bound of a TypeParameter or BoundedType.
  ///
  /// The value will always be of one of the kinds: Type, TypeRef,
  /// TypeParameter, BoundedType.
  ///
  /// Provided for instance kinds:
  ///  - BoundedType
  ///  - TypeParameter
  @optional
  InstanceRef bound;

  Instance({
    @required this.kind,
    @required this.classRef,
    this.valueAsString,
    this.valueAsStringIsTruncated,
    this.length,
    this.offset,
    this.count,
    this.name,
    this.typeClass,
    this.parameterizedClass,
    this.fields,
    this.elements,
    this.associations,
    this.bytes,
    this.mirrorReferent,
    this.pattern,
    this.isCaseSensitive,
    this.isMultiLine,
    this.propertyKey,
    this.propertyValue,
    this.typeArguments,
    this.parameterIndex,
    this.targetType,
    this.bound,
  });
  Instance._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    kind = json['kind'];
    classRef = createServiceObject(json['class'], const ['ClassRef']);
    valueAsString = json['valueAsString'];
    valueAsStringIsTruncated = json['valueAsStringIsTruncated'] ?? false;
    length = json['length'];
    offset = json['offset'];
    count = json['count'];
    name = json['name'];
    typeClass = createServiceObject(json['typeClass'], const ['ClassRef']);
    parameterizedClass =
        createServiceObject(json['parameterizedClass'], const ['ClassRef']);
    fields = json['fields'] == null
        ? null
        : List<BoundField>.from(
            createServiceObject(json['fields'], const ['BoundField']));
    elements = json['elements'] == null
        ? null
        : List<dynamic>.from(
            createServiceObject(json['elements'], const ['dynamic']));
    associations = json['associations'] == null
        ? null
        : List<MapAssociation>.from(
            _createSpecificObject(json['associations'], MapAssociation.parse));
    bytes = json['bytes'];
    mirrorReferent =
        createServiceObject(json['mirrorReferent'], const ['InstanceRef']);
    pattern = json['pattern'];
    isCaseSensitive = json['isCaseSensitive'];
    isMultiLine = json['isMultiLine'];
    propertyKey =
        createServiceObject(json['propertyKey'], const ['InstanceRef']);
    propertyValue =
        createServiceObject(json['propertyValue'], const ['InstanceRef']);
    typeArguments =
        createServiceObject(json['typeArguments'], const ['TypeArgumentsRef']);
    parameterIndex = json['parameterIndex'];
    targetType = createServiceObject(json['targetType'], const ['InstanceRef']);
    bound = createServiceObject(json['bound'], const ['InstanceRef']);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = super.toJson();
    json['type'] = 'Instance';
    json.addAll({
      'kind': kind,
      'class': classRef.toJson(),
    });
    _setIfNotNull(json, 'valueAsString', valueAsString);
    _setIfNotNull(
        json, 'valueAsStringIsTruncated', valueAsStringIsTruncated ?? false);
    _setIfNotNull(json, 'length', length);
    _setIfNotNull(json, 'offset', offset);
    _setIfNotNull(json, 'count', count);
    _setIfNotNull(json, 'name', name);
    _setIfNotNull(json, 'typeClass', typeClass?.toJson());
    _setIfNotNull(json, 'parameterizedClass', parameterizedClass?.toJson());
    _setIfNotNull(json, 'fields', fields?.map((f) => f?.toJson())?.toList());
    _setIfNotNull(
        json, 'elements', elements?.map((f) => f?.toJson())?.toList());
    _setIfNotNull(
        json, 'associations', associations?.map((f) => f?.toJson())?.toList());
    _setIfNotNull(json, 'bytes', bytes);
    _setIfNotNull(json, 'mirrorReferent', mirrorReferent?.toJson());
    _setIfNotNull(json, 'pattern', pattern);
    _setIfNotNull(json, 'isCaseSensitive', isCaseSensitive);
    _setIfNotNull(json, 'isMultiLine', isMultiLine);
    _setIfNotNull(json, 'propertyKey', propertyKey?.toJson());
    _setIfNotNull(json, 'propertyValue', propertyValue?.toJson());
    _setIfNotNull(json, 'typeArguments', typeArguments?.toJson());
    _setIfNotNull(json, 'parameterIndex', parameterIndex);
    _setIfNotNull(json, 'targetType', targetType?.toJson());
    _setIfNotNull(json, 'bound', bound?.toJson());
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is Instance && id == other.id;

  String toString() => '[Instance ' //
      'type: ${type}, id: ${id}, kind: ${kind}, classRef: ${classRef}]';
}

/// `IsolateRef` is a reference to an `Isolate` object.
class IsolateRef extends Response {
  static IsolateRef parse(Map<String, dynamic> json) =>
      json == null ? null : IsolateRef._fromJson(json);

  /// The id which is passed to the getIsolate RPC to load this isolate.
  String id;

  /// A numeric id for this isolate, represented as a string. Unique.
  String number;

  /// A name identifying this isolate. Not guaranteed to be unique.
  String name;

  IsolateRef({
    @required this.id,
    @required this.number,
    @required this.name,
  });
  IsolateRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    id = json['id'];
    number = json['number'];
    name = json['name'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = '@Isolate';
    json.addAll({
      'id': id,
      'number': number,
      'name': name,
    });
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is IsolateRef && id == other.id;

  String toString() =>
      '[IsolateRef type: ${type}, id: ${id}, number: ${number}, name: ${name}]';
}

/// An `Isolate` object provides information about one isolate in the VM.
class Isolate extends Response {
  static Isolate parse(Map<String, dynamic> json) =>
      json == null ? null : Isolate._fromJson(json);

  /// The id which is passed to the getIsolate RPC to reload this isolate.
  String id;

  /// A numeric id for this isolate, represented as a string. Unique.
  String number;

  /// A name identifying this isolate. Not guaranteed to be unique.
  String name;

  /// The time that the VM started in milliseconds since the epoch.
  ///
  /// Suitable to pass to DateTime.fromMillisecondsSinceEpoch.
  int startTime;

  /// Is the isolate in a runnable state?
  bool runnable;

  /// The number of live ports for this isolate.
  int livePorts;

  /// Will this isolate pause when exiting?
  bool pauseOnExit;

  /// The last pause event delivered to the isolate. If the isolate is running,
  /// this will be a resume event.
  Event pauseEvent;

  /// The root library for this isolate.
  ///
  /// Guaranteed to be initialized when the IsolateRunnable event fires.
  @optional
  LibraryRef rootLib;

  /// A list of all libraries for this isolate.
  ///
  /// Guaranteed to be initialized when the IsolateRunnable event fires.
  List<LibraryRef> libraries;

  /// A list of all breakpoints for this isolate.
  List<Breakpoint> breakpoints;

  /// The error that is causing this isolate to exit, if applicable.
  @optional
  Error error;

  /// The current pause on exception mode for this isolate.
  /*ExceptionPauseMode*/ String exceptionPauseMode;

  /// The list of service extension RPCs that are registered for this isolate,
  /// if any.
  @optional
  List<String> extensionRPCs;

  Isolate({
    @required this.id,
    @required this.number,
    @required this.name,
    @required this.startTime,
    @required this.runnable,
    @required this.livePorts,
    @required this.pauseOnExit,
    @required this.pauseEvent,
    @required this.libraries,
    @required this.breakpoints,
    @required this.exceptionPauseMode,
    this.rootLib,
    this.error,
    this.extensionRPCs,
  });
  Isolate._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    id = json['id'];
    number = json['number'];
    name = json['name'];
    startTime = json['startTime'];
    runnable = json['runnable'];
    livePorts = json['livePorts'];
    pauseOnExit = json['pauseOnExit'];
    pauseEvent = createServiceObject(json['pauseEvent'], const ['Event']);
    rootLib = createServiceObject(json['rootLib'], const ['LibraryRef']);
    libraries = List<LibraryRef>.from(
        createServiceObject(json['libraries'], const ['LibraryRef']) ?? []);
    breakpoints = List<Breakpoint>.from(
        createServiceObject(json['breakpoints'], const ['Breakpoint']) ?? []);
    error = createServiceObject(json['error'], const ['Error']);
    exceptionPauseMode = json['exceptionPauseMode'];
    extensionRPCs = json['extensionRPCs'] == null
        ? null
        : List<String>.from(json['extensionRPCs']);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'Isolate';
    json.addAll({
      'id': id,
      'number': number,
      'name': name,
      'startTime': startTime,
      'runnable': runnable,
      'livePorts': livePorts,
      'pauseOnExit': pauseOnExit,
      'pauseEvent': pauseEvent.toJson(),
      'libraries': libraries.map((f) => f.toJson()).toList(),
      'breakpoints': breakpoints.map((f) => f.toJson()).toList(),
      'exceptionPauseMode': exceptionPauseMode,
    });
    _setIfNotNull(json, 'rootLib', rootLib?.toJson());
    _setIfNotNull(json, 'error', error?.toJson());
    _setIfNotNull(
        json, 'extensionRPCs', extensionRPCs?.map((f) => f)?.toList());
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is Isolate && id == other.id;

  String toString() => '[Isolate]';
}

/// `IsolateGroupRef` is a reference to an `IsolateGroup` object.
class IsolateGroupRef extends Response {
  static IsolateGroupRef parse(Map<String, dynamic> json) =>
      json == null ? null : IsolateGroupRef._fromJson(json);

  /// The id which is passed to the getIsolateGroup RPC to load this isolate
  /// group.
  String id;

  /// A numeric id for this isolate group, represented as a string. Unique.
  String number;

  /// A name identifying this isolate group. Not guaranteed to be unique.
  String name;

  IsolateGroupRef({
    @required this.id,
    @required this.number,
    @required this.name,
  });
  IsolateGroupRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    id = json['id'];
    number = json['number'];
    name = json['name'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = '@IsolateGroup';
    json.addAll({
      'id': id,
      'number': number,
      'name': name,
    });
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is IsolateGroupRef && id == other.id;

  String toString() =>
      '[IsolateGroupRef type: ${type}, id: ${id}, number: ${number}, name: ${name}]';
}

/// An `Isolate` object provides information about one isolate in the VM.
class IsolateGroup extends Response {
  static IsolateGroup parse(Map<String, dynamic> json) =>
      json == null ? null : IsolateGroup._fromJson(json);

  /// The id which is passed to the getIsolate RPC to reload this isolate.
  String id;

  /// A numeric id for this isolate, represented as a string. Unique.
  String number;

  /// A name identifying this isolate. Not guaranteed to be unique.
  String name;

  /// A list of all isolates in this isolate group.
  List<IsolateRef> isolates;

  IsolateGroup({
    @required this.id,
    @required this.number,
    @required this.name,
    @required this.isolates,
  });
  IsolateGroup._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    id = json['id'];
    number = json['number'];
    name = json['name'];
    isolates = List<IsolateRef>.from(
        createServiceObject(json['isolates'], const ['IsolateRef']) ?? []);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'IsolateGroup';
    json.addAll({
      'id': id,
      'number': number,
      'name': name,
      'isolates': isolates.map((f) => f.toJson()).toList(),
    });
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is IsolateGroup && id == other.id;

  String toString() => '[IsolateGroup ' //
      'type: ${type}, id: ${id}, number: ${number}, name: ${name}, ' //
      'isolates: ${isolates}]';
}

/// See [getInboundReferences].
class InboundReferences extends Response {
  static InboundReferences parse(Map<String, dynamic> json) =>
      json == null ? null : InboundReferences._fromJson(json);

  /// An array of inbound references to an object.
  List<InboundReference> references;

  InboundReferences({
    @required this.references,
  });
  InboundReferences._fromJson(Map<String, dynamic> json)
      : super._fromJson(json) {
    references = List<InboundReference>.from(
        createServiceObject(json['references'], const ['InboundReference']) ??
            []);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'InboundReferences';
    json.addAll({
      'references': references.map((f) => f.toJson()).toList(),
    });
    return json;
  }

  String toString() =>
      '[InboundReferences type: ${type}, references: ${references}]';
}

/// See [getInboundReferences].
class InboundReference {
  static InboundReference parse(Map<String, dynamic> json) =>
      json == null ? null : InboundReference._fromJson(json);

  /// The object holding the inbound reference.
  ObjRef source;

  /// If source is a List, parentListIndex is the index of the inbound
  /// reference.
  @optional
  int parentListIndex;

  /// If source is a field of an object, parentField is the field containing the
  /// inbound reference.
  @optional
  FieldRef parentField;

  InboundReference({
    @required this.source,
    this.parentListIndex,
    this.parentField,
  });
  InboundReference._fromJson(Map<String, dynamic> json) {
    source = createServiceObject(json['source'], const ['ObjRef']);
    parentListIndex = json['parentListIndex'];
    parentField = createServiceObject(json['parentField'], const ['FieldRef']);
  }

  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json.addAll({
      'source': source.toJson(),
    });
    _setIfNotNull(json, 'parentListIndex', parentListIndex);
    _setIfNotNull(json, 'parentField', parentField?.toJson());
    return json;
  }

  String toString() => '[InboundReference source: ${source}]';
}

/// See [getInstances].
class InstanceSet extends Response {
  static InstanceSet parse(Map<String, dynamic> json) =>
      json == null ? null : InstanceSet._fromJson(json);

  /// The number of instances of the requested type currently allocated.
  int totalCount;

  /// An array of instances of the requested type.
  List<ObjRef> instances;

  InstanceSet({
    @required this.totalCount,
    @required this.instances,
  });
  InstanceSet._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    totalCount = json['totalCount'];
    instances = List<ObjRef>.from(createServiceObject(
        json['instances'] ?? json['samples'], const ['ObjRef']));
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'InstanceSet';
    json.addAll({
      'totalCount': totalCount,
      'instances': instances.map((f) => f.toJson()).toList(),
    });
    return json;
  }

  String toString() => '[InstanceSet ' //
      'type: ${type}, totalCount: ${totalCount}, instances: ${instances}]';
}

/// `LibraryRef` is a reference to a `Library`.
class LibraryRef extends ObjRef {
  static LibraryRef parse(Map<String, dynamic> json) =>
      json == null ? null : LibraryRef._fromJson(json);

  /// The name of this library.
  String name;

  /// The uri of this library.
  String uri;

  LibraryRef({
    @required this.name,
    @required this.uri,
  });
  LibraryRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    name = json['name'];
    uri = json['uri'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = super.toJson();
    json['type'] = '@Library';
    json.addAll({
      'name': name,
      'uri': uri,
    });
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is LibraryRef && id == other.id;

  String toString() =>
      '[LibraryRef type: ${type}, id: ${id}, name: ${name}, uri: ${uri}]';
}

/// A `Library` provides information about a Dart language library.
///
/// See [setLibraryDebuggable].
class Library extends Obj {
  static Library parse(Map<String, dynamic> json) =>
      json == null ? null : Library._fromJson(json);

  /// The name of this library.
  String name;

  /// The uri of this library.
  String uri;

  /// Is this library debuggable? Default true.
  bool debuggable;

  /// A list of the imports for this library.
  List<LibraryDependency> dependencies;

  /// A list of the scripts which constitute this library.
  List<ScriptRef> scripts;

  /// A list of the top-level variables in this library.
  List<FieldRef> variables;

  /// A list of the top-level functions in this library.
  List<FuncRef> functions;

  /// A list of all classes in this library.
  List<ClassRef> classes;

  Library({
    @required this.name,
    @required this.uri,
    @required this.debuggable,
    @required this.dependencies,
    @required this.scripts,
    @required this.variables,
    @required this.functions,
    @required this.classes,
  });
  Library._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    name = json['name'];
    uri = json['uri'];
    debuggable = json['debuggable'];
    dependencies = List<LibraryDependency>.from(
        _createSpecificObject(json['dependencies'], LibraryDependency.parse));
    scripts = List<ScriptRef>.from(
        createServiceObject(json['scripts'], const ['ScriptRef']) ?? []);
    variables = List<FieldRef>.from(
        createServiceObject(json['variables'], const ['FieldRef']) ?? []);
    functions = List<FuncRef>.from(
        createServiceObject(json['functions'], const ['FuncRef']) ?? []);
    classes = List<ClassRef>.from(
        createServiceObject(json['classes'], const ['ClassRef']) ?? []);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = super.toJson();
    json['type'] = 'Library';
    json.addAll({
      'name': name,
      'uri': uri,
      'debuggable': debuggable,
      'dependencies': dependencies.map((f) => f.toJson()).toList(),
      'scripts': scripts.map((f) => f.toJson()).toList(),
      'variables': variables.map((f) => f.toJson()).toList(),
      'functions': functions.map((f) => f.toJson()).toList(),
      'classes': classes.map((f) => f.toJson()).toList(),
    });
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is Library && id == other.id;

  String toString() => '[Library]';
}

/// A `LibraryDependency` provides information about an import or export.
class LibraryDependency {
  static LibraryDependency parse(Map<String, dynamic> json) =>
      json == null ? null : LibraryDependency._fromJson(json);

  /// Is this dependency an import (rather than an export)?
  bool isImport;

  /// Is this dependency deferred?
  bool isDeferred;

  /// The prefix of an 'as' import, or null.
  String prefix;

  /// The library being imported or exported.
  LibraryRef target;

  LibraryDependency({
    @required this.isImport,
    @required this.isDeferred,
    @required this.prefix,
    @required this.target,
  });
  LibraryDependency._fromJson(Map<String, dynamic> json) {
    isImport = json['isImport'];
    isDeferred = json['isDeferred'];
    prefix = json['prefix'];
    target = createServiceObject(json['target'], const ['LibraryRef']);
  }

  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json.addAll({
      'isImport': isImport,
      'isDeferred': isDeferred,
      'prefix': prefix,
      'target': target.toJson(),
    });
    return json;
  }

  String toString() => '[LibraryDependency ' //
      'isImport: ${isImport}, isDeferred: ${isDeferred}, prefix: ${prefix}, ' //
      'target: ${target}]';
}

class LogRecord extends Response {
  static LogRecord parse(Map<String, dynamic> json) =>
      json == null ? null : LogRecord._fromJson(json);

  /// The log message.
  InstanceRef message;

  /// The timestamp.
  int time;

  /// The severity level (a value between 0 and 2000).
  ///
  /// See the package:logging `Level` class for an overview of the possible
  /// values.
  int level;

  /// A monotonically increasing sequence number.
  int sequenceNumber;

  /// The name of the source of the log message.
  InstanceRef loggerName;

  /// The zone where the log was emitted.
  InstanceRef zone;

  /// An error object associated with this log event.
  InstanceRef error;

  /// A stack trace associated with this log event.
  InstanceRef stackTrace;

  LogRecord({
    @required this.message,
    @required this.time,
    @required this.level,
    @required this.sequenceNumber,
    @required this.loggerName,
    @required this.zone,
    @required this.error,
    @required this.stackTrace,
  });
  LogRecord._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    message = createServiceObject(json['message'], const ['InstanceRef']);
    time = json['time'];
    level = json['level'];
    sequenceNumber = json['sequenceNumber'];
    loggerName = createServiceObject(json['loggerName'], const ['InstanceRef']);
    zone = createServiceObject(json['zone'], const ['InstanceRef']);
    error = createServiceObject(json['error'], const ['InstanceRef']);
    stackTrace = createServiceObject(json['stackTrace'], const ['InstanceRef']);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'LogRecord';
    json.addAll({
      'message': message.toJson(),
      'time': time,
      'level': level,
      'sequenceNumber': sequenceNumber,
      'loggerName': loggerName.toJson(),
      'zone': zone.toJson(),
      'error': error.toJson(),
      'stackTrace': stackTrace.toJson(),
    });
    return json;
  }

  String toString() => '[LogRecord]';
}

class MapAssociation {
  static MapAssociation parse(Map<String, dynamic> json) =>
      json == null ? null : MapAssociation._fromJson(json);

  /// [key] can be one of [InstanceRef] or [Sentinel].
  dynamic key;

  /// [value] can be one of [InstanceRef] or [Sentinel].
  dynamic value;

  MapAssociation({
    @required this.key,
    @required this.value,
  });
  MapAssociation._fromJson(Map<String, dynamic> json) {
    key = createServiceObject(json['key'], const ['InstanceRef', 'Sentinel']);
    value =
        createServiceObject(json['value'], const ['InstanceRef', 'Sentinel']);
  }

  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json.addAll({
      'key': key.toJson(),
      'value': value.toJson(),
    });
    return json;
  }

  String toString() => '[MapAssociation key: ${key}, value: ${value}]';
}

/// A `MemoryUsage` object provides heap usage information for a specific
/// isolate at a given point in time.
class MemoryUsage extends Response {
  static MemoryUsage parse(Map<String, dynamic> json) =>
      json == null ? null : MemoryUsage._fromJson(json);

  /// The amount of non-Dart memory that is retained by Dart objects. For
  /// example, memory associated with Dart objects through APIs such as
  /// Dart_NewWeakPersistentHandle and Dart_NewExternalTypedData.  This usage is
  /// only as accurate as the values supplied to these APIs from the VM embedder
  /// or native extensions. This external memory applies GC pressure, but is
  /// separate from heapUsage and heapCapacity.
  int externalUsage;

  /// The total capacity of the heap in bytes. This is the amount of memory used
  /// by the Dart heap from the perspective of the operating system.
  int heapCapacity;

  /// The current heap memory usage in bytes. Heap usage is always less than or
  /// equal to the heap capacity.
  int heapUsage;

  MemoryUsage({
    @required this.externalUsage,
    @required this.heapCapacity,
    @required this.heapUsage,
  });
  MemoryUsage._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    externalUsage = json['externalUsage'];
    heapCapacity = json['heapCapacity'];
    heapUsage = json['heapUsage'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'MemoryUsage';
    json.addAll({
      'externalUsage': externalUsage,
      'heapCapacity': heapCapacity,
      'heapUsage': heapUsage,
    });
    return json;
  }

  String toString() => '[MemoryUsage ' //
      'type: ${type}, externalUsage: ${externalUsage}, heapCapacity: ${heapCapacity}, ' //
      'heapUsage: ${heapUsage}]';
}

/// A `Message` provides information about a pending isolate message and the
/// function that will be invoked to handle it.
class Message extends Response {
  static Message parse(Map<String, dynamic> json) =>
      json == null ? null : Message._fromJson(json);

  /// The index in the isolate's message queue. The 0th message being the next
  /// message to be processed.
  int index;

  /// An advisory name describing this message.
  String name;

  /// An instance id for the decoded message. This id can be passed to other
  /// RPCs, for example, getObject or evaluate.
  String messageObjectId;

  /// The size (bytes) of the encoded message.
  int size;

  /// A reference to the function that will be invoked to handle this message.
  @optional
  FuncRef handler;

  /// The source location of handler.
  @optional
  SourceLocation location;

  Message({
    @required this.index,
    @required this.name,
    @required this.messageObjectId,
    @required this.size,
    this.handler,
    this.location,
  });
  Message._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    index = json['index'];
    name = json['name'];
    messageObjectId = json['messageObjectId'];
    size = json['size'];
    handler = createServiceObject(json['handler'], const ['FuncRef']);
    location = createServiceObject(json['location'], const ['SourceLocation']);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'Message';
    json.addAll({
      'index': index,
      'name': name,
      'messageObjectId': messageObjectId,
      'size': size,
    });
    _setIfNotNull(json, 'handler', handler?.toJson());
    _setIfNotNull(json, 'location', location?.toJson());
    return json;
  }

  String toString() => '[Message ' //
      'type: ${type}, index: ${index}, name: ${name}, messageObjectId: ${messageObjectId}, ' //
      'size: ${size}]';
}

/// A `NativeFunction` object is used to represent native functions in profiler
/// samples. See [CpuSamples];
class NativeFunction {
  static NativeFunction parse(Map<String, dynamic> json) =>
      json == null ? null : NativeFunction._fromJson(json);

  /// The name of the native function this object represents.
  String name;

  NativeFunction({
    @required this.name,
  });
  NativeFunction._fromJson(Map<String, dynamic> json) {
    name = json['name'];
  }

  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json.addAll({
      'name': name,
    });
    return json;
  }

  String toString() => '[NativeFunction name: ${name}]';
}

/// `NullValRef` is a reference to an a `NullVal`.
class NullValRef extends InstanceRef {
  static NullValRef parse(Map<String, dynamic> json) =>
      json == null ? null : NullValRef._fromJson(json);

  /// Always 'null'.
  @override
  String valueAsString;

  NullValRef({
    @required this.valueAsString,
  });
  NullValRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    valueAsString = json['valueAsString'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = super.toJson();
    json['type'] = '@Null';
    json.addAll({
      'valueAsString': valueAsString,
    });
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is NullValRef && id == other.id;

  String toString() => '[NullValRef ' //
      'type: ${type}, id: ${id}, kind: ${kind}, classRef: ${classRef}, ' //
      'valueAsString: ${valueAsString}]';
}

/// A `NullVal` object represents the Dart language value null.
class NullVal extends Instance {
  static NullVal parse(Map<String, dynamic> json) =>
      json == null ? null : NullVal._fromJson(json);

  /// Always 'null'.
  @override
  String valueAsString;

  NullVal({
    @required this.valueAsString,
  });
  NullVal._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    valueAsString = json['valueAsString'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = super.toJson();
    json['type'] = 'Null';
    json.addAll({
      'valueAsString': valueAsString,
    });
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is NullVal && id == other.id;

  String toString() => '[NullVal ' //
      'type: ${type}, id: ${id}, kind: ${kind}, classRef: ${classRef}, ' //
      'valueAsString: ${valueAsString}]';
}

/// `ObjRef` is a reference to a `Obj`.
class ObjRef extends Response {
  static ObjRef parse(Map<String, dynamic> json) =>
      json == null ? null : ObjRef._fromJson(json);

  /// A unique identifier for an Object. Passed to the getObject RPC to load
  /// this Object.
  String id;

  /// Provided and set to true if the id of an Object is fixed. If true, the id
  /// of an Object is guaranteed not to change or expire. The object may,
  /// however, still be _Collected_.
  @optional
  bool fixedId;

  ObjRef({
    @required this.id,
    this.fixedId,
  });
  ObjRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    id = json['id'];
    fixedId = json['fixedId'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = '@Object';
    json.addAll({
      'id': id,
    });
    _setIfNotNull(json, 'fixedId', fixedId);
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is ObjRef && id == other.id;

  String toString() => '[ObjRef type: ${type}, id: ${id}]';
}

/// An `Obj` is a persistent object that is owned by some isolate.
class Obj extends Response {
  static Obj parse(Map<String, dynamic> json) =>
      json == null ? null : Obj._fromJson(json);

  /// A unique identifier for an Object. Passed to the getObject RPC to reload
  /// this Object.
  ///
  /// Some objects may get a new id when they are reloaded.
  String id;

  /// Provided and set to true if the id of an Object is fixed. If true, the id
  /// of an Object is guaranteed not to change or expire. The object may,
  /// however, still be _Collected_.
  @optional
  bool fixedId;

  /// If an object is allocated in the Dart heap, it will have a corresponding
  /// class object.
  ///
  /// The class of a non-instance is not a Dart class, but is instead an
  /// internal vm object.
  ///
  /// Moving an Object into or out of the heap is considered a backwards
  /// compatible change for types other than Instance.
  @optional
  ClassRef classRef;

  /// The size of this object in the heap.
  ///
  /// If an object is not heap-allocated, then this field is omitted.
  ///
  /// Note that the size can be zero for some objects. In the current VM
  /// implementation, this occurs for small integers, which are stored entirely
  /// within their object pointers.
  @optional
  int size;

  Obj({
    @required this.id,
    this.fixedId,
    this.classRef,
    this.size,
  });
  Obj._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    id = json['id'];
    fixedId = json['fixedId'];
    classRef = createServiceObject(json['class'], const ['ClassRef']);
    size = json['size'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'Object';
    json.addAll({
      'id': id,
    });
    _setIfNotNull(json, 'fixedId', fixedId);
    _setIfNotNull(json, 'class', classRef?.toJson());
    _setIfNotNull(json, 'size', size);
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is Obj && id == other.id;

  String toString() => '[Obj type: ${type}, id: ${id}]';
}

/// A `ProfileFunction` contains profiling information about a Dart or native
/// function.
///
/// See [CpuSamples].
class ProfileFunction {
  static ProfileFunction parse(Map<String, dynamic> json) =>
      json == null ? null : ProfileFunction._fromJson(json);

  /// The kind of function this object represents.
  String kind;

  /// The number of times function appeared on the stack during sampling events.
  int inclusiveTicks;

  /// The number of times function appeared on the top of the stack during
  /// sampling events.
  int exclusiveTicks;

  /// The resolved URL for the script containing function.
  String resolvedUrl;

  /// The function captured during profiling.
  dynamic function;

  ProfileFunction({
    @required this.kind,
    @required this.inclusiveTicks,
    @required this.exclusiveTicks,
    @required this.resolvedUrl,
    @required this.function,
  });
  ProfileFunction._fromJson(Map<String, dynamic> json) {
    kind = json['kind'];
    inclusiveTicks = json['inclusiveTicks'];
    exclusiveTicks = json['exclusiveTicks'];
    resolvedUrl = json['resolvedUrl'];
    function = createServiceObject(json['function'], const ['dynamic']);
  }

  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json.addAll({
      'kind': kind,
      'inclusiveTicks': inclusiveTicks,
      'exclusiveTicks': exclusiveTicks,
      'resolvedUrl': resolvedUrl,
      'function': function.toJson(),
    });
    return json;
  }

  String toString() => '[ProfileFunction ' //
      'kind: ${kind}, inclusiveTicks: ${inclusiveTicks}, exclusiveTicks: ${exclusiveTicks}, ' //
      'resolvedUrl: ${resolvedUrl}, function: ${function}]';
}

class ReloadReport extends Response {
  static ReloadReport parse(Map<String, dynamic> json) =>
      json == null ? null : ReloadReport._fromJson(json);

  /// Did the reload succeed or fail?
  bool success;

  ReloadReport({
    @required this.success,
  });
  ReloadReport._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    success = json['success'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'ReloadReport';
    json.addAll({
      'success': success,
    });
    return json;
  }

  String toString() => '[ReloadReport type: ${type}, success: ${success}]';
}

/// See [RetainingPath].
class RetainingObject {
  static RetainingObject parse(Map<String, dynamic> json) =>
      json == null ? null : RetainingObject._fromJson(json);

  /// An object that is part of a retaining path.
  ObjRef value;

  /// The offset of the retaining object in a containing list.
  @optional
  int parentListIndex;

  /// The key mapping to the retaining object in a containing map.
  @optional
  ObjRef parentMapKey;

  /// The name of the field containing the retaining object within an object.
  @optional
  String parentField;

  RetainingObject({
    @required this.value,
    this.parentListIndex,
    this.parentMapKey,
    this.parentField,
  });
  RetainingObject._fromJson(Map<String, dynamic> json) {
    value = createServiceObject(json['value'], const ['ObjRef']);
    parentListIndex = json['parentListIndex'];
    parentMapKey = createServiceObject(json['parentMapKey'], const ['ObjRef']);
    parentField = json['parentField'];
  }

  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json.addAll({
      'value': value.toJson(),
    });
    _setIfNotNull(json, 'parentListIndex', parentListIndex);
    _setIfNotNull(json, 'parentMapKey', parentMapKey?.toJson());
    _setIfNotNull(json, 'parentField', parentField);
    return json;
  }

  String toString() => '[RetainingObject value: ${value}]';
}

/// See [getRetainingPath].
class RetainingPath extends Response {
  static RetainingPath parse(Map<String, dynamic> json) =>
      json == null ? null : RetainingPath._fromJson(json);

  /// The length of the retaining path.
  int length;

  /// The type of GC root which is holding a reference to the specified object.
  /// Possible values include:  * class table  * local handle  * persistent
  /// handle  * stack  * user global  * weak persistent handle  * unknown
  String gcRootType;

  /// The chain of objects which make up the retaining path.
  List<RetainingObject> elements;

  RetainingPath({
    @required this.length,
    @required this.gcRootType,
    @required this.elements,
  });
  RetainingPath._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    length = json['length'];
    gcRootType = json['gcRootType'];
    elements = List<RetainingObject>.from(
        createServiceObject(json['elements'], const ['RetainingObject']) ?? []);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'RetainingPath';
    json.addAll({
      'length': length,
      'gcRootType': gcRootType,
      'elements': elements.map((f) => f.toJson()).toList(),
    });
    return json;
  }

  String toString() => '[RetainingPath ' //
      'type: ${type}, length: ${length}, gcRootType: ${gcRootType}, ' //
      'elements: ${elements}]';
}

/// Every non-error response returned by the Service Protocol extends
/// `Response`. By using the `type` property, the client can determine which
/// [type] of response has been provided.
class Response {
  static Response parse(Map<String, dynamic> json) =>
      json == null ? null : Response._fromJson(json);

  Map<String, dynamic> json;

  /// Every response returned by the VM Service has the type property. This
  /// allows the client distinguish between different kinds of responses.
  String type;

  Response({
    @required this.type,
  });
  Response._fromJson(this.json) {
    type = json['type'];
  }

  Map<String, dynamic> toJson() {
    var result = json == null ? <String, dynamic>{} : Map.of(json);
    result['type'] = type ?? 'Response';
    return result;
  }

  String toString() => '[Response type: ${type}]';
}

/// A `Sentinel` is used to indicate that the normal response is not available.
///
/// We use a `Sentinel` instead of an [error] for these cases because they do
/// not represent a problematic condition. They are normal.
class Sentinel extends Response {
  static Sentinel parse(Map<String, dynamic> json) =>
      json == null ? null : Sentinel._fromJson(json);

  /// What kind of sentinel is this?
  /*SentinelKind*/ String kind;

  /// A reasonable string representation of this sentinel.
  String valueAsString;

  Sentinel({
    @required this.kind,
    @required this.valueAsString,
  });
  Sentinel._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    kind = json['kind'];
    valueAsString = json['valueAsString'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'Sentinel';
    json.addAll({
      'kind': kind,
      'valueAsString': valueAsString,
    });
    return json;
  }

  String toString() => '[Sentinel ' //
      'type: ${type}, kind: ${kind}, valueAsString: ${valueAsString}]';
}

/// `ScriptRef` is a reference to a `Script`.
class ScriptRef extends ObjRef {
  static ScriptRef parse(Map<String, dynamic> json) =>
      json == null ? null : ScriptRef._fromJson(json);

  /// The uri from which this script was loaded.
  String uri;

  ScriptRef({
    @required this.uri,
  });
  ScriptRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    uri = json['uri'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = super.toJson();
    json['type'] = '@Script';
    json.addAll({
      'uri': uri,
    });
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is ScriptRef && id == other.id;

  String toString() => '[ScriptRef type: ${type}, id: ${id}, uri: ${uri}]';
}

/// A `Script` provides information about a Dart language script.
///
/// The `tokenPosTable` is an array of int arrays. Each subarray consists of a
/// line number followed by `(tokenPos, columnNumber)` pairs:
///
/// ```
/// [
/// ```lineNumber, (tokenPos, columnNumber)*]
/// ```
///
/// The `tokenPos` is an arbitrary integer value that is used to represent a
/// location in the source code. A `tokenPos` value is not meaningful in itself
/// and code should not rely on the exact values returned.
///
/// For example, a `tokenPosTable` with the value...
///
/// ```
/// [
/// ```[
/// ```1, 100, 5, 101, 8],[
/// ```2, 102, 7]]
/// ```
///
/// ...encodes the mapping:
///
/// tokenPos | line | column
/// -------- | ---- | ------
/// 100 | 1 | 5
/// 101 | 1 | 8
/// 102 | 2 | 7
class Script extends Obj {
  static Script parse(Map<String, dynamic> json) =>
      json == null ? null : Script._fromJson(json);

  final _tokenToLine = <int, int>{};
  final _tokenToColumn = <int, int>{};

  /// The uri from which this script was loaded.
  String uri;

  /// The library which owns this script.
  LibraryRef library;

  @optional
  int lineOffset;

  @optional
  int columnOffset;

  /// The source code for this script. This can be null for certain built-in
  /// scripts.
  @optional
  String source;

  /// A table encoding a mapping from token position to line and column. This
  /// field is null if sources aren't available.
  @optional
  List<List<int>> tokenPosTable;

  Script({
    @required this.uri,
    @required this.library,
    this.lineOffset,
    this.columnOffset,
    this.source,
    this.tokenPosTable,
  });
  Script._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    uri = json['uri'];
    library = createServiceObject(json['library'], const ['LibraryRef']);
    lineOffset = json['lineOffset'];
    columnOffset = json['columnOffset'];
    source = json['source'];
    tokenPosTable = json['tokenPosTable'] == null
        ? null
        : List<List<int>>.from(
            json['tokenPosTable'].map((dynamic list) => List<int>.from(list)));
    _parseTokenPosTable();
  }

  /// This function maps a token position to a line number.
  /// The VM considers the first line to be line 1.
  int getLineNumberFromTokenPos(int tokenPos) => _tokenToLine[tokenPos];

  /// This function maps a token position to a column number.
  /// The VM considers the first column to be column 1.
  int getColumnNumberFromTokenPos(int tokenPos) => _tokenToColumn[tokenPos];

  void _parseTokenPosTable() {
    if (tokenPosTable == null) {
      return;
    }
    final lineSet = Set<int>();
    for (List line in tokenPosTable) {
      // Each entry begins with a line number...
      int lineNumber = line[0];
      lineSet.add(lineNumber);
      for (var pos = 1; pos < line.length; pos += 2) {
        // ...and is followed by (token offset, col number) pairs.
        final int tokenOffset = line[pos];
        final int colNumber = line[pos + 1];
        _tokenToLine[tokenOffset] = lineNumber;
        _tokenToColumn[tokenOffset] = colNumber;
      }
    }
  }

  @override
  Map<String, dynamic> toJson() {
    var json = super.toJson();
    json['type'] = 'Script';
    json.addAll({
      'uri': uri,
      'library': library.toJson(),
    });
    _setIfNotNull(json, 'lineOffset', lineOffset);
    _setIfNotNull(json, 'columnOffset', columnOffset);
    _setIfNotNull(json, 'source', source);
    _setIfNotNull(json, 'tokenPosTable',
        tokenPosTable?.map((f) => f?.toList())?.toList());
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is Script && id == other.id;

  String toString() =>
      '[Script type: ${type}, id: ${id}, uri: ${uri}, library: ${library}]';
}

class ScriptList extends Response {
  static ScriptList parse(Map<String, dynamic> json) =>
      json == null ? null : ScriptList._fromJson(json);

  List<ScriptRef> scripts;

  ScriptList({
    @required this.scripts,
  });
  ScriptList._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    scripts = List<ScriptRef>.from(
        createServiceObject(json['scripts'], const ['ScriptRef']) ?? []);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'ScriptList';
    json.addAll({
      'scripts': scripts.map((f) => f.toJson()).toList(),
    });
    return json;
  }

  String toString() => '[ScriptList type: ${type}, scripts: ${scripts}]';
}

/// The `SourceLocation` class is used to designate a position or range in some
/// script.
class SourceLocation extends Response {
  static SourceLocation parse(Map<String, dynamic> json) =>
      json == null ? null : SourceLocation._fromJson(json);

  /// The script containing the source location.
  ScriptRef script;

  /// The first token of the location.
  int tokenPos;

  /// The last token of the location if this is a range.
  @optional
  int endTokenPos;

  SourceLocation({
    @required this.script,
    @required this.tokenPos,
    this.endTokenPos,
  });
  SourceLocation._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    script = createServiceObject(json['script'], const ['ScriptRef']);
    tokenPos = json['tokenPos'];
    endTokenPos = json['endTokenPos'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'SourceLocation';
    json.addAll({
      'script': script.toJson(),
      'tokenPos': tokenPos,
    });
    _setIfNotNull(json, 'endTokenPos', endTokenPos);
    return json;
  }

  String toString() =>
      '[SourceLocation type: ${type}, script: ${script}, tokenPos: ${tokenPos}]';
}

/// The `SourceReport` class represents a set of reports tied to source
/// locations in an isolate.
class SourceReport extends Response {
  static SourceReport parse(Map<String, dynamic> json) =>
      json == null ? null : SourceReport._fromJson(json);

  /// A list of ranges in the program source.  These ranges correspond to ranges
  /// of executable code in the user's program (functions, methods,
  /// constructors, etc.)
  ///
  /// Note that ranges may nest in other ranges, in the case of nested
  /// functions.
  ///
  /// Note that ranges may be duplicated, in the case of mixins.
  List<SourceReportRange> ranges;

  /// A list of scripts, referenced by index in the report's ranges.
  List<ScriptRef> scripts;

  SourceReport({
    @required this.ranges,
    @required this.scripts,
  });
  SourceReport._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    ranges = List<SourceReportRange>.from(
        _createSpecificObject(json['ranges'], SourceReportRange.parse));
    scripts = List<ScriptRef>.from(
        createServiceObject(json['scripts'], const ['ScriptRef']) ?? []);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'SourceReport';
    json.addAll({
      'ranges': ranges.map((f) => f.toJson()).toList(),
      'scripts': scripts.map((f) => f.toJson()).toList(),
    });
    return json;
  }

  String toString() =>
      '[SourceReport type: ${type}, ranges: ${ranges}, scripts: ${scripts}]';
}

/// The `SourceReportCoverage` class represents coverage information for one
/// [SourceReportRange].
///
/// Note that `SourceReportCoverage` does not extend [Response] and therefore
/// will not contain a `type` property.
class SourceReportCoverage {
  static SourceReportCoverage parse(Map<String, dynamic> json) =>
      json == null ? null : SourceReportCoverage._fromJson(json);

  /// A list of token positions in a SourceReportRange which have been executed.
  /// The list is sorted.
  List<int> hits;

  /// A list of token positions in a SourceReportRange which have not been
  /// executed.  The list is sorted.
  List<int> misses;

  SourceReportCoverage({
    @required this.hits,
    @required this.misses,
  });
  SourceReportCoverage._fromJson(Map<String, dynamic> json) {
    hits = List<int>.from(json['hits']);
    misses = List<int>.from(json['misses']);
  }

  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json.addAll({
      'hits': hits.map((f) => f).toList(),
      'misses': misses.map((f) => f).toList(),
    });
    return json;
  }

  String toString() =>
      '[SourceReportCoverage hits: ${hits}, misses: ${misses}]';
}

/// The `SourceReportRange` class represents a range of executable code
/// (function, method, constructor, etc) in the running program. It is part of a
/// [SourceReport].
///
/// Note that `SourceReportRange` does not extend [Response] and therefore will
/// not contain a `type` property.
class SourceReportRange {
  static SourceReportRange parse(Map<String, dynamic> json) =>
      json == null ? null : SourceReportRange._fromJson(json);

  /// An index into the script table of the SourceReport, indicating which
  /// script contains this range of code.
  int scriptIndex;

  /// The token position at which this range begins.
  int startPos;

  /// The token position at which this range ends.  Inclusive.
  int endPos;

  /// Has this range been compiled by the Dart VM?
  bool compiled;

  /// The error while attempting to compile this range, if this report was
  /// generated with forceCompile=true.
  @optional
  ErrorRef error;

  /// Code coverage information for this range.  Provided only when the Coverage
  /// report has been requested and the range has been compiled.
  @optional
  SourceReportCoverage coverage;

  /// Possible breakpoint information for this range, represented as a sorted
  /// list of token positions.  Provided only when the when the
  /// PossibleBreakpoint report has been requested and the range has been
  /// compiled.
  @optional
  List<int> possibleBreakpoints;

  SourceReportRange({
    @required this.scriptIndex,
    @required this.startPos,
    @required this.endPos,
    @required this.compiled,
    this.error,
    this.coverage,
    this.possibleBreakpoints,
  });
  SourceReportRange._fromJson(Map<String, dynamic> json) {
    scriptIndex = json['scriptIndex'];
    startPos = json['startPos'];
    endPos = json['endPos'];
    compiled = json['compiled'];
    error = createServiceObject(json['error'], const ['ErrorRef']);
    coverage =
        _createSpecificObject(json['coverage'], SourceReportCoverage.parse);
    possibleBreakpoints = json['possibleBreakpoints'] == null
        ? null
        : List<int>.from(json['possibleBreakpoints']);
  }

  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json.addAll({
      'scriptIndex': scriptIndex,
      'startPos': startPos,
      'endPos': endPos,
      'compiled': compiled,
    });
    _setIfNotNull(json, 'error', error?.toJson());
    _setIfNotNull(json, 'coverage', coverage?.toJson());
    _setIfNotNull(json, 'possibleBreakpoints',
        possibleBreakpoints?.map((f) => f)?.toList());
    return json;
  }

  String toString() => '[SourceReportRange ' //
      'scriptIndex: ${scriptIndex}, startPos: ${startPos}, endPos: ${endPos}, ' //
      'compiled: ${compiled}]';
}

class Stack extends Response {
  static Stack parse(Map<String, dynamic> json) =>
      json == null ? null : Stack._fromJson(json);

  List<Frame> frames;

  @optional
  List<Frame> asyncCausalFrames;

  @optional
  List<Frame> awaiterFrames;

  List<Message> messages;

  Stack({
    @required this.frames,
    @required this.messages,
    this.asyncCausalFrames,
    this.awaiterFrames,
  });
  Stack._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    frames = List<Frame>.from(
        createServiceObject(json['frames'], const ['Frame']) ?? []);
    asyncCausalFrames = json['asyncCausalFrames'] == null
        ? null
        : List<Frame>.from(
            createServiceObject(json['asyncCausalFrames'], const ['Frame']));
    awaiterFrames = json['awaiterFrames'] == null
        ? null
        : List<Frame>.from(
            createServiceObject(json['awaiterFrames'], const ['Frame']));
    messages = List<Message>.from(
        createServiceObject(json['messages'], const ['Message']) ?? []);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'Stack';
    json.addAll({
      'frames': frames.map((f) => f.toJson()).toList(),
      'messages': messages.map((f) => f.toJson()).toList(),
    });
    _setIfNotNull(json, 'asyncCausalFrames',
        asyncCausalFrames?.map((f) => f?.toJson())?.toList());
    _setIfNotNull(json, 'awaiterFrames',
        awaiterFrames?.map((f) => f?.toJson())?.toList());
    return json;
  }

  String toString() =>
      '[Stack type: ${type}, frames: ${frames}, messages: ${messages}]';
}

/// The `Success` type is used to indicate that an operation completed
/// successfully.
class Success extends Response {
  static Success parse(Map<String, dynamic> json) =>
      json == null ? null : Success._fromJson(json);

  Success();
  Success._fromJson(Map<String, dynamic> json) : super._fromJson(json);

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'Success';
    return json;
  }

  String toString() => '[Success type: ${type}]';
}

class Timeline extends Response {
  static Timeline parse(Map<String, dynamic> json) =>
      json == null ? null : Timeline._fromJson(json);

  /// A list of timeline events.
  List<TimelineEvent> traceEvents;

  /// The start of the period of time in which traceEvents were collected.
  int timeOriginMicros;

  /// The duration of time covered by the timeline.
  int timeExtentMicros;

  Timeline({
    @required this.traceEvents,
    @required this.timeOriginMicros,
    @required this.timeExtentMicros,
  });
  Timeline._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    traceEvents = List<TimelineEvent>.from(
        createServiceObject(json['traceEvents'], const ['TimelineEvent']) ??
            []);
    timeOriginMicros = json['timeOriginMicros'];
    timeExtentMicros = json['timeExtentMicros'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'Timeline';
    json.addAll({
      'traceEvents': traceEvents.map((f) => f.toJson()).toList(),
      'timeOriginMicros': timeOriginMicros,
      'timeExtentMicros': timeExtentMicros,
    });
    return json;
  }

  String toString() => '[Timeline ' //
      'type: ${type}, traceEvents: ${traceEvents}, timeOriginMicros: ${timeOriginMicros}, ' //
      'timeExtentMicros: ${timeExtentMicros}]';
}

/// An `TimelineEvent` is an arbitrary map that contains a [Trace Event Format]
/// event.
class TimelineEvent {
  static TimelineEvent parse(Map<String, dynamic> json) =>
      json == null ? null : TimelineEvent._fromJson(json);

  Map<String, dynamic> json;

  TimelineEvent();
  TimelineEvent._fromJson(this.json);

  Map<String, dynamic> toJson() {
    var result = json == null ? <String, dynamic>{} : Map.of(json);
    result['type'] = 'TimelineEvent';
    return result;
  }

  String toString() => '[TimelineEvent ]';
}

class TimelineFlags extends Response {
  static TimelineFlags parse(Map<String, dynamic> json) =>
      json == null ? null : TimelineFlags._fromJson(json);

  /// The name of the recorder currently in use. Recorder types include, but are
  /// not limited to: Callback, Endless, Fuchsia, Macos, Ring, Startup, and
  /// Systrace. Set to "null" if no recorder is currently set.
  String recorderName;

  /// The list of all available timeline streams.
  List<String> availableStreams;

  /// The list of timeline streams that are currently enabled.
  List<String> recordedStreams;

  TimelineFlags({
    @required this.recorderName,
    @required this.availableStreams,
    @required this.recordedStreams,
  });
  TimelineFlags._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    recorderName = json['recorderName'];
    availableStreams = List<String>.from(json['availableStreams']);
    recordedStreams = List<String>.from(json['recordedStreams']);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'TimelineFlags';
    json.addAll({
      'recorderName': recorderName,
      'availableStreams': availableStreams.map((f) => f).toList(),
      'recordedStreams': recordedStreams.map((f) => f).toList(),
    });
    return json;
  }

  String toString() => '[TimelineFlags ' //
      'type: ${type}, recorderName: ${recorderName}, availableStreams: ${availableStreams}, ' //
      'recordedStreams: ${recordedStreams}]';
}

class Timestamp extends Response {
  static Timestamp parse(Map<String, dynamic> json) =>
      json == null ? null : Timestamp._fromJson(json);

  /// A timestamp in microseconds since epoch.
  int timestamp;

  Timestamp({
    @required this.timestamp,
  });
  Timestamp._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    timestamp = json['timestamp'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'Timestamp';
    json.addAll({
      'timestamp': timestamp,
    });
    return json;
  }

  String toString() => '[Timestamp type: ${type}, timestamp: ${timestamp}]';
}

/// `TypeArgumentsRef` is a reference to a `TypeArguments` object.
class TypeArgumentsRef extends ObjRef {
  static TypeArgumentsRef parse(Map<String, dynamic> json) =>
      json == null ? null : TypeArgumentsRef._fromJson(json);

  /// A name for this type argument list.
  String name;

  TypeArgumentsRef({
    @required this.name,
  });
  TypeArgumentsRef._fromJson(Map<String, dynamic> json)
      : super._fromJson(json) {
    name = json['name'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = super.toJson();
    json['type'] = '@TypeArguments';
    json.addAll({
      'name': name,
    });
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is TypeArgumentsRef && id == other.id;

  String toString() =>
      '[TypeArgumentsRef type: ${type}, id: ${id}, name: ${name}]';
}

/// A `TypeArguments` object represents the type argument vector for some
/// instantiated generic type.
class TypeArguments extends Obj {
  static TypeArguments parse(Map<String, dynamic> json) =>
      json == null ? null : TypeArguments._fromJson(json);

  /// A name for this type argument list.
  String name;

  /// A list of types.
  ///
  /// The value will always be one of the kinds: Type, TypeRef, TypeParameter,
  /// BoundedType.
  List<InstanceRef> types;

  TypeArguments({
    @required this.name,
    @required this.types,
  });
  TypeArguments._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    name = json['name'];
    types = List<InstanceRef>.from(
        createServiceObject(json['types'], const ['InstanceRef']) ?? []);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = super.toJson();
    json['type'] = 'TypeArguments';
    json.addAll({
      'name': name,
      'types': types.map((f) => f.toJson()).toList(),
    });
    return json;
  }

  int get hashCode => id.hashCode;

  operator ==(other) => other is TypeArguments && id == other.id;

  String toString() =>
      '[TypeArguments type: ${type}, id: ${id}, name: ${name}, types: ${types}]';
}

/// The `UnresolvedSourceLocation` class is used to refer to an unresolved
/// breakpoint location. As such, it is meant to approximate the final location
/// of the breakpoint but it is not exact.
///
/// Either the `script` or the `scriptUri` field will be present.
///
/// Either the `tokenPos` or the `line` field will be present.
///
/// The `column` field will only be present when the breakpoint was specified
/// with a specific column number.
class UnresolvedSourceLocation extends Response {
  static UnresolvedSourceLocation parse(Map<String, dynamic> json) =>
      json == null ? null : UnresolvedSourceLocation._fromJson(json);

  /// The script containing the source location if the script has been loaded.
  @optional
  ScriptRef script;

  /// The uri of the script containing the source location if the script has yet
  /// to be loaded.
  @optional
  String scriptUri;

  /// An approximate token position for the source location. This may change
  /// when the location is resolved.
  @optional
  int tokenPos;

  /// An approximate line number for the source location. This may change when
  /// the location is resolved.
  @optional
  int line;

  /// An approximate column number for the source location. This may change when
  /// the location is resolved.
  @optional
  int column;

  UnresolvedSourceLocation({
    this.script,
    this.scriptUri,
    this.tokenPos,
    this.line,
    this.column,
  });
  UnresolvedSourceLocation._fromJson(Map<String, dynamic> json)
      : super._fromJson(json) {
    script = createServiceObject(json['script'], const ['ScriptRef']);
    scriptUri = json['scriptUri'];
    tokenPos = json['tokenPos'];
    line = json['line'];
    column = json['column'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'UnresolvedSourceLocation';
    _setIfNotNull(json, 'script', script?.toJson());
    _setIfNotNull(json, 'scriptUri', scriptUri);
    _setIfNotNull(json, 'tokenPos', tokenPos);
    _setIfNotNull(json, 'line', line);
    _setIfNotNull(json, 'column', column);
    return json;
  }

  String toString() => '[UnresolvedSourceLocation type: ${type}]';
}

/// See [Versioning].
class Version extends Response {
  static Version parse(Map<String, dynamic> json) =>
      json == null ? null : Version._fromJson(json);

  /// The major version number is incremented when the protocol is changed in a
  /// potentially incompatible way.
  int major;

  /// The minor version number is incremented when the protocol is changed in a
  /// backwards compatible way.
  int minor;

  Version({
    @required this.major,
    @required this.minor,
  });
  Version._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    major = json['major'];
    minor = json['minor'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'Version';
    json.addAll({
      'major': major,
      'minor': minor,
    });
    return json;
  }

  String toString() =>
      '[Version type: ${type}, major: ${major}, minor: ${minor}]';
}

/// `VMRef` is a reference to a `VM` object.
class VMRef extends Response {
  static VMRef parse(Map<String, dynamic> json) =>
      json == null ? null : VMRef._fromJson(json);

  /// A name identifying this vm. Not guaranteed to be unique.
  String name;

  VMRef({
    @required this.name,
  });
  VMRef._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    name = json['name'];
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = '@VM';
    json.addAll({
      'name': name,
    });
    return json;
  }

  String toString() => '[VMRef type: ${type}, name: ${name}]';
}

class VM extends Response {
  static VM parse(Map<String, dynamic> json) =>
      json == null ? null : VM._fromJson(json);

  /// A name identifying this vm. Not guaranteed to be unique.
  String name;

  /// Word length on target architecture (e.g. 32, 64).
  int architectureBits;

  /// The CPU we are actually running on.
  String hostCPU;

  /// The operating system we are running on.
  String operatingSystem;

  /// The CPU we are generating code for.
  String targetCPU;

  /// The Dart VM version string.
  String version;

  /// The process id for the VM.
  int pid;

  /// The time that the VM started in milliseconds since the epoch.
  ///
  /// Suitable to pass to DateTime.fromMillisecondsSinceEpoch.
  int startTime;

  /// A list of isolates running in the VM.
  List<IsolateRef> isolates;

  /// A list of isolate groups running in the VM.
  List<IsolateGroupRef> isolateGroups;

  VM({
    @required this.name,
    @required this.architectureBits,
    @required this.hostCPU,
    @required this.operatingSystem,
    @required this.targetCPU,
    @required this.version,
    @required this.pid,
    @required this.startTime,
    @required this.isolates,
    @required this.isolateGroups,
  });
  VM._fromJson(Map<String, dynamic> json) : super._fromJson(json) {
    name = json['name'];
    architectureBits = json['architectureBits'];
    hostCPU = json['hostCPU'];
    operatingSystem = json['operatingSystem'];
    targetCPU = json['targetCPU'];
    version = json['version'];
    pid = json['pid'];
    startTime = json['startTime'];
    isolates = List<IsolateRef>.from(
        createServiceObject(json['isolates'], const ['IsolateRef']) ?? []);
    isolateGroups = List<IsolateGroupRef>.from(
        createServiceObject(json['isolateGroups'], const ['IsolateGroupRef']) ??
            []);
  }

  @override
  Map<String, dynamic> toJson() {
    var json = <String, dynamic>{};
    json['type'] = 'VM';
    json.addAll({
      'name': name,
      'architectureBits': architectureBits,
      'hostCPU': hostCPU,
      'operatingSystem': operatingSystem,
      'targetCPU': targetCPU,
      'version': version,
      'pid': pid,
      'startTime': startTime,
      'isolates': isolates.map((f) => f.toJson()).toList(),
      'isolateGroups': isolateGroups.map((f) => f.toJson()).toList(),
    });
    return json;
  }

  String toString() => '[VM]';
}
