// Copyright (c) 2012, 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;

// ignore: implementation_imports
import 'package:js_ast/src/precedence.dart' as js show Precedence;

import '../common/elements.dart';
import '../constants/values.dart';
import '../elements/entities.dart';
import '../elements/types.dart' show DartType, InterfaceType;
import '../io/source_information.dart';
import '../js/js.dart' as js;
import '../js_backend/backend.dart';
import '../js_backend/codegen_inputs.dart';
import '../js_backend/namer.dart'
    show AsyncName, Namer, operatorNameToIdentifier, StringBackedName;
import '../js_backend/deferred_holder_expression.dart'
    show DeferredHolderExpression;
import '../js_backend/string_reference.dart' show StringReference;
import '../js_backend/type_reference.dart' show TypeReference;
import '../js_emitter/js_emitter.dart' show Emitter;
import '../js_model/elements.dart';
import '../native/behavior.dart';
import '../serialization/serialization.dart';
import '../universe/feature.dart';
import '../universe/resource_identifier.dart' show ResourceIdentifier;
import '../universe/selector.dart';
import '../universe/use.dart' show ConstantUse, DynamicUse, StaticUse, TypeUse;
import '../universe/world_impact.dart' show WorldImpact, WorldImpactBuilderImpl;
import '../util/enumset.dart';
import '../util/util.dart';

class CodegenImpact extends WorldImpact {
  const CodegenImpact();

  factory CodegenImpact.readFromDataSource(DataSourceReader source) =
      _CodegenImpact.readFromDataSource;

  void writeToDataSink(DataSinkWriter sink) {
    throw UnsupportedError('CodegenImpact.writeToDataSink');
  }

  Iterable<(DartType, DartType)> get typeVariableBoundsSubtypeChecks {
    return const <(DartType, DartType)>[];
  }

  Iterable<String> get constSymbols => const <String>[];

  Iterable<Set<ClassEntity>> get specializedGetInterceptors {
    return const <Set<ClassEntity>>[];
  }

  bool get usesInterceptor => false;

  Iterable<AsyncMarker> get asyncMarkers => const <AsyncMarker>[];

  Iterable<GenericInstantiation> get genericInstantiations =>
      const <GenericInstantiation>[];

  Iterable<NativeBehavior> get nativeBehaviors => const [];

  Iterable<FunctionEntity> get nativeMethods => const [];

  Iterable<Selector> get oneShotInterceptors => const [];
}

class _CodegenImpact extends WorldImpactBuilderImpl implements CodegenImpact {
  static const String tag = 'codegen-impact';

  Set<(DartType, DartType)>? _typeVariableBoundsSubtypeChecks;
  Set<String>? _constSymbols;
  List<Set<ClassEntity>>? _specializedGetInterceptors;
  bool _usesInterceptor = false;
  EnumSet<AsyncMarker> _asyncMarkers = EnumSet.empty();
  Set<GenericInstantiation>? _genericInstantiations;
  List<NativeBehavior>? _nativeBehaviors;
  Set<FunctionEntity>? _nativeMethods;
  Set<Selector>? _oneShotInterceptors;

  _CodegenImpact(MemberEntity super.member);

  _CodegenImpact.internal(
    MemberEntity member,
    super.dynamicUses,
    super.staticUses,
    super.typeUses,
    super.constantUses,
    this._typeVariableBoundsSubtypeChecks,
    this._constSymbols,
    this._specializedGetInterceptors,
    this._usesInterceptor,
    this._asyncMarkers,
    this._genericInstantiations,
    this._nativeBehaviors,
    this._nativeMethods,
    this._oneShotInterceptors,
  ) : super.internal(member: member);

  factory _CodegenImpact.readFromDataSource(DataSourceReader source) {
    source.begin(tag);
    MemberEntity member = source.readMember();
    final dynamicUses = source
        .readListOrNull(() => DynamicUse.readFromDataSource(source))
        ?.toSet();
    final staticUses = source
        .readListOrNull(() => StaticUse.readFromDataSource(source))
        ?.toSet();
    final typeUses = source
        .readListOrNull(() => TypeUse.readFromDataSource(source))
        ?.toSet();
    final constantUses = source
        .readListOrNull(() => ConstantUse.readFromDataSource(source))
        ?.toSet();
    final typeVariableBoundsSubtypeChecks = source.readListOrNull(() {
      return (source.readDartType(), source.readDartType());
    })?.toSet();
    final constSymbols = source.readStringsOrNull()?.toSet();
    final specializedGetInterceptors = source.readListOrNull(() {
      return source.readClasses().toSet();
    });
    bool usesInterceptor = source.readBool();
    final asyncMarkersValue = source.readInt();
    final asyncMarkers = EnumSet<AsyncMarker>.fromRawBits(asyncMarkersValue);
    final genericInstantiations = source
        .readListOrNull(() => GenericInstantiation.readFromDataSource(source))
        ?.toSet();
    final nativeBehaviors = source.readListOrNull(
      () => NativeBehavior.readFromDataSource(source),
    );
    final nativeMethods = source.readMembersOrNull<FunctionEntity>()?.toSet();
    final oneShotInterceptors = source
        .readListOrNull(() => Selector.readFromDataSource(source))
        ?.toSet();
    source.end(tag);
    return _CodegenImpact.internal(
      member,
      dynamicUses,
      staticUses,
      typeUses,
      constantUses,
      typeVariableBoundsSubtypeChecks,
      constSymbols,
      specializedGetInterceptors,
      usesInterceptor,
      asyncMarkers,
      genericInstantiations,
      nativeBehaviors,
      nativeMethods,
      oneShotInterceptors,
    );
  }

  @override
  void writeToDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeMember(member);
    sink.writeList(dynamicUses, (DynamicUse use) => use.writeToDataSink(sink));
    sink.writeList(staticUses, (StaticUse use) => use.writeToDataSink(sink));
    sink.writeList(typeUses, (TypeUse use) => use.writeToDataSink(sink));
    sink.writeList(
      constantUses,
      (ConstantUse use) => use.writeToDataSink(sink),
    );
    sink.writeListOrNull<(DartType, DartType)>(
      _typeVariableBoundsSubtypeChecks,
      (pair) {
        sink.writeDartType(pair.$1);
        sink.writeDartType(pair.$2);
      },
    );
    sink.writeStringsOrNull(_constSymbols);
    sink.writeListOrNull(_specializedGetInterceptors, sink.writeClasses);
    sink.writeBool(_usesInterceptor);
    sink.writeInt(_asyncMarkers.mask.bits);
    sink.writeListOrNull(
      _genericInstantiations,
      (GenericInstantiation instantiation) =>
          instantiation.writeToDataSink(sink),
    );
    sink.writeListOrNull(
      _nativeBehaviors,
      (NativeBehavior behavior) => behavior.writeToDataSink(sink),
    );
    sink.writeMembersOrNull(_nativeMethods);
    sink.writeListOrNull(
      _oneShotInterceptors,
      (Selector selector) => selector.writeToDataSink(sink),
    );
    sink.end(tag);
  }

  @override
  MemberEntity get member => super.member!;

  void registerTypeVariableBoundsSubtypeCheck(
    DartType subtype,
    DartType supertype,
  ) {
    (_typeVariableBoundsSubtypeChecks ??= {}).add((subtype, supertype));
  }

  @override
  Iterable<(DartType, DartType)> get typeVariableBoundsSubtypeChecks {
    return _typeVariableBoundsSubtypeChecks ?? const {};
  }

  void registerConstSymbol(String name) {
    (_constSymbols ??= {}).add(name);
  }

  @override
  Iterable<String> get constSymbols {
    return _constSymbols ?? const [];
  }

  void registerSpecializedGetInterceptor(Set<ClassEntity> classes) {
    (_specializedGetInterceptors ??= []).add(classes);
  }

  @override
  Iterable<Set<ClassEntity>> get specializedGetInterceptors {
    return _specializedGetInterceptors ?? const [];
  }

  void registerUseInterceptor() {
    _usesInterceptor = true;
  }

  @override
  bool get usesInterceptor => _usesInterceptor;

  void registerAsyncMarker(AsyncMarker asyncMarker) {
    _asyncMarkers = _asyncMarkers.add(asyncMarker);
  }

  @override
  Iterable<AsyncMarker> get asyncMarkers {
    return _asyncMarkers.isEmpty
        ? const []
        : _asyncMarkers.iterable(AsyncMarker.values);
  }

  void registerGenericInstantiation(GenericInstantiation instantiation) {
    (_genericInstantiations ??= {}).add(instantiation);
  }

  @override
  Iterable<GenericInstantiation> get genericInstantiations {
    return _genericInstantiations ?? const [];
  }

  void registerNativeBehavior(NativeBehavior nativeBehavior) {
    (_nativeBehaviors ??= []).add(nativeBehavior);
  }

  @override
  Iterable<NativeBehavior> get nativeBehaviors {
    return _nativeBehaviors ?? const [];
  }

  void registerNativeMethod(FunctionEntity function) {
    (_nativeMethods ??= {}).add(function);
  }

  @override
  Iterable<FunctionEntity> get nativeMethods {
    return _nativeMethods ?? const [];
  }

  void registerOneShotInterceptor(Selector selector) {
    (_oneShotInterceptors ??= {}).add(selector);
  }

  @override
  Iterable<Selector> get oneShotInterceptors {
    return _oneShotInterceptors ?? const [];
  }

  @override
  String toString() {
    StringBuffer sb = StringBuffer();
    sb.write('CodegenImpact:');
    WorldImpact.printOn(sb, this);

    void add(String title, Iterable<Object?> iterable) {
      if (iterable.isNotEmpty) {
        sb.write('\n $title:');
        for (var e in iterable) {
          sb.write('\n  $e');
        }
      }
    }

    add('typeVariableBoundsSubtypeChecks', typeVariableBoundsSubtypeChecks);
    add('constSymbols', constSymbols);
    add('specializedGetInterceptors', specializedGetInterceptors);
    if (usesInterceptor) {
      sb.write('\n usesInterceptor: true');
    }
    add('asyncMarkers', asyncMarkers);
    add('genericInstantiations', genericInstantiations);
    add('nativeBehaviors', nativeBehaviors);
    add('nativeMethods', nativeMethods);
    add('oneShotInterceptors', oneShotInterceptors);

    return sb.toString();
  }
}

// TODO(johnniwinther): Split this class into interface and implementation.
// TODO(johnniwinther): Move this implementation to the JS backend.
class CodegenRegistry {
  final ElementEnvironment _elementEnvironment;
  final MemberEntity _currentElement;
  final _CodegenImpact _worldImpact;
  late final List<ModularName> _names = [];
  late final List<ModularExpression> _expressions = [];

  CodegenRegistry(this._elementEnvironment, this._currentElement)
    : _worldImpact = _CodegenImpact(_currentElement);

  @override
  String toString() => 'CodegenRegistry for $_currentElement';

  @Deprecated("Use StaticUse for precise registration of statically known use")
  void registerInstantiatedClass(ClassEntity element) {
    registerInstantiation(_elementEnvironment.getRawType(element));
  }

  void registerStaticUse(StaticUse staticUse) {
    _worldImpact.registerStaticUse(staticUse);
  }

  void registerDynamicUse(DynamicUse dynamicUse) {
    _worldImpact.registerDynamicUse(dynamicUse);
  }

  void registerTypeUse(TypeUse typeUse) {
    _worldImpact.registerTypeUse(typeUse);
  }

  void registerConstantUse(ConstantUse constantUse) {
    _worldImpact.registerConstantUse(constantUse);
  }

  void registerTypeVariableBoundsSubtypeCheck(
    DartType subtype,
    DartType supertype,
  ) {
    _worldImpact.registerTypeVariableBoundsSubtypeCheck(subtype, supertype);
  }

  void registerInstantiatedClosure(FunctionEntity element) {
    _worldImpact.registerStaticUse(StaticUse.callMethod(element));
  }

  void registerConstSymbol(String name) {
    _worldImpact.registerConstSymbol(name);
  }

  void registerSpecializedGetInterceptor(Set<ClassEntity> classes) {
    _worldImpact.registerSpecializedGetInterceptor(classes);
  }

  void registerOneShotInterceptor(Selector selector) {
    _worldImpact.registerOneShotInterceptor(selector);
  }

  void registerUseInterceptor() {
    _worldImpact.registerUseInterceptor();
  }

  void registerInstantiation(InterfaceType type) {
    registerTypeUse(TypeUse.instantiation(type));
  }

  void registerAsyncMarker(AsyncMarker asyncMarker) {
    _worldImpact.registerAsyncMarker(asyncMarker);
  }

  void registerGenericInstantiation(GenericInstantiation instantiation) {
    _worldImpact.registerGenericInstantiation(instantiation);
  }

  void registerNativeBehavior(NativeBehavior nativeBehavior) {
    _worldImpact.registerNativeBehavior(nativeBehavior);
  }

  void registerNativeMethod(FunctionEntity function) {
    _worldImpact.registerNativeMethod(function);
  }

  void registerModularName(covariant ModularName name) {
    _names.add(name);
  }

  void registerModularExpression(covariant ModularExpression expression) {
    _expressions.add(expression);
  }

  CodegenResult close(js.Fun? code) {
    return CodegenResult(
      code,
      _worldImpact,
      js.DeferredExpressionData(
        _names.isEmpty ? const [] : _names,
        _expressions.isEmpty ? const [] : _expressions,
      ),
    );
  }
}

/// Code generation results computed on-demand.
///
/// This is used in the non-modular codegen enqueuer driving code generation.
class OnDemandCodegenResults implements CodegenResults {
  @override
  final CodegenInputs codegenInputs;
  final FunctionCompiler _functionCompiler;

  OnDemandCodegenResults(this.codegenInputs, this._functionCompiler);

  @override
  ({CodegenResult result, bool isGenerated}) getCodegenResults(
    MemberEntity member,
  ) {
    return (result: _functionCompiler.compile(member), isGenerated: true);
  }
}

/// The code generation result for a single [MemberEntity].
class CodegenResult {
  static const String tag = 'codegen-result';

  final js.Fun? code;
  final CodegenImpact impact;
  final js.DeferredExpressionData deferredExpressionData;

  CodegenResult(this.code, this.impact, this.deferredExpressionData);

  /// Reads a [CodegenResult] object from [source].
  factory CodegenResult.readFromDataSource(DataSourceReader source) {
    source.begin(tag);
    js.Fun? code = source.readJsNodeOrNull() as js.Fun?;
    CodegenImpact impact = CodegenImpact.readFromDataSource(source);
    final deferredExpressionData =
        js.DeferredExpressionRegistry.readDataFromDataSource(source);
    source.end(tag);
    if (code != null) {
      code = code.withAnnotation(deferredExpressionData) as js.Fun;
    }
    return CodegenResult(code, impact, deferredExpressionData);
  }

  /// Writes the [CodegenResult] object to [sink].
  void writeToDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    final registry = js.DeferredExpressionRegistry();
    sink.withDeferredExpressionRegistry(
      registry,
      () => sink.writeJsNodeOrNull(code),
    );
    impact.writeToDataSink(sink);
    registry.writeToDataSink(sink);
    sink.end(tag);
  }

  void applyModularState(Namer namer, Emitter emitter) {
    final Set<ModularName> updated = Set.identity();
    for (ModularName name in deferredExpressionData.modularNames) {
      if (!updated.add(name)) continue;
      switch (name.kind) {
        case ModularNameKind.rtiField:
          name.value = namer.rtiFieldJsName;
          break;
        case ModularNameKind.className:
          name.value = namer.className(name.data as ClassEntity);
          break;
        case ModularNameKind.aliasedSuperMember:
          name.value = namer.aliasedSuperMemberPropertyName(
            name.data as MemberEntity,
          );
          break;
        case ModularNameKind.staticClosure:
          name.value = namer.staticClosureName(name.data as FunctionEntity);
          break;
        case ModularNameKind.methodProperty:
          name.value = namer.methodPropertyName(name.data as FunctionEntity);
          break;
        case ModularNameKind.operatorIs:
          name.value = namer.operatorIs(name.data as ClassEntity);
          break;
        case ModularNameKind.instanceMethod:
          name.value = namer.instanceMethodName(name.data as FunctionEntity);
          break;
        case ModularNameKind.instanceField:
          name.value = namer.instanceFieldPropertyName(
            name.data as FieldEntity,
          );
          break;
        case ModularNameKind.invocation:
          name.value = namer.invocationName(name.data as Selector);
          break;
        case ModularNameKind.lazyInitializer:
          name.value = namer.lazyInitializerName(name.data as FieldEntity);
          break;
        case ModularNameKind.globalPropertyNameForClass:
          name.value = namer.globalPropertyNameForClass(
            name.data as ClassEntity,
          );
          break;
        case ModularNameKind.globalPropertyNameForMember:
          name.value = namer.globalPropertyNameForMember(
            name.data as MemberEntity,
          );
          break;
        case ModularNameKind.globalNameForInterfaceTypeVariable:
          name.value = namer.globalNameForInterfaceTypeVariable(
            name.data as TypeVariableEntity,
          );
          break;
        case ModularNameKind.nameForGetInterceptor:
          name.value = namer.nameForGetInterceptor(name.set!);
          break;
        case ModularNameKind.nameForOneShotInterceptor:
          name.value = namer.nameForOneShotInterceptor(
            name.data as Selector,
            name.set!,
          );
          break;
        case ModularNameKind.asName:
          name.value = namer.asName(name.data as String);
          break;
      }
    }
    for (ModularExpression expression
        in deferredExpressionData.modularExpressions) {
      switch (expression.kind) {
        case ModularExpressionKind.constant:
          expression.value = emitter
              .constantReference(expression.data as ConstantValue)
              .withSourceInformation(expression.sourceInformation);
          break;
        case ModularExpressionKind.embeddedGlobalAccess:
          expression.value = emitter
              .generateEmbeddedGlobalAccess(expression.data as String)
              .withSourceInformation(expression.sourceInformation);
          break;
      }
    }
  }

  @override
  String toString() {
    StringBuffer sb = StringBuffer();
    sb.write('CodegenResult(code=');
    sb.write(code != null ? js.DebugPrint(code!) : '<null>,');
    sb.write('impact=$impact,');
    sb.write('modularNames=${deferredExpressionData.modularNames},');
    sb.write('modularExpressions=${deferredExpressionData.modularExpressions}');
    sb.write(')');
    return sb.toString();
  }
}

enum ModularExpressionKind { constant, embeddedGlobalAccess }

class ModularExpression extends js.DeferredExpression
    implements js.AstContainer {
  static const String tag = 'modular-expression';

  final ModularExpressionKind kind;
  final Object data;
  js.Expression? _value;

  ModularExpression(this.kind, this.data);

  factory ModularExpression.readFromDataSource(DataSourceReader source) {
    source.begin(tag);
    ModularExpressionKind kind = source.readEnum(ModularExpressionKind.values);
    Object data;
    switch (kind) {
      case ModularExpressionKind.constant:
        data = source.readConstant();
        break;
      case ModularExpressionKind.embeddedGlobalAccess:
        data = source.readString();
        break;
    }
    source.end(tag);
    return ModularExpression(kind, data);
  }

  void writeToDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeEnum(kind);
    switch (kind) {
      case ModularExpressionKind.constant:
        sink.writeConstant(data as ConstantValue);
        break;
      case ModularExpressionKind.embeddedGlobalAccess:
        sink.writeString(data as String);
        break;
    }
    sink.end(tag);
  }

  @override
  bool get isFinalized => _value != null;

  @override
  js.Expression get value {
    return _value!;
  }

  set value(js.Expression node) {
    assert(!isFinalized);
    _value = node.withSourceInformation(sourceInformation);
  }

  @override
  js.Precedence get precedenceLevel =>
      _value?.precedenceLevel ?? js.Precedence.primary;

  @override
  Iterable<js.Node> get containedNodes {
    return _value != null ? [_value!] : const [];
  }

  @override
  int get hashCode {
    return Hashing.objectsHash(kind, data);
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return other is ModularExpression &&
        kind == other.kind &&
        data == other.data;
  }

  @override
  String toString() {
    StringBuffer sb = StringBuffer();
    sb.write('ModularExpression(kind=$kind,data=');
    if (data is ConstantValue) {
      sb.write((data as ConstantValue).toStructuredText(null));
    } else {
      sb.write(data);
    }
    sb.write(',value=$_value)');
    return sb.toString();
  }

  @override
  String nonfinalizedDebugText() {
    switch (kind) {
      case ModularExpressionKind.constant:
        return 'ModularExpression"<constant>"';
      case ModularExpressionKind.embeddedGlobalAccess:
        return 'ModularExpression"init.$data"';
    }
  }
}

enum JsNodeKind {
  comment,
  await,
  regExpLiteral,
  property,
  methodDefinition,
  objectInitializer,
  arrayHole,
  arrayInitializer,
  parentheses,
  modularName,
  asyncName,
  stringBackedName,
  stringConcatenation,
  literalNull,
  literalNumber,
  literalString,
  literalStringFromName,
  literalBool,
  modularExpression,
  function,
  arrowFunction,
  namedFunction,
  access,
  parameter,
  variableDeclaration,
  thisExpression,
  variableUse,
  postfix,
  prefix,
  binary,
  callExpression,
  newExpression,
  conditional,
  variableInitialization,
  assignment,
  variableDeclarationList,
  literalExpression,
  dartYield,
  literalStatement,
  labeledStatement,
  functionDeclaration,
  switchDefault,
  switchCase,
  switchStatement,
  catchClause,
  tryStatement,
  throwStatement,
  returnStatement,
  breakStatement,
  continueStatement,
  doStatement,
  whileStatement,
  forInStatement,
  forStatement,
  ifStatement,
  emptyStatement,
  expressionStatement,
  block,
  program,
  stringReference,
  typeReference,
  deferredHolderExpression,
}

/// Tags used for debugging serialization/deserialization boundary mismatches.
class JsNodeTags {
  static const String tag = 'js-node';
  static const String comment = 'js-comment';
  static const String await = 'js-await';
  static const String regExpLiteral = 'js-regExpLiteral';
  static const String property = 'js-property';
  static const String methodDefinition = 'js-methodDefinition';
  static const String objectInitializer = 'js-objectInitializer';
  static const String arrayHole = 'js-arrayHole';
  static const String arrayInitializer = 'js-arrayInitializer';
  static const String parentheses = 'js-parentheses';
  static const String modularName = 'js-modularName';
  static const String asyncName = 'js-asyncName';
  static const String stringBackedName = 'js-stringBackedName';
  static const String stringConcatenation = 'js-stringConcatenation';
  static const String literalNull = 'js-literalNull';
  static const String literalNumber = 'js-literalNumber';
  static const String literalString = 'js-literalString';
  static const String literalStringFromName = 'js-literalStringFromName';
  static const String literalBool = 'js-literalBool';
  static const String modularExpression = 'js-modularExpression';
  static const String function = 'js-function';
  static const String arrowFunction = 'js-arrowFunction';
  static const String namedFunction = 'js-namedFunction';
  static const String access = 'js-access';
  static const String parameter = 'js-parameter';
  static const String variableDeclaration = 'js-variableDeclaration';
  static const String thisExpression = 'js-thisExpression';
  static const String variableUse = 'js-variableUse';
  static const String postfix = 'js-postfix';
  static const String prefix = 'js-prefix';
  static const String binary = 'js-binary';
  static const String callExpression = 'js-callExpression';
  static const String newExpression = 'js-newExpression';
  static const String conditional = 'js-conditional';
  static const String variableInitialization = 'js-variableInitialization';
  static const String assignment = 'js-assignment';
  static const String variableDeclarationList = 'js-variableDeclarationList';
  static const String literalExpression = 'js-literalExpression';
  static const String dartYield = 'js-dartYield';
  static const String literalStatement = 'js-literalStatement';
  static const String labeledStatement = 'js-labeledStatement';
  static const String functionDeclaration = 'js-functionDeclaration';
  static const String switchDefault = 'js-switchDefault';
  static const String switchCase = 'js-switchCase';
  static const String switchStatement = 'js-switchStatement';
  static const String catchClause = 'js-catchClause';
  static const String tryStatement = 'js-tryStatement';
  static const String throwStatement = 'js-throwStatement';
  static const String returnStatement = 'js-returnStatement';
  static const String breakStatement = 'js-breakStatement';
  static const String continueStatement = 'js-continueStatement';
  static const String doStatement = 'js-doStatement';
  static const String whileStatement = 'js-whileStatement';
  static const String forInStatement = 'js-forInStatement';
  static const String forStatement = 'js-forStatement';
  static const String ifStatement = 'js-ifStatement';
  static const String emptyStatement = 'js-emptyStatement';
  static const String expressionStatement = 'js-expressionStatement';
  static const String block = 'js-block';
  static const String program = 'js-program';
  static const String stringReference = 'js-stringReference';
  static const String typeReference = 'js-typeReference';
  static const String deferredHolderExpression = 'js-deferredHolderExpression';
}

enum JsAnnotationKind { string, resourceIdentifier }

/// Visitor that serializes a [js.Node] into a [DataSinkWriter].
///
/// Collects deferred expressions into [deferredExpressionData] as it encounters
/// them in the AST.
class JsNodeSerializer implements js.NodeVisitor<void> {
  final DataSinkWriter sink;
  final js.DeferredExpressionRegistry? _registry;

  JsNodeSerializer._(this.sink, this._registry);

  static void writeToDataSink(
    DataSinkWriter sink,
    js.Node node,
    js.DeferredExpressionRegistry? registry,
  ) {
    sink.begin(JsNodeTags.tag);
    JsNodeSerializer serializer = JsNodeSerializer._(sink, registry);
    serializer.visit(node);
    sink.end(JsNodeTags.tag);
  }

  void visitOrNull(js.Node? node) {
    final isNotNull = node != null;
    sink.writeBool(isNotNull);
    if (isNotNull) {
      visit(node);
    }
  }

  void visit(js.Node node) {
    node.accept(this);
  }

  void visitList(Iterable<js.Node> nodes) {
    sink.writeList(nodes, visit);
  }

  void _writeInfo(js.Node node) {
    final sourceInformation = node.sourceInformation as SourceInformation?;
    final annotations = node.annotations;
    // Low bit encodes presence of `sourceInformation`, higher bits the number
    // of annotations.
    final infoCode =
        (sourceInformation == null ? 0 : 1) + 2 * annotations.length;
    sink.writeInt(infoCode);
    final hasSourceInformation = infoCode.isOdd;
    final annotationCount = infoCode ~/ 2;
    if (hasSourceInformation) {
      sink.writeIndexed<SourceInformation>(sourceInformation, (
        SourceInformation sourceInformation,
      ) {
        SourceInformation.writeToDataSink(sink, sourceInformation);
      });
    }
    for (int i = 0; i < annotationCount; i++) {
      _writeAnnotation(annotations[i]);
    }
  }

  void _writeAnnotation(Object annotation) {
    if (annotation is String) {
      sink.writeEnum(JsAnnotationKind.string);
      sink.writeString(annotation);
    } else if (annotation is ResourceIdentifier) {
      sink.writeEnum(JsAnnotationKind.resourceIdentifier);
      annotation.writeToDataSink(sink);
    } else {
      throw UnsupportedError(
        'JsNodeAnnotation ${annotation.runtimeType}: $annotation',
      );
    }
  }

  @override
  void visitInterpolatedDeclaration(js.InterpolatedDeclaration node) {
    throw UnsupportedError('JsNodeSerializer.visitInterpolatedDeclaration');
  }

  @override
  void visitInterpolatedStatement(js.InterpolatedStatement node) {
    throw UnsupportedError('JsNodeSerializer.visitInterpolatedStatement');
  }

  @override
  void visitInterpolatedSelector(js.InterpolatedSelector node) {
    throw UnsupportedError('JsNodeSerializer.visitInterpolatedDeclaration');
  }

  @override
  void visitInterpolatedParameter(js.InterpolatedParameter node) {
    throw UnsupportedError('JsNodeSerializer.visitInterpolatedParameter');
  }

  @override
  void visitInterpolatedLiteral(js.InterpolatedLiteral node) {
    throw UnsupportedError('JsNodeSerializer.visitInterpolatedLiteral');
  }

  @override
  void visitInterpolatedExpression(js.InterpolatedExpression node) {
    throw UnsupportedError('JsNodeSerializer.visitInterpolatedExpression');
  }

  @override
  void visitComment(js.Comment node) {
    sink.writeEnum(JsNodeKind.comment);
    sink.begin(JsNodeTags.comment);
    sink.writeString(node.comment);
    sink.end(JsNodeTags.comment);
    _writeInfo(node);
  }

  @override
  void visitAwait(js.Await node) {
    sink.writeEnum(JsNodeKind.await);
    sink.begin(JsNodeTags.await);
    visit(node.expression);
    sink.end(JsNodeTags.await);
    _writeInfo(node);
  }

  @override
  void visitRegExpLiteral(js.RegExpLiteral node) {
    sink.writeEnum(JsNodeKind.regExpLiteral);
    sink.begin(JsNodeTags.regExpLiteral);
    sink.writeString(node.pattern);
    sink.end(JsNodeTags.regExpLiteral);
    _writeInfo(node);
  }

  @override
  void visitProperty(js.Property node) {
    sink.writeEnum(JsNodeKind.property);
    sink.begin(JsNodeTags.property);
    visit(node.name);
    visit(node.value);
    sink.end(JsNodeTags.property);
    _writeInfo(node);
  }

  @override
  void visitMethodDefinition(js.MethodDefinition node) {
    sink.writeEnum(JsNodeKind.methodDefinition);
    sink.begin(JsNodeTags.methodDefinition);
    visit(node.name);
    visit(node.function);
    sink.end(JsNodeTags.methodDefinition);
    _writeInfo(node);
  }

  @override
  void visitObjectInitializer(js.ObjectInitializer node) {
    sink.writeEnum(JsNodeKind.objectInitializer);
    sink.begin(JsNodeTags.objectInitializer);
    visitList(node.properties);
    sink.writeBool(node.isOneLiner);
    sink.end(JsNodeTags.objectInitializer);
    _writeInfo(node);
  }

  @override
  void visitArrayHole(js.ArrayHole node) {
    sink.writeEnum(JsNodeKind.arrayHole);
    sink.begin(JsNodeTags.arrayHole);
    sink.end(JsNodeTags.arrayHole);
    _writeInfo(node);
  }

  @override
  void visitArrayInitializer(js.ArrayInitializer node) {
    sink.writeEnum(JsNodeKind.arrayInitializer);
    sink.begin(JsNodeTags.arrayInitializer);
    visitList(node.elements);
    sink.end(JsNodeTags.arrayInitializer);
    _writeInfo(node);
  }

  @override
  void visitParentheses(js.Parentheses node) {
    sink.writeEnum(JsNodeKind.parentheses);
    sink.begin(JsNodeTags.parentheses);
    visit(node.enclosed);
    sink.end(JsNodeTags.parentheses);
    _writeInfo(node);
  }

  @override
  void visitName(js.Name node) {
    if (node is ModularName) {
      sink.writeEnum(JsNodeKind.modularName);
      sink.begin(JsNodeTags.modularName);
      sink.writeIndexed<ModularName>(node, (_) {
        node.writeToDataSink(sink);
        _writeInfo(node);
      }, identity: true);
      _registry?.registerModularName(node);
      sink.end(JsNodeTags.modularName);
    } else if (node is AsyncName) {
      sink.writeEnum(JsNodeKind.asyncName);
      sink.begin(JsNodeTags.asyncName);
      visit(node.prefix);
      visit(node.base);
      sink.end(JsNodeTags.asyncName);
      _writeInfo(node);
    } else if (node is StringBackedName) {
      sink.writeEnum(JsNodeKind.stringBackedName);
      sink.begin(JsNodeTags.stringBackedName);
      sink.writeString(node.name);
      sink.end(JsNodeTags.stringBackedName);
      _writeInfo(node);
    } else {
      throw UnsupportedError(
        'Unexpected deferred expression: ${node.runtimeType}.',
      );
    }
  }

  @override
  void visitStringConcatenation(js.StringConcatenation node) {
    sink.writeEnum(JsNodeKind.stringConcatenation);
    sink.begin(JsNodeTags.stringConcatenation);
    visitList(node.parts);
    sink.end(JsNodeTags.stringConcatenation);
    _writeInfo(node);
  }

  @override
  void visitLiteralNull(js.LiteralNull node) {
    sink.writeEnum(JsNodeKind.literalNull);
    sink.begin(JsNodeTags.literalNull);
    sink.end(JsNodeTags.literalNull);
    _writeInfo(node);
  }

  @override
  void visitLiteralNumber(js.LiteralNumber node) {
    sink.writeEnum(JsNodeKind.literalNumber);
    sink.begin(JsNodeTags.literalNumber);
    sink.writeString(node.value);
    sink.end(JsNodeTags.literalNumber);
    _writeInfo(node);
  }

  @override
  void visitLiteralString(js.LiteralString node) {
    if (node is js.LiteralStringFromName) {
      sink.writeEnum(JsNodeKind.literalStringFromName);
      sink.begin(JsNodeTags.literalStringFromName);
      visit(node.name);
      sink.end(JsNodeTags.literalStringFromName);
    } else {
      sink.writeEnum(JsNodeKind.literalString);
      sink.begin(JsNodeTags.literalString);
      sink.writeString(node.value);
      sink.end(JsNodeTags.literalString);
    }
    _writeInfo(node);
  }

  @override
  void visitLiteralBool(js.LiteralBool node) {
    sink.writeEnum(JsNodeKind.literalBool);
    sink.begin(JsNodeTags.literalBool);
    sink.writeBool(node.value);
    sink.end(JsNodeTags.literalBool);
    _writeInfo(node);
  }

  @override
  void visitDeferredString(js.DeferredString node) {
    throw UnsupportedError('JsNodeSerializer.visitDeferredString');
  }

  @override
  void visitDeferredStatement(js.DeferredStatement node) {
    throw UnsupportedError('JsNodeSerializer.visitDeferredStatement');
  }

  @override
  void visitDeferredNumber(js.DeferredNumber node) {
    throw UnsupportedError('JsNodeSerializer.visitDeferredNumber');
  }

  @override
  void visitDeferredExpression(js.DeferredExpression node) {
    if (node is ModularExpression) {
      sink.writeEnum(JsNodeKind.modularExpression);
      sink.begin(JsNodeTags.modularExpression);
      sink.writeIndexed<ModularExpression>(node, (_) {
        node.writeToDataSink(sink);
        _writeInfo(node);
      }, identity: true);
      _registry?.registerModularExpression(node);
      sink.end(JsNodeTags.modularExpression);
    } else if (node is TypeReference) {
      sink.writeEnum(JsNodeKind.typeReference);
      sink.begin(JsNodeTags.typeReference);
      sink.writeIndexed<TypeReference>(node, (_) {
        node.writeToDataSink(sink);
        _writeInfo(node);
      }, identity: true);
      _registry?.registerTypeReference(node);
      sink.end(JsNodeTags.typeReference);
    } else if (node is StringReference) {
      sink.writeEnum(JsNodeKind.stringReference);
      sink.begin(JsNodeTags.stringReference);
      sink.writeIndexed<StringReference>(node, (_) {
        node.writeToDataSink(sink);
        _writeInfo(node);
      }, identity: true);
      _registry?.registerStringReference(node);
      sink.end(JsNodeTags.stringReference);
    } else if (node is DeferredHolderExpression) {
      sink.writeEnum(JsNodeKind.deferredHolderExpression);
      sink.begin(JsNodeTags.deferredHolderExpression);
      sink.writeIndexed<DeferredHolderExpression>(node, (_) {
        node.writeToDataSink(sink);
        _writeInfo(node);
      }, identity: true);
      _registry?.registerDeferredHolderExpression(node);
      sink.end(JsNodeTags.deferredHolderExpression);
    } else {
      throw UnsupportedError(
        'Unexpected deferred expression: ${node.runtimeType}.',
      );
    }
  }

  @override
  void visitFun(js.Fun node) {
    sink.writeEnum(JsNodeKind.function);
    sink.begin(JsNodeTags.function);
    visitList(node.params);
    sink.writeDeferrable(
      () => sink.writeList(node.body.statements, sink.writeJsNode),
    );
    sink.writeEnum(node.asyncModifier);
    sink.end(JsNodeTags.function);
    _writeInfo(node);
  }

  @override
  void visitArrowFunction(js.ArrowFunction node) {
    sink.writeEnum(JsNodeKind.arrowFunction);
    sink.begin(JsNodeTags.arrowFunction);
    visitList(node.params);
    visit(node.body);
    sink.writeEnum(node.asyncModifier);
    sink.end(JsNodeTags.arrowFunction);
    _writeInfo(node);
  }

  @override
  void visitNamedFunction(js.NamedFunction node) {
    sink.writeEnum(JsNodeKind.namedFunction);
    sink.begin(JsNodeTags.namedFunction);
    visit(node.name);
    visit(node.function);
    sink.end(JsNodeTags.namedFunction);
    _writeInfo(node);
  }

  @override
  void visitAccess(js.PropertyAccess node) {
    sink.writeEnum(JsNodeKind.access);
    sink.begin(JsNodeTags.access);
    visit(node.receiver);
    visit(node.selector);
    sink.end(JsNodeTags.access);
    _writeInfo(node);
  }

  @override
  void visitParameter(js.Parameter node) {
    sink.writeEnum(JsNodeKind.parameter);
    sink.begin(JsNodeTags.parameter);
    sink.writeString(node.name);
    sink.end(JsNodeTags.parameter);
    _writeInfo(node);
  }

  @override
  void visitVariableDeclaration(js.VariableDeclaration node) {
    sink.writeEnum(JsNodeKind.variableDeclaration);
    sink.begin(JsNodeTags.variableDeclaration);
    sink.writeString(node.name);
    sink.writeBool(node.allowRename);
    sink.end(JsNodeTags.variableDeclaration);
    _writeInfo(node);
  }

  @override
  void visitThis(js.This node) {
    sink.writeEnum(JsNodeKind.thisExpression);
    sink.begin(JsNodeTags.thisExpression);
    sink.end(JsNodeTags.thisExpression);
    _writeInfo(node);
  }

  @override
  void visitVariableUse(js.VariableUse node) {
    sink.writeEnum(JsNodeKind.variableUse);
    sink.begin(JsNodeTags.variableUse);
    sink.writeString(node.name);
    sink.end(JsNodeTags.variableUse);
    _writeInfo(node);
  }

  @override
  void visitPostfix(js.Postfix node) {
    sink.writeEnum(JsNodeKind.postfix);
    sink.begin(JsNodeTags.postfix);
    sink.writeString(node.op);
    visit(node.argument);
    sink.end(JsNodeTags.postfix);
    _writeInfo(node);
  }

  @override
  void visitPrefix(js.Prefix node) {
    sink.writeEnum(JsNodeKind.prefix);
    sink.begin(JsNodeTags.prefix);
    sink.writeString(node.op);
    visit(node.argument);
    sink.end(JsNodeTags.prefix);
    _writeInfo(node);
  }

  @override
  void visitBinary(js.Binary node) {
    sink.writeEnum(JsNodeKind.binary);
    sink.begin(JsNodeTags.binary);
    sink.writeString(node.op);
    visit(node.left);
    visit(node.right);
    sink.end(JsNodeTags.binary);
    _writeInfo(node);
  }

  @override
  void visitCall(js.Call node) {
    sink.writeEnum(JsNodeKind.callExpression);
    sink.begin(JsNodeTags.callExpression);
    visit(node.target);
    visitList(node.arguments);
    sink.end(JsNodeTags.callExpression);
    _writeInfo(node);
  }

  @override
  void visitNew(js.New node) {
    sink.writeEnum(JsNodeKind.newExpression);
    sink.begin(JsNodeTags.newExpression);
    visit(node.target);
    visitList(node.arguments);
    sink.end(JsNodeTags.newExpression);
    _writeInfo(node);
  }

  @override
  void visitConditional(js.Conditional node) {
    sink.writeEnum(JsNodeKind.conditional);
    sink.begin(JsNodeTags.conditional);
    visit(node.condition);
    visit(node.then);
    visit(node.otherwise);
    sink.end(JsNodeTags.conditional);
    _writeInfo(node);
  }

  @override
  void visitVariableInitialization(js.VariableInitialization node) {
    sink.writeEnum(JsNodeKind.variableInitialization);
    sink.begin(JsNodeTags.variableInitialization);
    visit(node.declaration);
    visitOrNull(node.value);
    sink.end(JsNodeTags.variableInitialization);
    _writeInfo(node);
  }

  @override
  void visitAssignment(js.Assignment node) {
    sink.writeEnum(JsNodeKind.assignment);
    sink.begin(JsNodeTags.assignment);
    visit(node.leftHandSide);
    sink.writeStringOrNull(node.op);
    visit(node.value);
    sink.end(JsNodeTags.assignment);
    _writeInfo(node);
  }

  @override
  void visitVariableDeclarationList(js.VariableDeclarationList node) {
    sink.writeEnum(JsNodeKind.variableDeclarationList);
    sink.begin(JsNodeTags.variableDeclarationList);
    visitList(node.declarations);
    sink.writeBool(node.indentSplits);
    sink.end(JsNodeTags.variableDeclarationList);
    _writeInfo(node);
  }

  @override
  void visitLiteralExpression(js.LiteralExpression node) {
    sink.writeEnum(JsNodeKind.literalExpression);
    sink.begin(JsNodeTags.literalExpression);
    sink.writeString(node.template);
    sink.end(JsNodeTags.literalExpression);
    _writeInfo(node);
  }

  @override
  void visitDartYield(js.DartYield node) {
    sink.writeEnum(JsNodeKind.dartYield);
    sink.begin(JsNodeTags.dartYield);
    visit(node.expression);
    sink.writeBool(node.hasStar);
    sink.end(JsNodeTags.dartYield);
    _writeInfo(node);
  }

  @override
  void visitLiteralStatement(js.LiteralStatement node) {
    sink.writeEnum(JsNodeKind.literalStatement);
    sink.begin(JsNodeTags.literalStatement);
    sink.writeString(node.code);
    sink.end(JsNodeTags.literalStatement);
    _writeInfo(node);
  }

  @override
  void visitLabeledStatement(js.LabeledStatement node) {
    sink.writeEnum(JsNodeKind.labeledStatement);
    sink.begin(JsNodeTags.labeledStatement);
    sink.writeString(node.label);
    visit(node.body);
    sink.end(JsNodeTags.labeledStatement);
    _writeInfo(node);
  }

  @override
  void visitFunctionDeclaration(js.FunctionDeclaration node) {
    sink.writeEnum(JsNodeKind.functionDeclaration);
    sink.begin(JsNodeTags.functionDeclaration);
    visit(node.name);
    visit(node.function);
    sink.end(JsNodeTags.functionDeclaration);
    _writeInfo(node);
  }

  @override
  void visitDefault(js.Default node) {
    sink.writeEnum(JsNodeKind.switchDefault);
    sink.begin(JsNodeTags.switchDefault);
    visit(node.body);
    sink.end(JsNodeTags.switchDefault);
    _writeInfo(node);
  }

  @override
  void visitCase(js.Case node) {
    sink.writeEnum(JsNodeKind.switchCase);
    sink.begin(JsNodeTags.switchCase);
    visit(node.expression);
    visit(node.body);
    sink.end(JsNodeTags.switchCase);
    _writeInfo(node);
  }

  @override
  void visitSwitch(js.Switch node) {
    sink.writeEnum(JsNodeKind.switchStatement);
    sink.begin(JsNodeTags.switchStatement);
    visit(node.key);
    visitList(node.cases);
    sink.end(JsNodeTags.switchStatement);
    _writeInfo(node);
  }

  @override
  void visitCatch(js.Catch node) {
    sink.writeEnum(JsNodeKind.catchClause);
    sink.begin(JsNodeTags.catchClause);
    visit(node.declaration);
    visit(node.body);
    sink.end(JsNodeTags.catchClause);
    _writeInfo(node);
  }

  @override
  void visitTry(js.Try node) {
    sink.writeEnum(JsNodeKind.tryStatement);
    sink.begin(JsNodeTags.tryStatement);
    visit(node.body);
    visitOrNull(node.catchPart);
    visitOrNull(node.finallyPart);
    sink.end(JsNodeTags.tryStatement);
    _writeInfo(node);
  }

  @override
  void visitThrow(js.Throw node) {
    sink.writeEnum(JsNodeKind.throwStatement);
    sink.begin(JsNodeTags.throwStatement);
    visit(node.expression);
    sink.end(JsNodeTags.throwStatement);
    _writeInfo(node);
  }

  @override
  void visitReturn(js.Return node) {
    sink.writeEnum(JsNodeKind.returnStatement);
    sink.begin(JsNodeTags.returnStatement);
    visitOrNull(node.value);
    sink.end(JsNodeTags.returnStatement);
    _writeInfo(node);
  }

  @override
  void visitBreak(js.Break node) {
    sink.writeEnum(JsNodeKind.breakStatement);
    sink.begin(JsNodeTags.breakStatement);
    sink.writeStringOrNull(node.targetLabel);
    sink.end(JsNodeTags.breakStatement);
    _writeInfo(node);
  }

  @override
  void visitContinue(js.Continue node) {
    sink.writeEnum(JsNodeKind.continueStatement);
    sink.begin(JsNodeTags.continueStatement);
    sink.writeStringOrNull(node.targetLabel);
    sink.end(JsNodeTags.continueStatement);
    _writeInfo(node);
  }

  @override
  void visitDo(js.Do node) {
    sink.writeEnum(JsNodeKind.doStatement);
    sink.begin(JsNodeTags.doStatement);
    visit(node.body);
    visit(node.condition);
    sink.end(JsNodeTags.doStatement);
    _writeInfo(node);
  }

  @override
  void visitWhile(js.While node) {
    sink.writeEnum(JsNodeKind.whileStatement);
    sink.begin(JsNodeTags.whileStatement);
    visit(node.condition);
    visit(node.body);
    sink.end(JsNodeTags.whileStatement);
    _writeInfo(node);
  }

  @override
  void visitForIn(js.ForIn node) {
    sink.writeEnum(JsNodeKind.forInStatement);
    sink.begin(JsNodeTags.forInStatement);
    visit(node.leftHandSide);
    visit(node.object);
    visit(node.body);
    sink.end(JsNodeTags.forInStatement);
    _writeInfo(node);
  }

  @override
  void visitFor(js.For node) {
    sink.writeEnum(JsNodeKind.forStatement);
    sink.begin(JsNodeTags.forStatement);
    visitOrNull(node.init);
    visitOrNull(node.condition);
    visitOrNull(node.update);
    visit(node.body);
    sink.end(JsNodeTags.forStatement);
    _writeInfo(node);
  }

  @override
  void visitIf(js.If node) {
    sink.writeEnum(JsNodeKind.ifStatement);
    sink.begin(JsNodeTags.ifStatement);
    visit(node.condition);
    visit(node.then);
    visit(node.otherwise);
    sink.end(JsNodeTags.ifStatement);
    _writeInfo(node);
  }

  @override
  void visitEmptyStatement(js.EmptyStatement node) {
    sink.writeEnum(JsNodeKind.emptyStatement);
    sink.begin(JsNodeTags.emptyStatement);
    sink.end(JsNodeTags.emptyStatement);
    _writeInfo(node);
  }

  @override
  void visitExpressionStatement(js.ExpressionStatement node) {
    sink.writeEnum(JsNodeKind.expressionStatement);
    sink.begin(JsNodeTags.expressionStatement);
    visit(node.expression);
    sink.end(JsNodeTags.expressionStatement);
    _writeInfo(node);
  }

  @override
  void visitBlock(js.Block node) {
    sink.writeEnum(JsNodeKind.block);
    sink.begin(JsNodeTags.block);
    visitList(node.statements);
    sink.end(JsNodeTags.block);
    _writeInfo(node);
  }

  @override
  void visitProgram(js.Program node) {
    sink.writeEnum(JsNodeKind.program);
    sink.begin(JsNodeTags.program);
    visitList(node.body);
    sink.end(JsNodeTags.program);
    _writeInfo(node);
  }
}

/// Helper class that deserializes a [js.Node] from [DataSourceReader].
class JsNodeDeserializer {
  final DataSourceReader source;

  JsNodeDeserializer._(this.source);

  static js.Node readFromDataSource(DataSourceReader source) {
    source.begin(JsNodeTags.tag);
    JsNodeDeserializer deserializer = JsNodeDeserializer._(source);
    js.Node node = deserializer.read();
    source.end(JsNodeTags.tag);
    return node;
  }

  T? readOrNull<T extends js.Node>() {
    bool hasValue = source.readBool();
    if (!hasValue) return null;
    return read();
  }

  static List<js.Statement> _readFunBodyStatements(DataSourceReader source) {
    return source.readList(() => source.readJsNode() as js.Statement);
  }

  T read<T extends js.Node>() {
    JsNodeKind kind = source.readEnum(JsNodeKind.values);
    js.Node node;
    bool needsInfo = true;
    switch (kind) {
      case JsNodeKind.comment:
        source.begin(JsNodeTags.comment);
        node = js.Comment(source.readString());
        source.end(JsNodeTags.comment);
        break;
      case JsNodeKind.await:
        source.begin(JsNodeTags.await);
        node = js.Await(read());
        source.end(JsNodeTags.await);
        break;
      case JsNodeKind.regExpLiteral:
        source.begin(JsNodeTags.regExpLiteral);
        node = js.RegExpLiteral(source.readString());
        source.end(JsNodeTags.regExpLiteral);
        break;
      case JsNodeKind.property:
        source.begin(JsNodeTags.property);
        js.Expression name = read();
        js.Expression value = read();
        node = js.Property(name, value);
        source.end(JsNodeTags.property);
        break;
      case JsNodeKind.methodDefinition:
        source.begin(JsNodeTags.methodDefinition);
        js.Expression name = read();
        final function = read() as js.Fun;
        node = js.MethodDefinition(name, function);
        source.end(JsNodeTags.methodDefinition);
        break;
      case JsNodeKind.objectInitializer:
        source.begin(JsNodeTags.objectInitializer);
        List<js.Property> properties = readList();
        bool isOneLiner = source.readBool();
        node = js.ObjectInitializer(properties, isOneLiner: isOneLiner);
        source.end(JsNodeTags.objectInitializer);
        break;
      case JsNodeKind.arrayHole:
        source.begin(JsNodeTags.arrayHole);
        node = js.ArrayHole();
        source.end(JsNodeTags.arrayHole);
        break;
      case JsNodeKind.arrayInitializer:
        source.begin(JsNodeTags.arrayInitializer);
        List<js.Expression> elements = readList();
        node = js.ArrayInitializer(elements);
        source.end(JsNodeTags.arrayInitializer);
        break;
      case JsNodeKind.parentheses:
        source.begin(JsNodeTags.parentheses);
        node = js.Parentheses(read());
        source.end(JsNodeTags.parentheses);
        break;
      case JsNodeKind.modularName:
        source.begin(JsNodeTags.modularName);
        needsInfo = false;
        node = source.readIndexed<ModularName>(
          () => _readInfo(ModularName.readFromDataSource(source)),
        );
        source.end(JsNodeTags.modularName);
        break;
      case JsNodeKind.asyncName:
        source.begin(JsNodeTags.asyncName);
        js.Name prefix = read();
        js.Name base = read();
        node = AsyncName(prefix, base);
        source.end(JsNodeTags.asyncName);
        break;
      case JsNodeKind.stringBackedName:
        source.begin(JsNodeTags.stringBackedName);
        node = StringBackedName(source.readString());
        source.end(JsNodeTags.stringBackedName);
        break;
      case JsNodeKind.stringConcatenation:
        source.begin(JsNodeTags.stringConcatenation);
        List<js.Literal> parts = readList();
        node = js.StringConcatenation(parts);
        source.end(JsNodeTags.stringConcatenation);
        break;
      case JsNodeKind.literalNull:
        source.begin(JsNodeTags.literalNull);
        node = js.LiteralNull();
        source.end(JsNodeTags.literalNull);
        break;
      case JsNodeKind.literalNumber:
        source.begin(JsNodeTags.literalNumber);
        node = js.LiteralNumber(source.readString());
        source.end(JsNodeTags.literalNumber);
        break;
      case JsNodeKind.literalString:
        source.begin(JsNodeTags.literalString);
        node = js.LiteralString(source.readString());
        source.end(JsNodeTags.literalString);
        break;
      case JsNodeKind.literalStringFromName:
        source.begin(JsNodeTags.literalStringFromName);
        js.Name name = read();
        node = js.LiteralStringFromName(name);
        source.end(JsNodeTags.literalStringFromName);
        break;
      case JsNodeKind.literalBool:
        source.begin(JsNodeTags.literalBool);
        node = js.LiteralBool(source.readBool());
        source.end(JsNodeTags.literalBool);
        break;
      case JsNodeKind.modularExpression:
        source.begin(JsNodeTags.modularExpression);
        needsInfo = false;
        node = source.readIndexed<ModularExpression>(
          () => _readInfo(ModularExpression.readFromDataSource(source)),
        );
        source.end(JsNodeTags.modularExpression);
        break;
      case JsNodeKind.function:
        source.begin(JsNodeTags.function);
        List<js.Parameter> params = readList();
        js.Block body = js.DeferredBlock(
          source.readDeferrable(_readFunBodyStatements, cacheData: false),
        );
        js.AsyncModifier asyncModifier = source.readEnum(
          js.AsyncModifier.values,
        );
        node = js.Fun(params, body, asyncModifier: asyncModifier);
        source.end(JsNodeTags.function);
        break;
      case JsNodeKind.arrowFunction:
        source.begin(JsNodeTags.arrowFunction);
        List<js.Parameter> params = readList();
        js.Node body = read();
        js.AsyncModifier asyncModifier = source.readEnum(
          js.AsyncModifier.values,
        );
        node = js.ArrowFunction(params, body, asyncModifier: asyncModifier);
        source.end(JsNodeTags.arrowFunction);
        break;
      case JsNodeKind.namedFunction:
        source.begin(JsNodeTags.namedFunction);
        js.Declaration name = read();
        js.Fun function = read();
        node = js.NamedFunction(name, function);
        source.end(JsNodeTags.namedFunction);
        break;
      case JsNodeKind.access:
        source.begin(JsNodeTags.access);
        js.Expression receiver = read();
        js.Expression selector = read();
        node = js.PropertyAccess(receiver, selector);
        source.end(JsNodeTags.access);
        break;
      case JsNodeKind.parameter:
        source.begin(JsNodeTags.parameter);
        node = js.Parameter(source.readString());
        source.end(JsNodeTags.parameter);
        break;
      case JsNodeKind.variableDeclaration:
        source.begin(JsNodeTags.variableDeclaration);
        String name = source.readString();
        bool allowRename = source.readBool();
        node = js.VariableDeclaration(name, allowRename: allowRename);
        source.end(JsNodeTags.variableDeclaration);
        break;
      case JsNodeKind.thisExpression:
        source.begin(JsNodeTags.thisExpression);
        node = js.This();
        source.end(JsNodeTags.thisExpression);
        break;
      case JsNodeKind.variableUse:
        source.begin(JsNodeTags.variableUse);
        node = js.VariableUse(source.readString());
        source.end(JsNodeTags.variableUse);
        break;
      case JsNodeKind.postfix:
        source.begin(JsNodeTags.postfix);
        String op = source.readString();
        js.Expression argument = read();
        node = js.Postfix(op, argument);
        source.end(JsNodeTags.postfix);
        break;
      case JsNodeKind.prefix:
        source.begin(JsNodeTags.prefix);
        String op = source.readString();
        js.Expression argument = read();
        node = js.Prefix(op, argument);
        source.end(JsNodeTags.prefix);
        break;
      case JsNodeKind.binary:
        source.begin(JsNodeTags.binary);
        String op = source.readString();
        js.Expression left = read();
        js.Expression right = read();
        node = js.Binary(op, left, right);
        source.end(JsNodeTags.binary);
        break;
      case JsNodeKind.callExpression:
        source.begin(JsNodeTags.callExpression);
        js.Expression target = read();
        List<js.Expression> arguments = readList();
        node = js.Call(target, arguments);
        source.end(JsNodeTags.callExpression);
        break;
      case JsNodeKind.newExpression:
        source.begin(JsNodeTags.newExpression);
        js.Expression cls = read();
        List<js.Expression> arguments = readList();
        node = js.New(cls, arguments);
        source.end(JsNodeTags.newExpression);
        break;
      case JsNodeKind.conditional:
        source.begin(JsNodeTags.conditional);
        js.Expression condition = read();
        js.Expression then = read();
        js.Expression otherwise = read();
        node = js.Conditional(condition, then, otherwise);
        source.end(JsNodeTags.conditional);
        break;
      case JsNodeKind.variableInitialization:
        source.begin(JsNodeTags.variableInitialization);
        js.Declaration declaration = read();
        final value = source.readValueOrNull(read) as js.Expression?;
        node = js.VariableInitialization(declaration, value);
        source.end(JsNodeTags.variableInitialization);
        break;
      case JsNodeKind.assignment:
        source.begin(JsNodeTags.assignment);
        js.Expression leftHandSide = read();
        final op = source.readStringOrNull();
        js.Expression value = read();
        node = js.Assignment.compound(leftHandSide, op, value);
        source.end(JsNodeTags.assignment);
        break;
      case JsNodeKind.variableDeclarationList:
        source.begin(JsNodeTags.variableDeclarationList);
        List<js.VariableInitialization> declarations = readList();
        bool indentSplits = source.readBool();
        node = js.VariableDeclarationList(
          declarations,
          indentSplits: indentSplits,
        );
        source.end(JsNodeTags.variableDeclarationList);
        break;
      case JsNodeKind.literalExpression:
        source.begin(JsNodeTags.literalExpression);
        node = js.LiteralExpression(source.readString());
        source.end(JsNodeTags.literalExpression);
        break;
      case JsNodeKind.dartYield:
        source.begin(JsNodeTags.dartYield);
        js.Expression expression = read();
        bool hasStar = source.readBool();
        node = js.DartYield(expression, hasStar);
        source.end(JsNodeTags.dartYield);
        break;
      case JsNodeKind.literalStatement:
        source.begin(JsNodeTags.literalStatement);
        node = js.LiteralStatement(source.readString());
        source.end(JsNodeTags.literalStatement);
        break;
      case JsNodeKind.labeledStatement:
        source.begin(JsNodeTags.labeledStatement);
        String label = source.readString();
        js.Statement body = read();
        node = js.LabeledStatement(label, body);
        source.end(JsNodeTags.labeledStatement);
        break;
      case JsNodeKind.functionDeclaration:
        source.begin(JsNodeTags.functionDeclaration);
        js.Declaration name = read();
        js.Fun function = read();
        node = js.FunctionDeclaration(name, function);
        source.end(JsNodeTags.functionDeclaration);
        break;
      case JsNodeKind.switchDefault:
        source.begin(JsNodeTags.switchDefault);
        js.Block body = read();
        node = js.Default(body);
        source.end(JsNodeTags.switchDefault);
        break;
      case JsNodeKind.switchCase:
        source.begin(JsNodeTags.switchCase);
        js.Expression expression = read();
        js.Block body = read();
        node = js.Case(expression, body);
        source.end(JsNodeTags.switchCase);
        break;
      case JsNodeKind.switchStatement:
        source.begin(JsNodeTags.switchStatement);
        js.Expression key = read();
        List<js.SwitchClause> cases = readList();
        node = js.Switch(key, cases);
        source.end(JsNodeTags.switchStatement);
        break;
      case JsNodeKind.catchClause:
        source.begin(JsNodeTags.catchClause);
        js.Declaration declaration = read();
        js.Block body = read();
        node = js.Catch(declaration, body);
        source.end(JsNodeTags.catchClause);
        break;
      case JsNodeKind.tryStatement:
        source.begin(JsNodeTags.tryStatement);
        js.Block body = read();
        final catchPart = source.readValueOrNull(read) as js.Catch?;
        final finallyPart = source.readValueOrNull(read) as js.Block?;
        node = js.Try(body, catchPart, finallyPart);
        source.end(JsNodeTags.tryStatement);
        break;
      case JsNodeKind.throwStatement:
        source.begin(JsNodeTags.throwStatement);
        js.Expression expression = read();
        node = js.Throw(expression);
        source.end(JsNodeTags.throwStatement);
        break;
      case JsNodeKind.returnStatement:
        source.begin(JsNodeTags.returnStatement);
        final value = source.readValueOrNull(read) as js.Expression?;
        node = js.Return(value);
        source.end(JsNodeTags.returnStatement);
        break;
      case JsNodeKind.breakStatement:
        source.begin(JsNodeTags.breakStatement);
        final targetLabel = source.readStringOrNull();
        node = js.Break(targetLabel);
        source.end(JsNodeTags.breakStatement);
        break;
      case JsNodeKind.continueStatement:
        source.begin(JsNodeTags.continueStatement);
        final targetLabel = source.readStringOrNull();
        node = js.Continue(targetLabel);
        source.end(JsNodeTags.continueStatement);
        break;
      case JsNodeKind.doStatement:
        source.begin(JsNodeTags.doStatement);
        js.Statement body = read();
        js.Expression condition = read();
        node = js.Do(body, condition);
        source.end(JsNodeTags.doStatement);
        break;
      case JsNodeKind.whileStatement:
        source.begin(JsNodeTags.whileStatement);
        js.Expression condition = read();
        js.Statement body = read();
        node = js.While(condition, body);
        source.end(JsNodeTags.whileStatement);
        break;
      case JsNodeKind.forInStatement:
        source.begin(JsNodeTags.forInStatement);
        js.Expression leftHandSide = read();
        js.Expression object = read();
        js.Statement body = read();
        node = js.ForIn(leftHandSide, object, body);
        source.end(JsNodeTags.forInStatement);
        break;
      case JsNodeKind.forStatement:
        source.begin(JsNodeTags.forStatement);
        final init = readOrNull() as js.Expression?;
        final condition = readOrNull() as js.Expression?;
        final update = readOrNull() as js.Expression?;
        js.Statement body = read();
        node = js.For(init, condition, update, body);
        source.end(JsNodeTags.forStatement);
        break;
      case JsNodeKind.ifStatement:
        source.begin(JsNodeTags.ifStatement);
        js.Expression condition = read();
        js.Statement then = read();
        js.Statement otherwise = read();
        node = js.If(condition, then, otherwise);
        source.end(JsNodeTags.ifStatement);
        break;
      case JsNodeKind.emptyStatement:
        source.begin(JsNodeTags.emptyStatement);
        node = js.EmptyStatement();
        source.end(JsNodeTags.emptyStatement);
        break;
      case JsNodeKind.expressionStatement:
        source.begin(JsNodeTags.expressionStatement);
        node = js.ExpressionStatement(read());
        source.end(JsNodeTags.expressionStatement);
        break;
      case JsNodeKind.block:
        source.begin(JsNodeTags.block);
        List<js.Statement> statements = readList();
        node = js.Block(statements);
        source.end(JsNodeTags.block);
        break;
      case JsNodeKind.program:
        source.begin(JsNodeTags.program);
        List<js.Statement> body = readList();
        node = js.Program(body);
        source.end(JsNodeTags.program);
        break;
      case JsNodeKind.stringReference:
        source.begin(JsNodeTags.stringReference);
        needsInfo = false;
        node = source.readIndexed<StringReference>(
          () => _readInfo(StringReference.readFromDataSource(source)),
        );
        source.end(JsNodeTags.stringReference);
        break;
      case JsNodeKind.typeReference:
        source.begin(JsNodeTags.typeReference);
        needsInfo = false;
        node = source.readIndexed<TypeReference>(
          () => _readInfo(TypeReference.readFromDataSource(source)),
        );
        source.end(JsNodeTags.typeReference);
        break;
      case JsNodeKind.deferredHolderExpression:
        source.begin(JsNodeTags.deferredHolderExpression);
        needsInfo = false;
        node = source.readIndexed<DeferredHolderExpression>(
          () => _readInfo(DeferredHolderExpression.readFromDataSource(source)),
        );
        source.end(JsNodeTags.deferredHolderExpression);
        break;
    }

    return needsInfo ? _readInfo(node) : node as T;
  }

  T _readInfo<T extends js.Node>(js.Node node) {
    final infoCode = source.readInt();
    final hasSourceInformation = infoCode.isOdd;
    final annotationCount = infoCode ~/ 2;
    if (hasSourceInformation) {
      final sourceInformation = source
          .readIndexedOrNullNoCache<SourceInformation>(() {
            return SourceInformation.readFromDataSource(source);
          });
      node = node.withSourceInformation(sourceInformation);
    }
    for (int i = 0; i < annotationCount; i++) {
      node = node.withAnnotation(_readAnnotation());
    }
    return node as T;
  }

  List<T> readList<T extends js.Node>() {
    return source.readList(read);
  }

  Object _readAnnotation() {
    final kind = source.readEnum(JsAnnotationKind.values);
    switch (kind) {
      case JsAnnotationKind.string:
        return source.readString();
      case JsAnnotationKind.resourceIdentifier:
        return ResourceIdentifier.readFromDataSource(source);
    }
  }
}

enum ModularNameKind {
  rtiField,
  className,
  aliasedSuperMember,
  staticClosure,
  methodProperty,
  operatorIs,
  instanceMethod,
  instanceField,
  invocation,
  lazyInitializer,
  globalPropertyNameForClass,
  globalPropertyNameForMember,
  globalNameForInterfaceTypeVariable,
  nameForGetInterceptor,
  nameForOneShotInterceptor,
  asName,
}

class ModularName extends js.Name implements js.AstContainer {
  static const String tag = 'modular-name';

  final ModularNameKind kind;
  js.Name? _value;
  final Object? data;
  final Set<ClassEntity>? set;

  ModularName(this.kind, {this.data, this.set});

  factory ModularName.readFromDataSource(DataSourceReader source) {
    source.begin(tag);
    ModularNameKind kind = source.readEnum(ModularNameKind.values);
    Object? data;
    Set<ClassEntity>? set;
    switch (kind) {
      case ModularNameKind.rtiField:
        break;
      case ModularNameKind.className:
      case ModularNameKind.operatorIs:
      case ModularNameKind.globalPropertyNameForClass:
        data = source.readClass();
        break;
      case ModularNameKind.aliasedSuperMember:
      case ModularNameKind.staticClosure:
      case ModularNameKind.methodProperty:
      case ModularNameKind.instanceField:
      case ModularNameKind.instanceMethod:
      case ModularNameKind.lazyInitializer:
      case ModularNameKind.globalPropertyNameForMember:
        data = source.readMember();
        break;
      case ModularNameKind.invocation:
        data = Selector.readFromDataSource(source);
        break;
      case ModularNameKind.globalNameForInterfaceTypeVariable:
        data = source.readTypeVariable();
        break;
      case ModularNameKind.nameForGetInterceptor:
        set = source.readClasses().toSet();
        break;
      case ModularNameKind.nameForOneShotInterceptor:
        data = Selector.readFromDataSource(source);
        set = source.readClasses().toSet();
        break;
      case ModularNameKind.asName:
        data = source.readString();
        break;
    }
    source.end(tag);
    return ModularName(kind, data: data, set: set);
  }

  void writeToDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeEnum(kind);
    switch (kind) {
      case ModularNameKind.rtiField:
        break;
      case ModularNameKind.className:
      case ModularNameKind.operatorIs:
      case ModularNameKind.globalPropertyNameForClass:
        sink.writeClass(data as ClassEntity);
        break;
      case ModularNameKind.aliasedSuperMember:
      case ModularNameKind.staticClosure:
      case ModularNameKind.methodProperty:
      case ModularNameKind.instanceField:
      case ModularNameKind.instanceMethod:
      case ModularNameKind.lazyInitializer:
      case ModularNameKind.globalPropertyNameForMember:
        sink.writeMember(data as MemberEntity);
        break;
      case ModularNameKind.invocation:
        final selector = data as Selector;
        selector.writeToDataSink(sink);
        break;
      case ModularNameKind.globalNameForInterfaceTypeVariable:
        final typeVariable = data as TypeVariableEntity;
        sink.writeTypeVariable(typeVariable);
        break;
      case ModularNameKind.nameForGetInterceptor:
        sink.writeClasses(set!);
        break;
      case ModularNameKind.nameForOneShotInterceptor:
        final selector = data as Selector;
        selector.writeToDataSink(sink);
        sink.writeClasses(set!);
        break;
      case ModularNameKind.asName:
        sink.writeString(data as String);
        break;
    }
    sink.end(tag);
  }

  @override
  bool get isFinalized => _value != null;

  js.Name get value {
    assert(isFinalized, 'value not set for $this');
    return _value!;
  }

  set value(js.Name node) {
    assert(!isFinalized);
    _value = node.withSourceInformation(sourceInformation) as js.Name;
  }

  @override
  String get key {
    assert(isFinalized);
    return _value!.key;
  }

  @override
  String get name {
    assert(isFinalized, 'value not set for $this');
    return _value!.name;
  }

  @override
  bool get allowRename {
    assert(isFinalized, 'value not set for $this');
    return _value!.allowRename;
  }

  @override
  Iterable<js.Node> get containedNodes {
    return _value != null ? [_value!] : const [];
  }

  @override
  int get hashCode {
    return Hashing.setHash(set, Hashing.objectsHash(kind, data));
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) return true;
    return other is ModularName &&
        kind == other.kind &&
        data == other.data &&
        equalSets(set, other.set);
  }

  @override
  String toString() =>
      'ModularName(kind=$kind, data=$data, value=${_value?.key})';

  @override
  String nonfinalizedDebugText() {
    switch (kind) {
      case ModularNameKind.rtiField:
        return r'ModularName"$ti"';
      case ModularNameKind.instanceField:
        return 'ModularName"field:${(data as Entity).name}"';
      case ModularNameKind.instanceMethod:
        return 'ModularName"${_instanceMethodName(data as MemberEntity)}"';
      case ModularNameKind.methodProperty:
        return 'ModularName"methodProperty:${(data as Entity).name}"';
      case ModularNameKind.operatorIs:
        return 'ModularName"is:${_className(data as ClassEntity)}"';
      case ModularNameKind.className:
        return 'ModularName"class:${_className(data as ClassEntity)}"';
      case ModularNameKind.globalPropertyNameForClass:
        return 'ModularName"classref:${_className(data as ClassEntity)}"';
      case ModularNameKind.aliasedSuperMember:
        MemberEntity member = (data as MemberEntity);
        String className = _className(member.enclosingClass!);
        String invocationName = operatorNameToIdentifier(member.name)!;
        final description = "$className.$invocationName";
        return 'ModularName"alias:$description"';
      case ModularNameKind.staticClosure:
        return 'ModularName"closure:${_qualifiedStaticName(data as MemberEntity)}"';
      case ModularNameKind.lazyInitializer:
        return 'ModularName"lazy:${(data as MemberEntity).name}"';
      case ModularNameKind.globalPropertyNameForMember:
        MemberEntity member = data as MemberEntity;
        return 'ModularName"ref:${_qualifiedStaticName(member)}"';
      case ModularNameKind.invocation:
        return 'ModularName"selector:${_selectorText(data as Selector)}"';
      case ModularNameKind.nameForOneShotInterceptor:
        return 'ModularName"oneshot:${_selectorText(data as Selector)}"';
      case ModularNameKind.globalNameForInterfaceTypeVariable:
        break;
      case ModularNameKind.nameForGetInterceptor:
        return 'ModularName"getInterceptor"';
      case ModularNameKind.asName:
        return 'ModularName"asName:$data"';
    }
    return super.nonfinalizedDebugText();
  }

  String _className(ClassEntity cls) {
    return cls.name.replaceAll('&', '_');
  }

  String _qualifiedStaticName(MemberEntity member) {
    if (member is ConstructorEntity || member.isStatic) {
      return '${_className(member.enclosingClass!)}.${member.name!}';
    }
    return member.name!;
  }

  String _instanceMethodInvocationName(MemberEntity member) {
    String invocationName = operatorNameToIdentifier(member.name)!;
    if (member.isGetter) invocationName = r'get$' + invocationName;
    if (member.isSetter) invocationName = r'set$' + invocationName;
    return invocationName;
  }

  String _instanceMethodName(MemberEntity member) {
    if (member is ConstructorBodyEntity) {
      return 'constructorBody:${_qualifiedStaticName(member.constructor)}';
    }
    if (member is JGeneratorBody) {
      MemberEntity function = member.function;
      return 'generatorBody:'
          '${_className(function.enclosingClass!)}.'
          '${_instanceMethodInvocationName(function)}';
    }
    return 'instanceMethod:${_instanceMethodInvocationName(member)}';
  }

  String _selectorText(Selector selector) {
    // Approximation to unminified selector.
    if (selector.isGetter) return r'get$' + selector.name;
    if (selector.isSetter) return r'set$' + selector.name;
    if (selector.isOperator || selector.isIndex || selector.isIndexSet) {
      return operatorNameToIdentifier(selector.name)!;
    }
    List<String> parts = [
      selector.name,
      if (selector.callStructure.typeArgumentCount > 0)
        '${selector.callStructure.typeArgumentCount}',
      '${selector.callStructure.argumentCount}',
      ...selector.callStructure.getOrderedNamedArguments(),
    ];
    return parts.join(r'$');
  }
}

/// Interface for reading the code generation results for all [MemberEntity]s.
abstract class CodegenResults {
  CodegenInputs get codegenInputs;
  ({CodegenResult result, bool isGenerated}) getCodegenResults(
    MemberEntity member,
  );
}

/// Deserialized code generation results.
///
/// This is used for modular code generation.
class DeserializedCodegenResults implements CodegenResults {
  @override
  final CodegenInputs codegenInputs;
  final FunctionCompiler _functionCompiler;

  final Map<MemberEntity, CodegenResult> _map;

  DeserializedCodegenResults(
    this.codegenInputs,
    this._map,
    this._functionCompiler,
  );

  @override
  ({CodegenResult result, bool isGenerated}) getCodegenResults(
    MemberEntity member,
  ) {
    // We only access these results once as it is picked up by the work queue
    // so it is safe to remove and free up space in the map. With deferred
    // deserialization this will also free the Deferrable holder.
    // Some entities such as parameter stubs are generated lazily and so we have
    // to compile them on the fly.
    final deserialized = _map.remove(member);
    if (deserialized != null) return (result: deserialized, isGenerated: false);
    return (result: _functionCompiler.compile(member), isGenerated: true);
  }
}
