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

// @dart = 2.10

library dart2js.common.codegen;

import 'package:js_ast/src/precedence.dart' as js show PRIMARY;

import '../common.dart';
import '../common/elements.dart';
import '../constants/values.dart';
import '../deferred_load/output_unit.dart' show OutputUnit;
import '../elements/entities.dart';
import '../elements/types.dart' show DartType, InterfaceType;
import '../inferrer/abstract_value_domain.dart';
import '../inferrer/types.dart';
import '../io/source_information.dart';
import '../js/js.dart' as js;
import '../js_backend/backend.dart';
import '../js_backend/namer.dart';
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/code_emitter_task.dart' show Emitter;
import '../js_model/elements.dart' show JGeneratorBody;
import '../js_model/type_recipe.dart' show TypeRecipe;
import '../native/behavior.dart';
import '../serialization/serialization.dart';
import '../ssa/ssa.dart';
import '../universe/feature.dart';
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';
import '../world.dart';

class CodegenImpact extends WorldImpact {
  const CodegenImpact();

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

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

  Iterable<Pair<DartType, DartType>> get typeVariableBoundsSubtypeChecks {
    return const <Pair<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';

  @override
  final MemberEntity member;
  Set<Pair<DartType, DartType>> _typeVariableBoundsSubtypeChecks;
  Set<String> _constSymbols;
  List<Set<ClassEntity>> _specializedGetInterceptors;
  bool _usesInterceptor = false;
  EnumSet<AsyncMarker> _asyncMarkers;
  Set<GenericInstantiation> _genericInstantiations;
  List<NativeBehavior> _nativeBehaviors;
  Set<FunctionEntity> _nativeMethods;
  Set<Selector> _oneShotInterceptors;

  _CodegenImpact(this.member);

  _CodegenImpact.internal(
      this.member,
      Set<DynamicUse> dynamicUses,
      Set<StaticUse> staticUses,
      Set<TypeUse> typeUses,
      Set<ConstantUse> constantUses,
      this._typeVariableBoundsSubtypeChecks,
      this._constSymbols,
      this._specializedGetInterceptors,
      this._usesInterceptor,
      this._asyncMarkers,
      this._genericInstantiations,
      this._nativeBehaviors,
      this._nativeMethods,
      this._oneShotInterceptors)
      : super.internal(dynamicUses, staticUses, typeUses, constantUses);

  factory _CodegenImpact.readFromDataSource(DataSourceReader source) {
    source.begin(tag);
    MemberEntity member = source.readMember();
    Set<DynamicUse> dynamicUses = source
        .readListOrNull(() => DynamicUse.readFromDataSource(source))
        ?.toSet();
    Set<StaticUse> staticUses = source
        .readListOrNull(() => StaticUse.readFromDataSource(source))
        ?.toSet();
    Set<TypeUse> typeUses = source
        .readListOrNull(() => TypeUse.readFromDataSource(source))
        ?.toSet();
    Set<ConstantUse> constantUses = source
        .readListOrNull(() => ConstantUse.readFromDataSource(source))
        ?.toSet();
    Set<Pair<DartType, DartType>> typeVariableBoundsSubtypeChecks =
        source.readListOrNull(() {
      return Pair(source.readDartType(), source.readDartType());
    })?.toSet();
    Set<String> constSymbols = source.readStrings(emptyAsNull: true)?.toSet();
    List<Set<ClassEntity>> specializedGetInterceptors =
        source.readListOrNull(() {
      return source.readClasses().toSet();
    });
    bool usesInterceptor = source.readBool();
    int asyncMarkersValue = source.readIntOrNull();
    EnumSet<AsyncMarker> asyncMarkers =
        asyncMarkersValue != null ? EnumSet.fromValue(asyncMarkersValue) : null;
    Set<GenericInstantiation> genericInstantiations = source
        .readListOrNull(() => GenericInstantiation.readFromDataSource(source))
        ?.toSet();
    List<NativeBehavior> nativeBehaviors =
        source.readListOrNull(() => NativeBehavior.readFromDataSource(source));
    Set<FunctionEntity> nativeMethods =
        source.readMembersOrNull<FunctionEntity>()?.toSet();
    Set<Selector> 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),
        allowNull: true);
    sink.writeList(staticUses, (StaticUse use) => use.writeToDataSink(sink),
        allowNull: true);
    sink.writeList(typeUses, (TypeUse use) => use.writeToDataSink(sink),
        allowNull: true);
    sink.writeList(constantUses, (ConstantUse use) => use.writeToDataSink(sink),
        allowNull: true);
    sink.writeList<Pair<DartType, DartType>>(_typeVariableBoundsSubtypeChecks,
        (pair) {
      sink.writeDartType(pair.a);
      sink.writeDartType(pair.b);
    }, allowNull: true);
    sink.writeStrings(_constSymbols, allowNull: true);
    sink.writeList(_specializedGetInterceptors, sink.writeClasses,
        allowNull: true);
    sink.writeBool(_usesInterceptor);
    sink.writeIntOrNull(_asyncMarkers?.value);
    sink.writeList(
        _genericInstantiations,
        (GenericInstantiation instantiation) =>
            instantiation.writeToDataSink(sink),
        allowNull: true);
    sink.writeList(_nativeBehaviors,
        (NativeBehavior behavior) => behavior.writeToDataSink(sink),
        allowNull: true);
    sink.writeMembers(_nativeMethods, allowNull: true);
    sink.writeList(_oneShotInterceptors,
        (Selector selector) => selector.writeToDataSink(sink),
        allowNull: true);
    sink.end(tag);
  }

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

  @override
  Iterable<Pair<DartType, DartType>> get typeVariableBoundsSubtypeChecks {
    return _typeVariableBoundsSubtypeChecks ??
        const <Pair<DartType, DartType>>[];
  }

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

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

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

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

  void registerUseInterceptor() {
    _usesInterceptor = true;
  }

  @override
  bool get usesInterceptor => _usesInterceptor;

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

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

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

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

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

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

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

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

  void registerOneShotInterceptor(Selector selector) {
    _oneShotInterceptors ??= {};
    _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 iterable) {
      if (iterable.isNotEmpty) {
        sb.write('\n $title:');
        iterable.forEach((e) => 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;
  List<ModularName> _names;
  List<ModularExpression> _expressions;

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

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

  @deprecated
  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(ModularName name) {
    _names ??= [];
    _names.add(name);
  }

  void registerModularExpression(ModularExpression expression) {
    _expressions ??= [];
    _expressions.add(expression);
  }

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

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

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

  OnDemandCodegenResults(this.globalTypeInferenceResults, this.codegenInputs,
      this._functionCompiler);

  @override
  CodegenResult getCodegenResults(MemberEntity member) {
    return _functionCompiler.compile(member);
  }
}

/// Deserialized code generation results.
///
/// This is used for modular code generation.
class DeserializedCodegenResults extends CodegenResults {
  @override
  final GlobalTypeInferenceResults globalTypeInferenceResults;
  @override
  final CodegenInputs codegenInputs;

  final Map<MemberEntity, CodegenResult> _map;

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

  @override
  CodegenResult getCodegenResults(MemberEntity member) {
    CodegenResult result = _map[member];
    if (result == null) {
      failedAt(member,
          "No codegen results from $member (${identityHashCode(member)}).");
    }
    return result;
  }
}

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

  final js.Fun code;
  final CodegenImpact impact;
  final Iterable<ModularName> modularNames;
  final Iterable<ModularExpression> modularExpressions;

  CodegenResult(this.code, this.impact, List<ModularName> modularNames,
      List<ModularExpression> modularExpressions)
      : this.modularNames =
            modularNames.isEmpty ? const [] : List.unmodifiable(modularNames),
        this.modularExpressions = modularExpressions.isEmpty
            ? const []
            : List.unmodifiable(modularExpressions);

  /// Reads a [CodegenResult] object from [source].
  ///
  /// The [ModularName] and [ModularExpression] nodes read during
  /// deserialization are collected in [modularNames] and [modularExpressions]
  /// to avoid the need for visiting the [code] node post deserialization.
  factory CodegenResult.readFromDataSource(
      DataSourceReader source,
      List<ModularName> modularNames,
      List<ModularExpression> modularExpressions) {
    source.begin(tag);
    js.Fun code = source.readJsNodeOrNull();
    CodegenImpact impact = CodegenImpact.readFromDataSource(source);
    source.end(tag);
    return CodegenResult(code, impact, modularNames, modularExpressions);
  }

  /// Writes the [CodegenResult] object to [sink].
  ///
  /// The [modularNames] and [modularExpressions] fields are not directly
  /// serializes because these are embedded in the [code] node and collected
  /// through this during deserialization.
  void writeToDataSink(DataSinkWriter sink) {
    sink.begin(tag);
    sink.writeJsNodeOrNull(code);
    impact.writeToDataSink(sink);
    sink.end(tag);
  }

  void applyModularState(Namer namer, Emitter emitter) {
    for (ModularName name in modularNames) {
      switch (name.kind) {
        case ModularNameKind.rtiField:
          name.value = namer.rtiFieldJsName;
          break;
        case ModularNameKind.className:
          name.value = namer.className(name.data);
          break;
        case ModularNameKind.aliasedSuperMember:
          name.value = namer.aliasedSuperMemberPropertyName(name.data);
          break;
        case ModularNameKind.staticClosure:
          name.value = namer.staticClosureName(name.data);
          break;
        case ModularNameKind.methodProperty:
          name.value = namer.methodPropertyName(name.data);
          break;
        case ModularNameKind.operatorIs:
          name.value = namer.operatorIs(name.data);
          break;
        case ModularNameKind.instanceMethod:
          name.value = namer.instanceMethodName(name.data);
          break;
        case ModularNameKind.instanceField:
          name.value = namer.instanceFieldPropertyName(name.data);
          break;
        case ModularNameKind.invocation:
          name.value = namer.invocationName(name.data);
          break;
        case ModularNameKind.lazyInitializer:
          name.value = namer.lazyInitializerName(name.data);
          break;
        case ModularNameKind.globalPropertyNameForClass:
          name.value = namer.globalPropertyNameForClass(name.data);
          break;
        case ModularNameKind.globalPropertyNameForMember:
          name.value = namer.globalPropertyNameForMember(name.data);
          break;
        case ModularNameKind.globalNameForInterfaceTypeVariable:
          name.value = namer.globalNameForInterfaceTypeVariable(name.data);
          break;
        case ModularNameKind.nameForGetInterceptor:
          name.value = namer.nameForGetInterceptor(name.set);
          break;
        case ModularNameKind.nameForOneShotInterceptor:
          name.value = namer.nameForOneShotInterceptor(name.data, name.set);
          break;
        case ModularNameKind.asName:
          name.value = namer.asName(name.data);
          break;
      }
    }
    for (ModularExpression expression in modularExpressions) {
      switch (expression.kind) {
        case ModularExpressionKind.constant:
          expression.value = emitter
              .constantReference(expression.data)
              .withSourceInformation(expression.sourceInformation);
          break;
        case ModularExpressionKind.embeddedGlobalAccess:
          expression.value = emitter
              .generateEmbeddedGlobalAccess(expression.data)
              .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=$modularNames,');
    sb.write('modularExpressions=$modularExpressions');
    sb.write(')');
    return sb.toString();
  }
}

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);
        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);
        break;
      case ModularNameKind.invocation:
        Selector selector = data;
        selector.writeToDataSink(sink);
        break;
      case ModularNameKind.globalNameForInterfaceTypeVariable:
        TypeVariableEntity typeVariable = data;
        sink.writeTypeVariable(typeVariable);
        break;
      case ModularNameKind.nameForGetInterceptor:
        sink.writeClasses(set);
        break;
      case ModularNameKind.nameForOneShotInterceptor:
        Selector selector = data;
        selector.writeToDataSink(sink);
        sink.writeClasses(set);
        break;
      case ModularNameKind.asName:
        sink.writeString(data);
        break;
    }
    sink.end(tag);
  }

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

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

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

  @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)}"';
      case ModularNameKind.methodProperty:
        return 'ModularName"methodProperty:${(data as Entity).name}"';
      case ModularNameKind.operatorIs:
        return 'ModularName"is:${_className(data)}"';
      case ModularNameKind.className:
        return 'ModularName"class:${_className(data)}"';
      case ModularNameKind.globalPropertyNameForClass:
        return 'ModularName"classref:${_className(data)}"';
      case ModularNameKind.aliasedSuperMember:
        MemberEntity member = (data as MemberEntity);
        String className = _className(member.enclosingClass);
        String invocationName = Namer.operatorNameToIdentifier(member.name);
        final description = "$className.$invocationName";
        return 'ModularName"alias:$description"';
      case ModularNameKind.staticClosure:
        return 'ModularName"closure:${_qualifiedStaticName(data)}"';
      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.isConstructor || member.isStatic) {
      return '${_className(member.enclosingClass)}.${member.name}';
    }
    return member.name;
  }

  String _instanceMethodInvocationName(MemberEntity member) {
    String invocationName = Namer.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 Namer.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'$');
  }
}

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);
        break;
      case ModularExpressionKind.embeddedGlobalAccess:
        sink.writeString(data);
        break;
    }
    sink.end(tag);
  }

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

  @override
  js.Expression get value {
    assert(isFinalized);
    return _value;
  }

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

  @override
  int get precedenceLevel => _value?.precedenceLevel ?? js.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"';
    }
    return super.nonfinalizedDebugText();
  }
}

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

/// Visitor that serializes a [js.Node] into a [DataSinkWriter].
class JsNodeSerializer implements js.NodeVisitor<void> {
  final DataSinkWriter sink;

  JsNodeSerializer._(this.sink);

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

  void visit(js.Node node, {bool allowNull = false}) {
    if (allowNull) {
      sink.writeBool(node != null);
      if (node != null) {
        node.accept(this);
      }
    } else {
      node.accept(this);
    }
  }

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

  void _writeInfo(js.Node node) {
    sink.writeCached<SourceInformation /*!*/ >(node.sourceInformation,
        (SourceInformation sourceInformation) {
      SourceInformation.writeToDataSink(sink, sourceInformation);
    });
  }

  @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);
      node.writeToDataSink(sink);
      sink.end(JsNodeTags.modularName);
      _writeInfo(node);
    } 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);
      node.writeToDataSink(sink);
      sink.end(JsNodeTags.modularExpression);
      _writeInfo(node);
    } else if (node is TypeReference) {
      sink.writeEnum(JsNodeKind.typeReference);
      sink.begin(JsNodeTags.typeReference);
      node.writeToDataSink(sink);
      sink.end(JsNodeTags.typeReference);
      _writeInfo(node);
    } else if (node is StringReference) {
      sink.writeEnum(JsNodeKind.stringReference);
      sink.begin(JsNodeTags.stringReference);
      node.writeToDataSink(sink);
      sink.end(JsNodeTags.stringReference);
      _writeInfo(node);
    } else if (node is DeferredHolderExpression) {
      sink.writeEnum(JsNodeKind.deferredHolderExpression);
      sink.begin(JsNodeTags.deferredHolderExpression);
      node.writeToDataSink(sink);
      sink.end(JsNodeTags.deferredHolderExpression);
      _writeInfo(node);
    } 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);
    visit(node.body);
    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);
    visit(node.value, allowNull: true);
    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);
    visit(node.catchPart, allowNull: true);
    visit(node.finallyPart, allowNull: true);
    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);
    visit(node.value, allowNull: true);
    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);
    visit(node.init, allowNull: true);
    visit(node.condition, allowNull: true);
    visit(node.update, allowNull: true);
    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].
///
/// Deserialized [ModularName]s and [ModularExpression]s are collected in the
/// [modularNames] and [modularExpressions] lists.
class JsNodeDeserializer {
  final DataSourceReader source;
  final List<ModularName> modularNames;
  final List<ModularExpression> modularExpressions;

  JsNodeDeserializer._(this.source, this.modularNames, this.modularExpressions);

  static js.Node readFromDataSource(
      DataSourceReader source,
      List<ModularName> modularNames,
      List<ModularExpression> modularExpressions) {
    source.begin(JsNodeTags.tag);
    JsNodeDeserializer deserializer =
        JsNodeDeserializer._(source, modularNames, modularExpressions);
    js.Node node = deserializer.read();
    source.end(JsNodeTags.tag);
    return node;
  }

  T read<T extends js.Node>({bool allowNull = false}) {
    if (allowNull) {
      bool hasValue = source.readBool();
      if (!hasValue) return null;
    }
    JsNodeKind kind = source.readEnum(JsNodeKind.values);
    js.Node node;
    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();
        js.Expression function = read();
        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);
        ModularName modularName = ModularName.readFromDataSource(source);
        modularNames.add(modularName);
        node = modularName;
        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);
        ModularExpression modularExpression =
            ModularExpression.readFromDataSource(source);
        modularExpressions.add(modularExpression);
        node = modularExpression;
        source.end(JsNodeTags.modularExpression);
        break;
      case JsNodeKind.function:
        source.begin(JsNodeTags.function);
        List<js.Parameter> params = readList();
        js.Block body = read();
        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();
        js.Expression value = source.readValueOrNull(read);
        node = js.VariableInitialization(declaration, value);
        source.end(JsNodeTags.variableInitialization);
        break;
      case JsNodeKind.assignment:
        source.begin(JsNodeTags.assignment);
        js.Expression leftHandSide = read();
        String 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();
        js.Catch catchPart = source.readValueOrNull(read);
        js.Block finallyPart = source.readValueOrNull(read);
        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);
        js.Expression value = source.readValueOrNull(read);
        node = js.Return(value);
        source.end(JsNodeTags.returnStatement);
        break;
      case JsNodeKind.breakStatement:
        source.begin(JsNodeTags.breakStatement);
        String targetLabel = source.readStringOrNull();
        node = js.Break(targetLabel);
        source.end(JsNodeTags.breakStatement);
        break;
      case JsNodeKind.continueStatement:
        source.begin(JsNodeTags.continueStatement);
        String 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);
        js.Expression init = read(allowNull: true);
        js.Expression condition = read(allowNull: true);
        js.Expression update = read(allowNull: true);
        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);
        node = StringReference.readFromDataSource(source);
        source.end(JsNodeTags.stringReference);
        break;
      case JsNodeKind.typeReference:
        source.begin(JsNodeTags.typeReference);
        node = TypeReference.readFromDataSource(source);
        source.end(JsNodeTags.typeReference);
        break;
      case JsNodeKind.deferredHolderExpression:
        source.begin(JsNodeTags.deferredHolderExpression);
        node = DeferredHolderExpression.readFromDataSource(source);
        source.end(JsNodeTags.deferredHolderExpression);
        break;
    }
    SourceInformation sourceInformation =
        source.readCachedOrNull<SourceInformation>(() {
      return SourceInformation.readFromDataSource(source);
    });
    if (sourceInformation != null) {
      node = node.withSourceInformation(sourceInformation);
    }
    return node;
  }

  List<T> readList<T extends js.Node>({bool emptyAsNull = false}) {
    // TODO(48820): Is [emptyAsNull] unused?
    return emptyAsNull ? source.readListOrNull(read) : source.readList(read);
  }
}

class CodegenReaderImpl implements CodegenReader {
  final JClosedWorld closedWorld;
  final List<ModularName> modularNames;
  final List<ModularExpression> modularExpressions;

  CodegenReaderImpl(
      this.closedWorld, this.modularNames, this.modularExpressions);

  @override
  AbstractValue readAbstractValue(DataSourceReader source) {
    return closedWorld.abstractValueDomain
        .readAbstractValueFromDataSource(source);
  }

  @override
  js.Node readJsNode(DataSourceReader source) {
    return JsNodeDeserializer.readFromDataSource(
        source, modularNames, modularExpressions);
  }

  @override
  OutputUnit readOutputUnitReference(DataSourceReader source) {
    return closedWorld.outputUnitData.outputUnits[source.readInt()];
  }

  @override
  TypeRecipe readTypeRecipe(DataSourceReader source) {
    return TypeRecipe.readFromDataSource(source);
  }
}

class CodegenWriterImpl implements CodegenWriter {
  final JClosedWorld closedWorld;

  CodegenWriterImpl(this.closedWorld);

  @override
  void writeAbstractValue(DataSinkWriter sink, AbstractValue value) {
    closedWorld.abstractValueDomain.writeAbstractValueToDataSink(sink, value);
  }

  @override
  void writeJsNode(DataSinkWriter sink, js.Node node) {
    JsNodeSerializer.writeToDataSink(sink, node);
  }

  @override
  void writeOutputUnitReference(DataSinkWriter sink, OutputUnit value) {
    sink.writeInt(closedWorld.outputUnitData.outputUnits.indexOf(value));
  }

  @override
  void writeTypeRecipe(DataSinkWriter sink, TypeRecipe recipe) {
    recipe.writeToDataSink(sink);
  }
}
