// 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.

library generate_vm_service_dart;

// TODO(bkonyi): remove once markdown and pub_semver deps are updated to null
// safety for the SDK.
// ignore_for_file: import_of_legacy_library_into_null_safe
import 'package:markdown/markdown.dart';

import '../common/generate_common.dart';
import '../common/parser.dart';
import '../common/src_gen_common.dart';
import 'src_gen_dart.dart';

export 'src_gen_dart.dart' show DartGenerator;

late Api api;

String? _coerceRefType(String? typeName) {
  if (typeName == 'Object') typeName = 'Obj';
  if (typeName == '@Object') typeName = 'ObjRef';
  if (typeName == 'Null') typeName = 'NullVal';
  if (typeName == '@Null') typeName = 'NullValRef';
  if (typeName == 'Function') typeName = 'Func';
  if (typeName == '@Function') typeName = 'FuncRef';

  if (typeName!.startsWith('@')) typeName = typeName.substring(1) + 'Ref';

  if (typeName == 'string') typeName = 'String';
  if (typeName == 'map') typeName = 'Map';

  return typeName;
}

String _typeRefListToString(List<TypeRef> types) =>
    'const [' + types.map((e) => "'" + e.name! + "'").join(',') + ']';

final String _headerCode = r'''
// 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 'service_extension_registry.dart';

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

final String _implCode = r'''

  /// 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<String, dynamic>? args
  }) {
    return callServiceExtension(method, isolateId: isolateId, args: args);
  }

  /// Invoke a specific service protocol extension method.
  ///
  /// See https://api.dart.dev/stable/dart-developer/dart-developer-library.html.
  @override
  Future<Response> callServiceExtension(String method, {
    String? isolateId,
    Map<String, dynamic>? 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;

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

  Future get onDone => _onDoneCompleter.future;

  Future<T> _call<T>(String method, [Map args = const {}]) {
    String id = '${++_id}';
    Completer<T> completer = Completer<T>();
    _completers[id] = completer;
    _methodCalls[id] = method;
    Map m = {'jsonrpc': '2.0', 'id': id, 'method': method, '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['method'] == 'streamNotify') {
      String streamId = map['params']['streamId'];
      Map event = map['params']['event'];
      event['data'] = data;
      _getEventController(streamId)
          .add(createServiceObject(event, const ['Event'])! as Event);
    }
  }

  void _processMessageStr(String message) {
    late Map<String, dynamic> 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 (type == 'Sentinel') {
        completer.completeError(SentinelException.parse(methodName, result));
      } else 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'] ?? <String, dynamic>{});
    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<String, dynamic> params = json['params'] ?? <String, dynamic>{};
    if (method == 'streamNotify') {
      String streamId = params['streamId'];
      _getEventController(streamId).add(createServiceObject(params['event'], const ['Event'])! as Event);
    } else {
      await _routeRequest(method, params);
    }
  }

  Future<Map> _routeRequest(String method, Map<String, dynamic> params) async{
    final service = _services[method];
    if (service == null) {
      RPCError error = RPCError(
          method, RPCError.kMethodNotFound, 'method not found \'$method\'');
      return {'error': error.toMap()};
    }

    try {
      return await service(params);
    } catch (e, st) {
      RPCError error = RPCError.withDetails(
        method, RPCError.kServerError, '$e', details: '$st',);
      return {'error': error.toMap()};
    }
  }
''';

final String _rpcError = r'''


typedef DisposeHandler = Future Function();

class RPCError implements Exception {
  /// Application specific error codes.
  static const int kServerError = -32000;

  /// The JSON sent is not a valid Request object.
  static const int kInvalidRequest = -32600;

  /// The method does not exist or is not available.
  static const int kMethodNotFound = -32601;

  /// Invalid method parameter(s), such as a mismatched type.
  static const int kInvalidParams = -32602;

  /// Internal JSON-RPC error.
  static const int kInternalError = -32603;

  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]);

  RPCError.withDetails(this.callingMethod, this.code, this.message,
      {Object? details})
      : data = details == null ? null : <String, dynamic>{} {
    if (details != null) {
      data!['details'] = details;
    }
  }

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

  /// Return a map representation of this error suitable for converstion to
  /// json.
  Map<String, dynamic> toMap() {
    Map<String, dynamic> map = {
      'code': code,
      'message': message,
    };
    if (data != null) {
      map['data'] = data;
    }
    return map;
  }

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

/// Thrown when an RPC response is a [Sentinel].
class SentinelException implements Exception {
  final String callingMethod;
  final Sentinel sentinel;

  SentinelException.parse(this.callingMethod, Map<String, dynamic> data) :
    sentinel = Sentinel.parse(data)!;

  String toString() => '$sentinel from ${callingMethod}()';
}

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

  final Map<String, dynamic> 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) {}
}
''';

final _registerServiceImpl = '''
_serviceExtensionRegistry.registerExtension(params!['service'], this);
response =  Success();''';

final _streamListenCaseImpl = '''
var id = params!['streamId'];
if (_streamSubscriptions.containsKey(id)) {
  throw RPCError.withDetails(
    '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();''';

final _streamCancelCaseImpl = '''
var id = params!['streamId'];
var existing = _streamSubscriptions.remove(id);
if (existing == null) {
  throw RPCError.withDetails(
    'streamCancel', 104, 'Stream not subscribed',
    details: "The stream '\$id' is not subscribed",
  );
}
await existing.cancel();
response = Success();''';

abstract class Member {
  String? get name;

  String? get docs => null;

  void generate(DartGenerator gen);

  bool get hasDocs => docs != null;

  String toString() => name!;
}

class Api extends Member with ApiParseUtil {
  String? serviceVersion;
  List<Method> methods = [];
  List<Enum> enums = [];
  List<Type?> types = [];
  List<StreamCategory> streamCategories = [];

  void parse(List<Node> nodes) {
    serviceVersion = ApiParseUtil.parseVersionString(nodes);

    // Look for h3 nodes
    // the pre following it is the definition
    // the optional p following that is the documentation

    String? h3Name;

    for (int i = 0; i < nodes.length; i++) {
      Node node = nodes[i];

      if (isPre(node) && h3Name != null) {
        String definition = textForCode(node);
        String? docs = '';

        while (i + 1 < nodes.length &&
                (isPara(nodes[i + 1]) || isBlockquote(nodes[i + 1])) ||
            isList(nodes[i + 1])) {
          Element p = nodes[++i] as Element;
          String str = TextOutputVisitor.printText(p);
          if (!str.contains('|') &&
              !str.contains('``') &&
              !str.startsWith('- ')) {
            str = collapseWhitespace(str);
          }
          docs = '${docs}\n\n${str}';
        }

        docs = docs!.trim();
        if (docs.isEmpty) docs = null;

        _parse(h3Name, definition, docs);
      } else if (isH3(node)) {
        h3Name = textForElement(node);
      } else if (isHeader(node)) {
        h3Name = null;
      }
    }

    for (Type? type in types) {
      type!.calculateFieldOverrides();
    }

    Method streamListenMethod =
        methods.singleWhere((method) => method.name == 'streamListen');
    _parseStreamListenDocs(streamListenMethod.docs!);
  }

  String get name => 'api';

  String? get docs => null;

  void _parse(String name, String definition, [String? docs]) {
    name = name.trim();
    definition = definition.trim();
    // clean markdown introduced changes
    definition = definition.replaceAll('&lt;', '<').replaceAll('&gt;', '>');
    if (docs != null) docs = docs.trim();

    if (definition.startsWith('class ')) {
      types.add(Type(this, name, definition, docs));
    } else if (name.substring(0, 1).toLowerCase() == name.substring(0, 1)) {
      methods.add(Method(name, definition, docs));
    } else if (definition.startsWith('enum ')) {
      enums.add(Enum(name, definition, docs));
    } else {
      throw 'unexpected entity: ${name}, ${definition}';
    }
  }

  static String printNode(Node n) {
    if (n is Text) {
      return n.text;
    } else if (n is Element) {
      if (n.tag != 'h3') return n.tag;
      return '${n.tag}:[${n.children.map((c) => printNode(c)).join(', ')}]';
    } else {
      return '${n}';
    }
  }

  void generate(DartGenerator gen) {
    gen.out(_headerCode);
    gen.writeln("const String vmServiceVersion = '${serviceVersion}';");
    gen.writeln();
    gen.writeln('''
/// @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;
    }
    final typeFactory = _typeFactories[type];
    if (typeFactory == null) {
      return null;
    } else {
      return typeFactory(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) {
    return creator({
      for (String key in json.keys)
        key: json[key],
    });
  } else {
    // Handle simple types.
    return json;
  }
}

void _setIfNotNull(Map<String, dynamic> 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;
}

''');
    gen.writeln();
    gen.writeln('Map<String, Function> _typeFactories = {');
    types.forEach((Type? type) {
      gen.writeln("'${type!.rawName}': ${type.name}.parse,");
    });
    gen.writeln('};');
    gen.writeln();

    gen.writeln('Map<String, List<String>> _methodReturnTypes = {');
    methods.forEach((Method method) {
      String returnTypes = _typeRefListToString(method.returnType.types);
      gen.writeln("'${method.name}' : $returnTypes,");
    });
    gen.writeln('};');
    gen.writeln();

    // The service interface, both servers and clients implement this.
    gen.writeStatement('''
/// 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<String, dynamic>? args});
''');
    methods.forEach((m) {
      m.generateDefinition(gen);
      gen.write(';');
    });
    gen.write('}');
    gen.writeln();

    // The server class, takes a VmServiceInterface and delegates to it
    // automatically.
    gen.write('''
  class _PendingServiceRequest {
    Future<Map<String, Object?>> get future => _completer.future;
    final _completer = Completer<Map<String, Object?>>();

    final dynamic originalId;

    _PendingServiceRequest(this.originalId);

    void complete(Map<String, Object?> response) {
      response['id'] = originalId;
      _completer.complete(response);
    }
  }

  /// 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<void> get done => _doneCompleter.future;
    final _doneCompleter = Completer<void>();

    /// Pending service extension requests to this client by id.
    final _pendingServiceExtensionRequests = <dynamic, _PendingServiceRequest>{};

    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) {
      final originalId = request['id'];
      request = Map<String, Object?>.of(request);
      // Modify the request ID to ensure we don't have conflicts between
      // multiple clients ids.
      final newId = '\${_nextServiceRequestId++}:\$originalId';
      request['id'] = newId;
      var pendingRequest = _PendingServiceRequest(originalId);
      _pendingServiceExtensionRequests[newId] = pendingRequest;
      _responseSink.add(request);
      return pendingRequest.future;
    }

    void _delegateRequest(Map<String, Object?> request) async {
      try {
        var id = request['id'];
        // Check if this is actually a response to a pending request.
        if (_pendingServiceExtensionRequests.containsKey(id)) {
          final pending = _pendingServiceExtensionRequests[id]!;
          pending.complete(Map<String, Object?>.of(request));
          return;
        }
        final method = request['method'] as String?;
        if (method == null) {
          throw RPCError(
            null, RPCError.kInvalidRequest, 'Invalid Request', request);
        }
        final params = request['params'] as Map<String, dynamic>?;
        late Response response;

        switch(method) {
          case 'registerService':
            $_registerServiceImpl
            break;
    ''');
    methods.forEach((m) {
      if (m.name != 'registerService') {
        gen.writeln("case '${m.name}':");
        if (m.name == 'streamListen') {
          gen.writeln(_streamListenCaseImpl);
        } else if (m.name == 'streamCancel') {
          gen.writeln(_streamCancelCaseImpl);
        } else {
          bool firstParam = true;
          final nullCheck = () {
            final result = firstParam ? '!' : '';
            if (firstParam) {
              firstParam = false;
            }
            return result;
          };
          gen.write("response = await _serviceImplementation.${m.name}(");
          // Positional args
          m.args.where((arg) => !arg.optional).forEach((MethodArg arg) {
            if (arg.type.isArray) {
              gen.write(
                  "${arg.type.listCreationRef}.from(params${nullCheck()}['${arg.name}'] ?? []), ");
            } else {
              gen.write("params${nullCheck()}['${arg.name}'], ");
            }
          });
          // Optional named args
          var namedArgs = m.args.where((arg) => arg.optional);
          if (namedArgs.isNotEmpty) {
            namedArgs.forEach((arg) {
              if (arg.name == 'scope') {
                gen.writeln(
                    "${arg.name}: params${nullCheck()}['${arg.name}']?.cast<String, String>(), ");
              } else {
                gen.writeln(
                    "${arg.name}: params${nullCheck()}['${arg.name}'], ");
              }
            });
          }
          gen.writeln(");");
        }
        gen.writeln('break;');
      }
    });
    // Handle service extensions
    gen.writeln('default:');
    gen.writeln('''
        final 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.
          final args = params == null ? null : Map<String, dynamic>.of(params);
          final isolateId = args?.remove('isolateId');
          response = await _serviceImplementation.callServiceExtension(method,
              isolateId: isolateId, args: args);
        } else {
          throw RPCError(method, RPCError.kMethodNotFound, 'Method not found', request);
        }
''');
    // Terminate the switch
    gen.writeln('}');

    // Generate the json success response
    gen.write("""_responseSink.add({
  'jsonrpc': '2.0',
  'id': id,
  'result': response.toJson(),
});
""");

    // Close the try block, handle errors
    gen.write(r'''
      } catch (e, st) {
        final error = e is RPCError
            ? e.toMap()
            : {
                'code': RPCError.kInternalError,
                'message': '${request['method']}: $e',
                'data': {'details': '$st'},
              };
        _responseSink.add({
          'jsonrpc': '2.0',
          'id': request['id'],
          'error': error,
        });
      }
''');

    // terminate the _delegateRequest method
    gen.write('}');
    gen.writeln();

    gen.write('}');
    gen.writeln();

    // The client side service implementation.
    gen.writeStatement('class VmService implements VmServiceInterface {');
    gen.writeStatement('late final StreamSubscription _streamSub;');
    gen.writeStatement('late final Function _writeMessage;');
    gen.writeStatement('int _id = 0;');
    gen.writeStatement('Map<String, Completer> _completers = {};');
    gen.writeStatement('Map<String, String> _methodCalls = {};');
    gen.writeStatement('Map<String, ServiceCallback> _services = {};');
    gen.writeStatement('late final Log _log;');
    gen.write('''

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;
}

late final 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;
''');

    // streamCategories
    streamCategories.forEach((s) => s.generate(gen));

    gen.writeln();
    methods.forEach((m) => m.generate(gen));
    gen.out(_implCode);
    gen.writeStatement('}');
    gen.writeln();
    gen.out(_rpcError);
    gen.writeln('// enums');
    enums.forEach((e) {
      if (e.name == 'EventKind') {
        _generateEventStream(gen);
      }
      e.generate(gen);
    });
    gen.writeln();
    gen.writeln('// types');
    types.where((t) => !t!.skip).forEach((t) => t!.generate(gen));
  }

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

// This is a generated file.

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

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

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

bool assertBool(bool obj) {
  return obj;
}

int assertInt(int obj) {
  return obj;
}

double assertDouble(double obj) {
  return obj;
}

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

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

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

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

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

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

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

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

''');
    for (Enum e in enums) {
      e.generateAssert(gen);
    }
    for (Type? type in types) {
      if (type!.name == 'Success') continue;
      type.generateAssert(gen);
      if (type.name!.endsWith('Ref') ||
          [
            'BoundVariable',
            'Breakpoint',
            'ClassHeapStats',
            'CodeRegion',
            'ContextElement',
            'CpuSample',
            'Flag',
            'Frame',
            'InboundReference',
            'LibraryDependency',
            'Message',
            'ProcessMemoryItem',
            'ProfileFunction',
            'ProcessMemoryItem',
            'Protocol',
            'RetainingObject',
            'SourceReportRange',
            'TimelineEvent',
          ].contains(type.name)) {
        type.generateListAssert(gen);
      }
    }
  }

  void setDefaultValue(String typeName, String fieldName, String defaultValue) {
    types
        .firstWhere((t) => t!.name == typeName)!
        .fields
        .firstWhere((f) => f.name == fieldName)
        .defaultValue = defaultValue;
  }

  bool isEnumName(String? typeName) =>
      enums.any((Enum e) => e.name == typeName);

  Type? getType(String? name) =>
      types.firstWhere((t) => t!.name == name, orElse: () => null);

  void _parseStreamListenDocs(String docs) {
    Iterator<String> lines = docs.split('\n').map((l) => l.trim()).iterator;
    bool inStreamDef = false;

    while (lines.moveNext()) {
      final String line = lines.current;

      if (line.startsWith('streamId |')) {
        inStreamDef = true;
        lines.moveNext();
      } else if (inStreamDef) {
        if (line.isEmpty) {
          inStreamDef = false;
        } else {
          streamCategories.add(StreamCategory(line));
        }
      }
    }
  }

  void _generateEventStream(DartGenerator gen) {
    gen.writeln();
    gen.writeDocs('An enum of available event streams.');
    gen.writeln('class EventStreams {');
    gen.writeln('EventStreams._();');
    gen.writeln();

    streamCategories.forEach((c) {
      gen.writeln("static const String k${c.name} = '${c.name}';");
    });

    gen.writeln('}');
  }
}

class StreamCategory {
  String? _name;
  List<String>? _events;

  StreamCategory(String line) {
    // Debug | PauseStart, PauseExit, ...
    _name = line.split('|')[0].trim();

    line = line.split('|')[1];
    _events = line.split(',').map((w) => w.trim()).toList();
  }

  String? get name => _name;

  List<String>? get events => _events;

  void generate(DartGenerator gen) {
    gen.writeln();
    gen.writeln('// ${events!.join(', ')}');
    gen.writeln(
        "Stream<Event> get on${name}Event => _getEventController('$name').stream;");
  }

  String toString() => '$name: $events';
}

class Method extends Member {
  final String name;
  final String? docs;

  MemberType returnType = MemberType();
  List<MethodArg> args = [];

  Method(this.name, String definition, [this.docs]) {
    _parse(Tokenizer(definition).tokenize());
  }

  bool get hasArgs => args.isNotEmpty;

  bool get hasOptionalArgs => args.any((MethodArg arg) => arg.optional);

  void generate(DartGenerator gen) {
    generateDefinition(gen, withDocs: false, withOverrides: true);
    if (!hasArgs) {
      gen.writeStatement("=> _call('${name}');");
    } else if (hasOptionalArgs) {
      gen.writeStatement("=> _call('$name', {");
      gen.write(args
          .where((MethodArg a) => !a.optional)
          .map((arg) => "'${arg.name}': ${arg.name},")
          .join());

      args.where((MethodArg a) => a.optional).forEach((MethodArg arg) {
        String? valueRef = arg.name;
        // Special case for `getAllocationProfile`. We do not want to add these
        // params if they are false.
        if (name == 'getAllocationProfile') {
          gen.writeln("if (${arg.name} != null && ${arg.name})");
        } else {
          gen.writeln("if (${arg.name} != null)");
        }
        gen.writeln("'${arg.name}': $valueRef,");
      });

      gen.writeln('});');
    } else {
      gen.write("=> _call('${name}', {");
      gen.write(args.map((MethodArg arg) {
        return "'${arg.name}': ${arg.name}";
      }).join(', '));
      gen.writeStatement('});');
    }
  }

  /// Writes the method definition without the body.
  ///
  /// Does not write an opening or closing bracket, or a trailing semicolon.
  ///
  /// If [withOverrides] is `true` then it will add an `@override` annotation
  /// before each method.
  void generateDefinition(DartGenerator gen,
      {bool withDocs = true, bool withOverrides = false}) {
    gen.writeln();
    if (withDocs && docs != null) {
      String _docs = docs == null ? '' : docs!;
      if (returnType.isMultipleReturns) {
        _docs += '\n\nThe return value can be one of '
            '${joinLast(returnType.types.map((t) => '[${t}]'), ', ', ' or ')}.';
        _docs = _docs.trim();
      }
      if (returnType.canReturnSentinel) {
        _docs +=
            '\n\nThis method will throw a [SentinelException] in the case a [Sentinel] is returned.';
        _docs = _docs.trim();
      }
      if (_docs.isNotEmpty) gen.writeDocs(_docs);
    }
    if (withOverrides) gen.writeln('@override');
    gen.write('Future<${returnType.name}> ${name}(');
    bool startedOptional = false;
    gen.write(args.map((MethodArg arg) {
      String? typeName;
      if (api.isEnumName(arg.type.name)) {
        if (arg.type.isArray) {
          typeName = typeName = '/*${arg.type}*/ List<String>';
        } else {
          typeName = '/*${arg.type}*/ String';
        }
      } else {
        typeName = arg.type.ref;
      }
      final nullable = arg.optional ? '?' : '';
      if (arg.optional && !startedOptional) {
        startedOptional = true;
        return '{${typeName}$nullable ${arg.name}';
      } else {
        return '${typeName}$nullable ${arg.name}';
      }
    }).join(', '));
    if (args.length >= 4) gen.write(',');
    if (startedOptional) gen.write('}');
    gen.write(') ');
  }

  void _parse(Token? token) => MethodParser(token).parseInto(this);
}

class MemberType extends Member {
  List<TypeRef> types = [];

  MemberType();

  void parse(Parser parser, {bool isReturnType = false}) {
    // foo|bar[]|baz
    // (@Instance|Sentinel)[]
    bool loop = true;
    this.isReturnType = isReturnType;

    while (loop) {
      if (parser.consume('(')) {
        while (parser.peek()!.text != ')') {
          // @Instance | Sentinel
          parser.advance();
        }
        parser.consume(')');
        TypeRef ref = TypeRef('dynamic');
        while (parser.consume('[')) {
          parser.expect(']');
          ref.arrayDepth++;
        }
        types.add(ref);
      } else {
        Token t = parser.expectName();
        TypeRef ref = TypeRef(_coerceRefType(t.text));
        while (parser.consume('[')) {
          parser.expect(']');
          ref.arrayDepth++;
        }
        if (isReturnType && ref.name == 'Sentinel') {
          canReturnSentinel = true;
        } else {
          types.add(ref);
        }
      }

      loop = parser.consume('|');
    }
  }

  String? get name {
    if (types.isEmpty) return '';
    if (types.length == 1) return types.first.ref;
    if (isReturnType) return 'Response';
    return 'dynamic';
  }

  bool isReturnType = false;
  bool canReturnSentinel = false;

  bool get isMultipleReturns => types.length > 1;

  bool get isSimple => types.length == 1 && types.first.isSimple;

  bool get isEnum => types.length == 1 && api.isEnumName(types.first.name);

  bool get isArray => types.length == 1 && types.first.isArray;

  void generate(DartGenerator gen) => gen.write(name!);
}

class TypeRef {
  String? name;
  int arrayDepth = 0;
  List<TypeRef>? genericTypes;

  TypeRef(this.name);

  String? get ref {
    if (arrayDepth == 2) {
      return 'List<List<${name}>>';
    } else if (arrayDepth == 1) {
      return 'List<${name}>';
    } else if (genericTypes != null) {
      return '$name<${genericTypes!.join(', ')}>';
    } else {
      return name!.startsWith('_') ? name!.substring(1) : name;
    }
  }

  String get listCreationRef {
    assert(arrayDepth == 1);

    if (isListTypeSimple) {
      return 'List<$name>';
    } else {
      return 'List<String>';
    }
  }

  String? get listTypeArg => arrayDepth == 2 ? 'List<$name>' : name;

  bool get isArray => arrayDepth > 0;

  bool get isSimple =>
      arrayDepth == 0 &&
      (name == 'int' ||
          name == 'num' ||
          name == 'String' ||
          name == 'bool' ||
          name == 'double' ||
          name == 'ByteData');

  bool get isListTypeSimple =>
      arrayDepth == 1 &&
      (name == 'int' ||
          name == 'num' ||
          name == 'String' ||
          name == 'bool' ||
          name == 'double' ||
          name == 'ByteData');

  String toString() => ref!;
}

class MethodArg extends Member {
  final Method parent;
  TypeRef type;
  String? name;
  bool optional = false;

  MethodArg(this.parent, this.type, this.name);

  void generate(DartGenerator gen) {
    gen.write('${type.ref} ${name}');
  }

  String toString() => '$type $name';
}

class Type extends Member {
  final Api parent;
  String? rawName;
  String? name;
  String? superName;
  final String? docs;
  List<TypeField> fields = [];

  Type(this.parent, String categoryName, String definition, [this.docs]) {
    _parse(Tokenizer(definition).tokenize());
  }

  Type._(this.parent, this.rawName, this.name, this.superName, this.docs);

  factory Type.merge(Type t1, Type t2) {
    final Api parent = t1.parent;
    final String? rawName = t1.rawName;
    final String? name = t1.name;
    final String? superName = t1.superName;
    final String docs = [t1.docs, t2.docs].where((e) => e != null).join('\n');
    final Map<String?, TypeField> map = <String?, TypeField>{};
    for (TypeField f in t2.fields.reversed) {
      map[f.name] = f;
    }
    // The official service.md is the default
    for (TypeField f in t1.fields.reversed) {
      map[f.name] = f;
    }

    final fields = map.values.toList().reversed.toList();

    return Type._(parent, rawName, name, superName, docs)..fields = fields;
  }

  bool get isResponse {
    if (superName == null) return false;
    if (name == 'Response' || superName == 'Response') return true;
    return parent.getType(superName)!.isResponse;
  }

  bool get isRef => name!.endsWith('Ref');

  bool get supportsIdentity {
    if (fields.any((f) => f.name == 'id')) return true;
    return superName == null ? false : getSuper()!.supportsIdentity;
  }

  Type? getSuper() => superName == null ? null : api.getType(superName);

  List<TypeField> getAllFields() {
    if (superName == null) return fields;

    List<TypeField> all = [];
    all.insertAll(0, fields);

    Type? s = getSuper();
    while (s != null) {
      all.insertAll(0, s.fields);
      s = s.getSuper();
    }

    return all;
  }

  bool get skip => name == 'ExtensionData';

  void generate(DartGenerator gen) {
    gen.writeln();
    if (docs != null) gen.writeDocs(docs);
    gen.write('class ${name} ');
    Type? superType;
    if (superName != null) {
      superType = parent.getType(superName);
      gen.write('extends ${superName} ');
    }
    if (parent.getType('${name}Ref') != null) {
      gen.write('implements ${name}Ref ');
    }
    gen.writeln('{');
    gen.writeln('static ${name}? parse(Map<String, dynamic>? json) => '
        'json == null ? null : ${name}._fromJson(json);');
    gen.writeln();

    if (name == 'Response' || name == 'TimelineEvent') {
      gen.writeln('Map<String, dynamic>? json;');
    }
    if (name == 'Script') {
      gen.writeln('final _tokenToLine = <int, int>{};');
      gen.writeln('final _tokenToColumn = <int, int>{};');
    }

    // fields
    fields.forEach((TypeField field) => field.generate(gen));
    gen.writeln();

    // ctors

    bool hasRequiredParentFields = superType != null &&
        (superType.name == 'ObjRef' || superType.name == 'Obj');
    // Default
    gen.write('${name}(');
    if (fields.isNotEmpty) {
      gen.write('{');
      fields.where((field) => !field.optional).forEach((field) {
        final fromParent = (name == 'Instance' && field.name == 'classRef');
        field.generateNamedParameter(gen, fromParent: fromParent);
      });
      if (hasRequiredParentFields) {
        superType.fields.where((field) => !field.optional).forEach(
            (field) => field.generateNamedParameter(gen, fromParent: true));
      }
      fields
          .where((field) => field.optional)
          .forEach((field) => field.generateNamedParameter(gen));
      gen.write('}');
    }
    gen.write(')');
    if (hasRequiredParentFields) {
      gen.write(' : super(');
      superType.fields.where((field) => !field.optional).forEach((field) {
        String? name = field.generatableName;
        gen.writeln('$name: $name,');
      });
      if (name == 'Instance') {
        gen.writeln('classRef: classRef,');
      }
      gen.write(')');
    } else if (name!.contains('NullVal')) {
      gen.writeln(' : super(');
      gen.writeln("id: 'instance/null',");
      gen.writeln('kind: InstanceKind.kNull,');
      gen.writeln("classRef: ClassRef(id: 'class/null',");
      gen.writeln("name: 'Null',),");
      gen.writeln(')');
    }

    gen.writeln(';');

    // Build from JSON.
    gen.writeln();
    String superCall = superName == null ? '' : ": super._fromJson(json) ";
    if (name == 'Response' || name == 'TimelineEvent') {
      gen.write('${name}._fromJson(this.json)');
    } else {
      gen.write('${name}._fromJson(Map<String, dynamic> json) ${superCall}');
    }

    if (fields.isEmpty) {
      gen.writeln(';');
    } else {
      gen.writeln('{');
    }

    fields.forEach((TypeField field) {
      if (field.type.isSimple || field.type.isEnum) {
        // Special case `AllocationProfile`.
        if (name == 'AllocationProfile' && field.type.name == 'int') {
          gen.write(
              "${field.generatableName} = json['${field.name}'] is String ? "
              "int.parse(json['${field.name}']) : json['${field.name}']");
        } else {
          gen.write("${field.generatableName} = json['${field.name}']");
        }
        if (field.defaultValue != null) {
          gen.write(' ?? ${field.defaultValue}');
        } else if (!field.optional) {
          // If a default isn't provided and the field is required, generate a
          // sane default initializer to avoid TypeErrors at runtime when
          // running in a null-safe context.
          dynamic defaultValue;
          switch (field.type.name) {
            case 'int':
            case 'num':
            case 'double':
              defaultValue = -1;
              break;
            case 'bool':
              defaultValue = false;
              break;
            case 'String':
              defaultValue = "''";
              break;
            case 'ByteData':
              defaultValue = "ByteData(0)";
              break;
            default:
              {
                if (field.type.isEnum) {
                  // TODO(bkonyi): Figure out if there's a more correct way to
                  // determine a default value for enums.
                  defaultValue = "''";
                }
                break;
              }
          }
          gen.write(' ?? $defaultValue');
        }
        gen.writeln(';');
        // } else if (field.type.isEnum) {
        //   // Parse the enum.
        //   String enumTypeName = field.type.types.first.name;
        //   gen.writeln(
        //     "${field.generatableName} = _parse${enumTypeName}[json['${field.name}']];");
      } else if (name == 'Event' && field.name == 'extensionData') {
        // Special case `Event.extensionData`.
        gen.writeln(
            "extensionData = ExtensionData.parse(json['extensionData']);");
      } else if (name == 'Instance') {
        if (field.name == 'associations') {
          // Special case `Instance.associations`.
          gen.writeln("associations = json['associations'] == null "
              "? null : List<MapAssociation>.from("
              "_createSpecificObject(json['associations'], MapAssociation.parse));");
        } else if (field.name == 'classRef') {
          // This is populated by `Obj`
        }
      } else if (name == '_CpuProfile' && field.name == 'codes') {
        // Special case `_CpuProfile.codes`.
        gen.writeln("codes = List<CodeRegion>.from("
            "_createSpecificObject(json['codes']!, CodeRegion.parse));");
      } else if (name == '_CpuProfile' && field.name == 'functions') {
        // Special case `_CpuProfile.functions`.
        gen.writeln("functions = List<ProfileFunction>.from("
            "_createSpecificObject(json['functions']!, ProfileFunction.parse));");
      } else if (name == 'SourceReport' && field.name == 'ranges') {
        // Special case `SourceReport.ranges`.
        gen.writeln("ranges = List<SourceReportRange>.from("
            "_createSpecificObject(json['ranges']!, SourceReportRange.parse));");
      } else if (name == 'SourceReportRange' && field.name == 'coverage') {
        // Special case `SourceReportRange.coverage`.
        gen.writeln("coverage = _createSpecificObject("
            "json['coverage']!, SourceReportCoverage.parse);");
      } else if (name == 'Library' && field.name == 'dependencies') {
        // Special case `Library.dependencies`.
        gen.writeln("dependencies = List<LibraryDependency>.from("
            "_createSpecificObject(json['dependencies']!, "
            "LibraryDependency.parse));");
      } else if (name == 'Script' && field.name == 'tokenPosTable') {
        // Special case `Script.tokenPosTable`.
        gen.write("tokenPosTable = ");
        if (field.optional) {
          gen.write("json['tokenPosTable'] == null ? null : ");
        }
        gen.writeln("List<List<int>>.from(json['tokenPosTable']!.map"
            "((dynamic list) => List<int>.from(list)));");
        gen.writeln('_parseTokenPosTable();');
      } else if (field.type.isArray) {
        TypeRef fieldType = field.type.types.first;
        String typesList = _typeRefListToString(field.type.types);
        String ref = "json['${field.name}']";
        if (field.optional) {
          if (fieldType.isListTypeSimple) {
            gen.writeln("${field.generatableName} = $ref == null ? null : "
                "List<${fieldType.listTypeArg}>.from($ref);");
          } else {
            gen.writeln("${field.generatableName} = $ref == null ? null : "
                "List<${fieldType.listTypeArg}>.from(createServiceObject($ref, $typesList)! as List);");
          }
        } else {
          if (fieldType.isListTypeSimple) {
            // Special case `ClassHeapStats`. Pre 3.18, responses included keys
            // `new` and `old`. Post 3.18, these will be null.
            if (name == 'ClassHeapStats') {
              gen.writeln("${field.generatableName} = $ref == null ? null : "
                  "List<${fieldType.listTypeArg}>.from($ref);");
            } else {
              gen.writeln("${field.generatableName} = "
                  "List<${fieldType.listTypeArg}>.from($ref);");
            }
          } else {
            // Special case `InstanceSet`. Pre 3.20, instances were sent in a
            // field named 'samples' instead of 'instances'.
            if (name == 'InstanceSet') {
              gen.writeln("${field.generatableName} = "
                  "List<${fieldType.listTypeArg}>.from(createServiceObject(($ref ?? json['samples']!) as List, $typesList)! as List);");
            } else {
              gen.writeln("${field.generatableName} = "
                  "List<${fieldType.listTypeArg}>.from(createServiceObject($ref, $typesList) as List? ?? []);");
            }
          }
        }
      } else {
        String typesList = _typeRefListToString(field.type.types);
        gen.writeln("${field.generatableName} = "
            "createServiceObject(json['${field.name}']${field.optional ? '' : '!'}, "
            "$typesList) as ${field.type.name}${field.optional ? '?' : ''};");
      }
    });
    if (fields.isNotEmpty) {
      gen.writeln('}');
    }
    gen.writeln();

    if (name == 'Script') {
      generateScriptTypeMethods(gen);
    }

    // toJson support, the base Response type is not supported
    if (name == 'Response') {
      gen.writeln("String get type => 'Response';");
      gen.writeln();
      gen.writeln('''
Map<String, dynamic> toJson() {
  final localJson = json;
  final result = localJson == null ? <String, dynamic>{} : Map<String, dynamic>.of(localJson);
  result['type'] = type;
  return result;
}''');
    } else if (name == 'TimelineEvent') {
      // TimelineEvent doesn't have any declared properties as the response is
      // fairly dynamic. Return the json directly.
      gen.writeln('''
          Map<String, dynamic> toJson() {
            final localJson = json;
            final result = localJson == null ? <String, dynamic>{} : Map<String, dynamic>.of(localJson);
            result['type'] = 'TimelineEvent';
            return result;
          }
      ''');
    } else {
      if (isResponse) {
        gen.writeln('@override');
        gen.writeln("String get type => '$name';");
        gen.writeln();
      }

      if (isResponse) {
        gen.writeln('@override');
      }
      gen.writeln('Map<String, dynamic> toJson() {');
      if (superName == null || superName == 'Response') {
        // The base Response type doesn't have a toJson
        gen.writeln('final json = <String, dynamic>{};');
      } else {
        gen.writeln('final json = super.toJson();');
      }

      // Only Response objects have a `type` field, as defined by protocol.
      if (isResponse) {
        // Overwrites "type" from the super class if we had one.
        gen.writeln("json['type'] = type;");
      }

      var requiredFields = fields.where((f) => !f.optional);
      if (requiredFields.isNotEmpty) {
        gen.writeln('json.addAll({');
        requiredFields.forEach((TypeField field) {
          gen.write("'${field.name}': ");
          generateSerializedFieldAccess(field, gen);
          gen.writeln(',');
        });
        gen.writeln('});');
      }

      var optionalFields = fields.where((f) => f.optional);
      optionalFields.forEach((TypeField field) {
        gen.write("_setIfNotNull(json, '${field.name}', ");
        generateSerializedFieldAccess(field, gen);
        gen.writeln(');');
      });
      gen.writeln('return json;');
      gen.writeln('}');
      gen.writeln();
    }

    // equals and hashCode
    if (supportsIdentity) {
      gen.writeStatement('int get hashCode => id.hashCode;');
      gen.writeln();

      gen.writeStatement(
          'operator==(other) => other is ${name} && id == other.id;');
      gen.writeln();
    }

    // toString()
    Iterable<TypeField> toStringFields =
        getAllFields().where((f) => !f.optional);
    if (toStringFields.length <= 7) {
      String properties = toStringFields
          .map(
              (TypeField f) => "${f.generatableName}: \${${f.generatableName}}")
          .join(', ');
      if (properties.length > 60) {
        int index = properties.indexOf(', ', 55);
        if (index != -1) {
          properties = properties.substring(0, index + 2) +
              "' //\n'" +
              properties.substring(index + 2);
        }
        gen.writeln("String toString() => '[${name} ' //\n'${properties}]';");
      } else {
        final formattedProperties = (properties.isEmpty) ? '' : ' $properties';
        gen.writeln("String toString() => '[$name$formattedProperties]';");
      }
    } else {
      gen.writeln("String toString() => '[${name}]';");
    }

    gen.writeln('}');
  }

  // Special methods for Script objects.
  void generateScriptTypeMethods(DartGenerator gen) {
    gen.writeDocs('''This function maps a token position to a line number.
The VM considers the first line to be line 1.''');
    gen.writeln(
        'int? getLineNumberFromTokenPos(int tokenPos) => _tokenToLine[tokenPos];');
    gen.writeln();
    gen.writeDocs('''This function maps a token position to a column number.
The VM considers the first column to be column 1.''');
    gen.writeln(
        'int? getColumnNumberFromTokenPos(int tokenPos) => _tokenToColumn[tokenPos];');
    gen.writeln();
    gen.writeln('''
void _parseTokenPosTable() {
  final tokenPositionTable = tokenPosTable;
  if (tokenPositionTable == null) {
    return;
  }
  final lineSet = <int>{};
  for (List line in tokenPositionTable) {
    // 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;
    }
  }
}''');
  }

  // Writes the code to retrieve the serialized value of a field.
  void generateSerializedFieldAccess(TypeField field, DartGenerator gen) {
    var nullAware = field.optional ? '?' : '';
    if (field.type.isSimple || field.type.isEnum) {
      gen.write('${field.generatableName}');
      if (field.defaultValue != null) {
        gen.write(' ?? ${field.defaultValue}');
      }
    } else if (name == 'Event' && field.name == 'extensionData') {
      // Special case `Event.extensionData`.
      gen.writeln('extensionData$nullAware.data');
    } else if (field.type.isArray) {
      gen.write('${field.generatableName}$nullAware.map((f) => f');
      // Special case `tokenPosTable` which is a List<List<int>>.
      if (field.name == 'tokenPosTable') {
        gen.write('.toList()');
      } else if (!field.type.types.first.isListTypeSimple) {
        gen.write('.toJson()');
      }
      gen.write(').toList()');
    } else {
      gen.write('${field.generatableName}$nullAware.toJson()');
    }
  }

  void generateAssert(DartGenerator gen) {
    gen.writeln('vms.${name} assert${name}(vms.${name} obj) {');
    gen.writeln('assertNotNull(obj);');
    for (TypeField field in getAllFields()) {
      if (!field.optional) {
        MemberType type = field.type;
        if (type.isArray) {
          TypeRef arrayType = type.types.first;
          if (arrayType.arrayDepth == 1) {
            String assertMethodName = 'assertListOf' +
                arrayType.name!.substring(0, 1).toUpperCase() +
                arrayType.name!.substring(1);
            gen.writeln('$assertMethodName(obj.${field.generatableName});');
          } else {
            gen.writeln(
                '// assert obj.${field.generatableName} is ${type.name}');
          }
        } else if (type.isMultipleReturns) {
          bool first = true;
          for (TypeRef typeRef in type.types) {
            if (!first) gen.write('} else ');
            first = false;
            gen.writeln(
                'if (obj.${field.generatableName} is vms.${typeRef.name}) {');
            String assertMethodName = 'assert' +
                typeRef.name!.substring(0, 1).toUpperCase() +
                typeRef.name!.substring(1);
            gen.writeln('$assertMethodName(obj.${field.generatableName});');
          }
          gen.writeln('} else {');
          gen.writeln(
              'throw "Unexpected value: \${obj.${field.generatableName}}";');
          gen.writeln('}');
        } else {
          String assertMethodName = 'assert' +
              type.name!.substring(0, 1).toUpperCase() +
              type.name!.substring(1);
          gen.writeln('$assertMethodName(obj.${field.generatableName});');
        }
      }
    }
    gen.writeln('return obj;');
    gen.writeln('}');
    gen.writeln('');
  }

  void generateListAssert(DartGenerator gen) {
    gen.writeln('List<vms.${name}> '
        'assertListOf${name}(List<vms.${name}> list) {');
    gen.writeln('for (vms.${name} elem in list) {');
    gen.writeln('assert${name}(elem);');
    gen.writeln('}');
    gen.writeln('return list;');
    gen.writeln('}');
    gen.writeln('');
  }

  void _parse(Token? token) => TypeParser(token).parseInto(this);

  void calculateFieldOverrides() {
    for (TypeField field in fields.toList()) {
      if (superName == null) continue;

      if (getSuper()!.hasField(field.name)) {
        field.setOverrides();
      }
    }
  }

  bool hasField(String? name) {
    if (fields.any((field) => field.name == name)) return true;
    return getSuper()?.hasField(name) ?? false;
  }
}

class TypeField extends Member {
  static final Map<String, String> _nameRemap = {
    'const': 'isConst',
    'final': 'isFinal',
    'static': 'isStatic',
    'abstract': 'isAbstract',
    'super': 'superClass',
    'class': 'classRef',
    'new': 'new_',
  };

  final Type parent;
  final String? _docs;
  MemberType type = MemberType();
  String? name;
  bool optional = false;
  String? defaultValue;
  bool overrides = false;

  TypeField(this.parent, this._docs);

  void setOverrides() => overrides = true;

  String? get docs {
    String str = _docs == null ? '' : _docs!;
    if (type.isMultipleReturns) {
      str += '\n\n[${generatableName}] can be one of '
          '${joinLast(type.types.map((t) => '[${t}]'), ', ', ' or ')}.';
      str = str.trim();
    }
    return str;
  }

  String? get generatableName {
    return _nameRemap[name] != null ? _nameRemap[name] : name;
  }

  void generate(DartGenerator gen) {
    if (docs!.isNotEmpty) gen.writeDocs(docs);
    if (optional) gen.write('@optional ');
    if (overrides) gen.write('@override ');
    // Special case where Instance extends Obj, but 'classRef' is not optional
    // for Instance although it is for Obj.
    if (parent.name == 'Instance' && generatableName == 'classRef') {
      gen.writeStatement('covariant late final ClassRef classRef;');
    } else if (parent.name!.contains('NullVal') &&
        generatableName == 'valueAsString') {
      gen.writeStatement('covariant late final String valueAsString;');
    } else {
      String? typeName =
          api.isEnumName(type.name) ? '/*${type.name}*/ String' : type.name;
      if (optional) {
        typeName = '$typeName?';
      }
      typeName = 'late final $typeName';
      gen.writeStatement('${typeName} ${generatableName};');
      if (parent.fields.any((field) => field.hasDocs)) gen.writeln();
    }
  }

  void generateNamedParameter(DartGenerator gen, {bool fromParent = false}) {
    if (!optional) {
      gen.write('required ');
    }
    if (fromParent) {
      String? typeName =
          api.isEnumName(type.name) ? '/*${type.name}*/ String' : type.name;
      gen.writeStatement('$typeName ${generatableName},');
    } else {
      gen.writeStatement('this.${generatableName},');
    }
  }
}

class Enum extends Member {
  final String name;
  final String? docs;

  List<EnumValue> enums = [];

  Enum(this.name, String definition, [this.docs]) {
    _parse(Tokenizer(definition).tokenize());
  }

  Enum._(this.name, this.docs);

  factory Enum.merge(Enum e1, Enum e2) {
    final String name = e1.name;
    final String docs = [e1.docs, e2.docs].where((e) => e != null).join('\n');
    final Map<String?, EnumValue> map = <String?, EnumValue>{};
    for (EnumValue e in e2.enums.reversed) {
      map[e.name] = e;
    }
    // The official service.md is the default
    for (EnumValue e in e1.enums.reversed) {
      map[e.name] = e;
    }

    final enums = map.values.toList().reversed.toList();

    return Enum._(name, docs)..enums = enums;
  }

  String get prefix =>
      name.endsWith('Kind') ? name.substring(0, name.length - 4) : name;

  void generate(DartGenerator gen) {
    gen.writeln();
    if (docs != null) gen.writeDocs(docs);
    gen.writeStatement('class ${name} {');
    gen.writeStatement('${name}._();');
    gen.writeln();
    enums.forEach((e) => e.generate(gen));
    gen.writeStatement('}');
  }

  void generateAssert(DartGenerator gen) {
    gen.writeln('String assert${name}(String obj) {');
    List<EnumValue> sorted = enums.toList()
      ..sort((EnumValue e1, EnumValue e2) => e1.name!.compareTo(e2.name!));
    for (EnumValue value in sorted) {
      gen.writeln('  if (obj == "${value.name}") return obj;');
    }
    gen.writeln('  throw "invalid ${name}: \$obj";');
    gen.writeln('}');
    gen.writeln('');
  }

  void _parse(Token? token) => EnumParser(token).parseInto(this);
}

class EnumValue extends Member {
  final Enum parent;
  final String? name;
  final String? docs;

  EnumValue(this.parent, this.name, [this.docs]);

  bool get isLast => parent.enums.last == this;

  void generate(DartGenerator gen) {
    if (docs != null) gen.writeDocs(docs);
    gen.writeStatement("static const String k${name} = '${name}';");
  }
}

class TextOutputVisitor implements NodeVisitor {
  static String printText(Node node) {
    TextOutputVisitor visitor = TextOutputVisitor();
    node.accept(visitor);
    return visitor.toString();
  }

  StringBuffer buf = StringBuffer();
  bool _em = false;
  bool _href = false;
  bool _blockquote = false;

  TextOutputVisitor();

  bool visitElementBefore(Element element) {
    if (element.tag == 'em' || element.tag == 'code') {
      buf.write('`');
      _em = true;
    } else if (element.tag == 'p') {
      // Nothing to do.
    } else if (element.tag == 'blockquote') {
      buf.write('```\n');
      _blockquote = true;
    } else if (element.tag == 'a') {
      _href = true;
    } else if (element.tag == 'strong') {
      buf.write('**');
    } else if (element.tag == 'ul') {
      // Nothing to do.
    } else if (element.tag == 'li') {
      buf.write('- ');
    } else {
      throw 'unknown node type: ${element.tag}';
    }

    return true;
  }

  void visitText(Text text) {
    String? t = text.text;
    if (_em) {
      t = _coerceRefType(t);
    } else if (_href) {
      t = '[${_coerceRefType(t)}]';
    }

    if (_blockquote) {
      buf.write('${t}\n```');
    } else {
      buf.write(t);
    }
  }

  void visitElementAfter(Element element) {
    if (element.tag == 'em' || element.tag == 'code') {
      buf.write('`');
      _em = false;
    } else if (element.tag == 'p') {
      buf.write('\n\n');
    } else if (element.tag == 'blockquote') {
      _blockquote = false;
    } else if (element.tag == 'a') {
      _href = false;
    } else if (element.tag == 'strong') {
      buf.write('**');
    } else if (element.tag == 'ul') {
      // Nothing to do.
    } else if (element.tag == 'li') {
      buf.write('\n');
    } else {
      throw 'unknown node type: ${element.tag}';
    }
  }

  String toString() => buf.toString().trim();
}

// @Instance|@Error|Sentinel evaluate(
//     string isolateId,
//     string targetId [optional],
//     string expression)
class MethodParser extends Parser {
  MethodParser(Token? startToken) : super(startToken);

  void parseInto(Method method) {
    // method is return type, name, (, args )
    // args is type name, [optional], comma

    method.returnType.parse(this, isReturnType: true);

    Token t = expectName();
    validate(
        t.text == method.name, 'method name ${method.name} equals ${t.text}');

    expect('(');

    while (peek()!.text != ')') {
      Token type = expectName();
      TypeRef ref = TypeRef(_coerceRefType(type.text));
      if (peek()!.text == '[') {
        while (consume('[')) {
          expect(']');
          ref.arrayDepth++;
        }
      } else if (peek()!.text == '<') {
        // handle generics
        expect('<');
        ref.genericTypes = [];
        while (peek()!.text != '>') {
          Token genericTypeName = expectName();
          ref.genericTypes!.add(TypeRef(_coerceRefType(genericTypeName.text)));
          consume(',');
        }
        expect('>');
      }

      Token name = expectName();
      MethodArg arg = MethodArg(method, ref, name.text);
      if (consume('[')) {
        expect('optional');
        expect(']');
        arg.optional = true;
      }
      method.args.add(arg);
      consume(',');
    }

    expect(')');

    method.args.sort((MethodArg a, MethodArg b) {
      if (!a.optional && b.optional) return -1;
      if (a.optional && !b.optional) return 1;
      return 0;
    });
  }
}

class TypeParser extends Parser {
  TypeParser(Token? startToken) : super(startToken);

  void parseInto(Type type) {
    // class ClassList extends Response {
    //   // Docs here.
    //   @Class[] classes [optional];
    // }
    expect('class');

    Token t = expectName();
    type.rawName = t.text;
    type.name = _coerceRefType(type.rawName);
    if (consume('extends')) {
      t = expectName();
      type.superName = _coerceRefType(t.text);
    }

    expect('{');

    while (peek()!.text != '}') {
      TypeField field = TypeField(type, collectComments());
      field.type.parse(this);
      field.name = expectName().text;
      if (consume('[')) {
        expect('optional');
        expect(']');
        field.optional = true;
      }
      type.fields.add(field);
      expect(';');
    }

    // Special case for Event in order to expose binary response for
    // HeapSnapshot events.
    if (type.rawName == 'Event') {
      final comment = 'Binary data associated with the event.\n\n'
          'This is provided for the event kinds:\n  - HeapSnapshot';
      TypeField dataField = TypeField(type, comment);
      dataField.type.types.add(TypeRef('ByteData'));
      dataField.name = 'data';
      dataField.optional = true;
      type.fields.add(dataField);
    } else if (type.rawName == 'Response') {
      type.fields.removeWhere((field) => field.name == 'type');
    }

    expect('}');
  }
}

class EnumParser extends Parser {
  EnumParser(Token? startToken) : super(startToken);

  void parseInto(Enum e) {
    // enum ErrorKind { UnhandledException, Foo, Bar }
    // enum name { (comment* name ,)+ }
    expect('enum');

    Token t = expectName();
    validate(t.text == e.name, 'enum name ${e.name} equals ${t.text}');
    expect('{');

    while (!t.eof) {
      if (consume('}')) break;
      String? docs = collectComments();
      t = expectName();
      consume(',');

      e.enums.add(EnumValue(e, t.text, docs));
    }
  }
}
