// Copyright (c) 2020, 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.

import 'dart:typed_data';

import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/dart/element/type_algebra.dart';
import 'package:analyzer/src/dart/resolver/variance.dart';
import 'package:analyzer/src/summary2/ast_binary_tag.dart';
import 'package:analyzer/src/summary2/ast_binary_writer.dart';
import 'package:analyzer/src/summary2/data_writer.dart';
import 'package:analyzer/src/summary2/element_flags.dart';
import 'package:analyzer/src/summary2/reference.dart';
import 'package:analyzer/src/task/inference_error.dart';
import 'package:collection/collection.dart';

class BundleWriter {
  late final _BundleWriterReferences _references;

  /// The declaration sink - any data that can be read without a need to
  /// have any other elements to be available. For example declarations of
  /// classes, methods, functions, etc. But not supertypes of classes, or
  /// return types of methods - these might reference other classes that we
  /// have not read yet. Such resolution data is stored into [_resolutionSink].
  ///
  /// Some resolution data is still written into this sink, if it does not
  /// require any other declaration read it later. For example type inference
  /// errors, or whether a parameter inherits `covariant`, or a class is
  /// simply bounded.
  late final _SummaryDataWriter _sink = _SummaryDataWriter(
    sink: ByteSink(),
    stringIndexer: _stringIndexer,
  );

  /// The resolution sink - any data that references elements, so can only
  /// be read after elements are created and available via its [Reference]s.
  late final ResolutionSink _resolutionSink = ResolutionSink(
    sink: ByteSink(),
    stringIndexer: _stringIndexer,
    references: _references,
  );

  /// [_writeClassElement] remembers the length of data written into [_sink]
  /// while writing members. So, when we read, we can skip members initially,
  /// and read them later on demand.
  List<int> _classMembersLengths = [];

  final StringIndexer _stringIndexer = StringIndexer();

  final List<_Library> _libraries = [];

  BundleWriter(Reference dynamicReference) {
    _references = _BundleWriterReferences(dynamicReference);
  }

  BundleWriterResult finish() {
    var baseResolutionOffset = _sink.offset;
    _sink.addBytes(_resolutionSink.flushAndTake());

    var librariesOffset = _sink.offset;
    _sink.writeList<_Library>(_libraries, (library) {
      _sink._writeStringReference(library.uriStr);
      _sink.writeUInt30(library.offset);
      _sink.writeUint30List(library.classMembersOffsets);
    });

    var referencesOffset = _sink.offset;
    _sink.writeUint30List(_references._referenceParents);
    _sink._writeStringList(_references._referenceNames);
    _references._clearIndexes();

    var stringTableOffset = _stringIndexer.write(_sink);

    // Write as Uint32 so that we know where it is.
    _sink.writeUInt32(baseResolutionOffset);
    _sink.writeUInt32(librariesOffset);
    _sink.writeUInt32(referencesOffset);
    _sink.writeUInt32(stringTableOffset);

    var bytes = _sink.flushAndTake();
    return BundleWriterResult(
      astBytes: Uint8List(0),
      resolutionBytes: bytes,
    );
  }

  void writeLibraryElement(
    LibraryElementImpl libraryElement,
    List<Reference> exports,
  ) {
    var libraryOffset = _sink.offset;
    _classMembersLengths = <int>[];

    _sink.writeUInt30(_resolutionSink.offset);
    _sink._writeStringReference(libraryElement.name!);
    _writeFeatureSet(libraryElement.featureSet);
    _writeLanguageVersion(libraryElement.languageVersion);
    _resolutionSink._writeAnnotationList(libraryElement.metadata);
    _writeList(libraryElement.imports, _writeImportElement);
    _writeList(libraryElement.exports, _writeExportElement);
    _resolutionSink.writeElement(libraryElement.entryPoint);
    LibraryElementFlags.write(_sink, libraryElement);
    _sink.writeUInt30(libraryElement.units.length);
    for (var unitElement in libraryElement.units) {
      _writeUnitElement(unitElement);
    }
    _writeReferences(exports);

    _libraries.add(
      _Library(
        uriStr: '${libraryElement.source.uri}',
        offset: libraryOffset,
        classMembersOffsets: _classMembersLengths,
      ),
    );
  }

  void _writeClassElement(ClassElement element) {
    element as ClassElementImpl;
    _sink.writeUInt30(_resolutionSink.offset);

    _sink._writeStringReference(element.name);
    ClassElementFlags.write(_sink, element);

    _resolutionSink._writeAnnotationList(element.metadata);

    _writeTypeParameters(element.typeParameters, () {
      _resolutionSink.writeOptionalInterfaceType(element.supertype);
      _resolutionSink._writeInterfaceTypeList(element.mixins);
      _resolutionSink._writeInterfaceTypeList(element.interfaces);

      if (!element.isMixinApplication) {
        var membersOffset = _sink.offset;
        _writeList(
          element.fields.where((e) => !e.isSynthetic).toList(),
          _writeFieldElement,
        );
        _writeList(
          element.accessors.where((e) => !e.isSynthetic).toList(),
          _writePropertyAccessorElement,
        );
        _writeList(element.constructors, _writeConstructorElement);
        _writeList(element.methods, _writeMethodElement);
        _classMembersLengths.add(_sink.offset - membersOffset);
      }
    });
  }

  void _writeConstructorElement(ConstructorElement element) {
    element as ConstructorElementImpl;
    _sink.writeUInt30(_resolutionSink.offset);
    _sink._writeStringReference(element.name);
    ConstructorElementFlags.write(_sink, element);
    _resolutionSink._writeAnnotationList(element.metadata);

    _resolutionSink.localElements.pushScope();
    _resolutionSink.localElements.declareAll(element.parameters);
    try {
      _writeList(element.parameters, _writeParameterElement);
      if (element.isConst || element.isFactory) {
        _resolutionSink.writeElement(element.redirectedConstructor);
        _resolutionSink._writeNodeList(element.constantInitializers);
      }
    } finally {
      _resolutionSink.localElements.popScope();
    }
  }

  void _writeEnumElement(ClassElement element) {
    element as EnumElementImpl;
    _sink.writeUInt30(_resolutionSink.offset);
    _sink._writeStringReference(element.name);
    _resolutionSink._writeAnnotationList(element.metadata);

    var constants = element.fields.where((e) => !e.isSynthetic).toList();
    _writeList<FieldElement>(constants, (field) {
      _sink._writeStringReference(field.name);
      _resolutionSink._writeAnnotationList(field.metadata);
    });
  }

  void _writeExportElement(ExportElement element) {
    _sink._writeOptionalStringReference(element.uri);
    _sink.writeList(element.combinators, _writeNamespaceCombinator);
    _resolutionSink._writeAnnotationList(element.metadata);
    _resolutionSink.writeElement(element.exportedLibrary);
  }

  void _writeExtensionElement(ExtensionElement element) {
    element as ExtensionElementImpl;
    _sink.writeUInt30(_resolutionSink.offset);

    _sink._writeOptionalStringReference(element.name);
    _sink._writeStringReference(element.reference!.name);

    _resolutionSink._writeAnnotationList(element.metadata);

    _writeTypeParameters(element.typeParameters, () {
      _resolutionSink.writeType(element.extendedType);

      _writeList(
        element.accessors.where((e) => !e.isSynthetic).toList(),
        _writePropertyAccessorElement,
      );
      _writeList(
        element.fields.where((e) => !e.isSynthetic).toList(),
        _writeFieldElement,
      );
      _writeList(element.methods, _writeMethodElement);
    });
  }

  void _writeFeatureSet(FeatureSet featureSet) {
    var experimentStatus = featureSet as ExperimentStatus;
    var encoded = experimentStatus.toStorage();
    _sink.writeUint8List(encoded);
  }

  void _writeFieldElement(FieldElement element) {
    element as FieldElementImpl;
    _sink.writeUInt30(_resolutionSink.offset);
    _sink._writeStringReference(element.name);
    _sink.writeBool(element is ConstFieldElementImpl);
    FieldElementFlags.write(_sink, element);
    _sink._writeTopLevelInferenceError(element.typeInferenceError);
    _resolutionSink._writeAnnotationList(element.metadata);
    _resolutionSink.writeType(element.type);
    _resolutionSink._writeOptionalNode(element.constantInitializer);
  }

  void _writeFunctionElement(FunctionElement element) {
    element as FunctionElementImpl;
    _sink.writeUInt30(_resolutionSink.offset);
    _sink._writeStringReference(element.name);
    FunctionElementFlags.write(_sink, element);

    _resolutionSink._writeAnnotationList(element.metadata);

    _writeTypeParameters(element.typeParameters, () {
      _resolutionSink.writeType(element.returnType);
      _writeList(element.parameters, _writeParameterElement);
    });
  }

  void _writeImportElement(ImportElement element) {
    element as ImportElementImpl;
    ImportElementFlags.write(_sink, element);
    _sink._writeOptionalStringReference(element.uri);
    _sink._writeOptionalStringReference(element.prefix?.name);
    _sink.writeList(element.combinators, _writeNamespaceCombinator);
    _resolutionSink._writeAnnotationList(element.metadata);
    _resolutionSink.writeElement(element.importedLibrary);
  }

  void _writeLanguageVersion(LibraryLanguageVersion version) {
    _sink.writeUInt30(version.package.major);
    _sink.writeUInt30(version.package.minor);

    var override = version.override;
    if (override != null) {
      _sink.writeBool(true);
      _sink.writeUInt30(override.major);
      _sink.writeUInt30(override.minor);
    } else {
      _sink.writeBool(false);
    }
  }

  void _writeList<T>(List<T> elements, void Function(T) writeElement) {
    _sink.writeUInt30(elements.length);
    for (var element in elements) {
      writeElement(element);
    }
  }

  void _writeMethodElement(MethodElement element) {
    element as MethodElementImpl;
    _sink.writeUInt30(_resolutionSink.offset);
    _sink._writeStringReference(element.name);
    MethodElementFlags.write(_sink, element);

    _resolutionSink._writeAnnotationList(element.metadata);

    _writeTypeParameters(element.typeParameters, () {
      _writeList(element.parameters, _writeParameterElement);
      _sink._writeTopLevelInferenceError(element.typeInferenceError);
      _resolutionSink.writeType(element.returnType);
    });
  }

  void _writeMixinElement(ClassElement element) {
    element as MixinElementImpl;
    _sink.writeUInt30(_resolutionSink.offset);

    _sink._writeStringReference(element.name);
    _resolutionSink._writeAnnotationList(element.metadata);

    _writeTypeParameters(element.typeParameters, () {
      _resolutionSink._writeInterfaceTypeList(element.superclassConstraints);
      _resolutionSink._writeInterfaceTypeList(element.interfaces);

      _writeList(
        element.accessors.where((e) => !e.isSynthetic).toList(),
        _writePropertyAccessorElement,
      );
      _writeList(
        element.fields.where((e) => !e.isSynthetic).toList(),
        _writeFieldElement,
      );
      _writeList(element.constructors, _writeConstructorElement);
      _writeList(element.methods, _writeMethodElement);
      _sink._writeStringList(element.superInvokedNames);
    });
  }

  void _writeNamespaceCombinator(NamespaceCombinator combinator) {
    if (combinator is HideElementCombinator) {
      _sink.writeByte(Tag.HideCombinator);
      _sink.writeList<String>(combinator.hiddenNames, (name) {
        _sink._writeStringReference(name);
      });
    } else if (combinator is ShowElementCombinator) {
      _sink.writeByte(Tag.ShowCombinator);
      _sink.writeList<String>(combinator.shownNames, (name) {
        _sink._writeStringReference(name);
      });
    } else {
      throw UnimplementedError('${combinator.runtimeType}');
    }
  }

  void _writeParameterElement(ParameterElement element) {
    element as ParameterElementImpl;
    _sink._writeStringReference(element.name);
    _sink.writeBool(element.isInitializingFormal);
    _sink._writeFormalParameterKind(element);
    ParameterElementFlags.write(_sink, element);

    _resolutionSink._writeAnnotationList(element.metadata);

    _writeTypeParameters(element.typeParameters, () {
      _writeList(element.parameters, _writeParameterElement);
      _resolutionSink.writeType(element.type);

      if (element is ConstVariableElement) {
        var constElement = element as ConstVariableElement;
        _resolutionSink._writeOptionalNode(constElement.constantInitializer);
      }
      if (element is FieldFormalParameterElementImpl) {
        _resolutionSink.writeElement(element.field);
      }
    });
  }

  void _writePropertyAccessorElement(PropertyAccessorElement element) {
    element as PropertyAccessorElementImpl;
    _sink.writeUInt30(_resolutionSink.offset);
    _sink._writeStringReference(element.displayName);
    PropertyAccessorElementFlags.write(_sink, element);

    _resolutionSink._writeAnnotationList(element.metadata);
    _resolutionSink.writeType(element.returnType);
    _writeList(element.parameters, _writeParameterElement);
  }

  void _writeReferences(List<Reference> references) {
    var length = references.length;
    _sink.writeUInt30(length);

    for (var reference in references) {
      var index = _references._indexOfReference(reference);
      _sink.writeUInt30(index);
    }
  }

  void _writeTopLevelVariableElement(TopLevelVariableElement element) {
    element as TopLevelVariableElementImpl;
    _sink.writeUInt30(_resolutionSink.offset);
    _sink._writeStringReference(element.name);
    _sink.writeBool(element.isConst);
    TopLevelVariableElementFlags.write(_sink, element);
    _sink._writeTopLevelInferenceError(element.typeInferenceError);
    _resolutionSink._writeAnnotationList(element.metadata);
    _resolutionSink.writeType(element.type);
    _resolutionSink._writeOptionalNode(element.constantInitializer);
  }

  void _writeTypeAliasElement(TypeAliasElement element) {
    element as TypeAliasElementImpl;
    _sink.writeUInt30(_resolutionSink.offset);

    _sink._writeStringReference(element.name);
    _sink.writeBool(element.isFunctionTypeAliasBased);
    TypeAliasElementFlags.write(_sink, element);

    _resolutionSink._writeAnnotationList(element.metadata);

    _writeTypeParameters(element.typeParameters, () {
      _resolutionSink._writeAliasedElement(element.aliasedElement);
      _resolutionSink.writeType(element.aliasedType);
    });
  }

  void _writeTypeParameterElement(TypeParameterElement typeParameter) {
    typeParameter as TypeParameterElementImpl;
    _sink._writeStringReference(typeParameter.name);
    _sink.writeByte(_encodeVariance(typeParameter).index);
    _resolutionSink._writeAnnotationList(typeParameter.metadata);
    _resolutionSink.writeType(typeParameter.bound);
    _resolutionSink.writeType(typeParameter.defaultType);
  }

  /// Add [typeParameters] to the indexing scope, so make them available
  /// when writing types that might reference them, and write the elements.
  void _writeTypeParameters(
    List<TypeParameterElement> typeParameters,
    void Function() f,
  ) {
    _resolutionSink.localElements.pushScope();
    _resolutionSink.localElements.declareAll(typeParameters);
    try {
      _sink.writeList(typeParameters, _writeTypeParameterElement);
      f();
    } finally {
      _resolutionSink.localElements.popScope();
    }
  }

  void _writeUnitElement(CompilationUnitElement unitElement) {
    _sink.writeUInt30(_resolutionSink.offset);

    _sink._writeStringReference('${unitElement.source.uri}');
    _sink._writeOptionalStringReference(unitElement.uri);
    _sink.writeBool(unitElement.isSynthetic);
    _resolutionSink._writeAnnotationList(unitElement.metadata);
    _writeList(unitElement.types, _writeClassElement);
    _writeList(unitElement.enums, _writeEnumElement);
    _writeList(unitElement.extensions, _writeExtensionElement);
    _writeList(unitElement.functions, _writeFunctionElement);
    _writeList(unitElement.mixins, _writeMixinElement);
    _writeList(unitElement.typeAliases, _writeTypeAliasElement);

    _writeList(
      unitElement.topLevelVariables
          .where((element) => !element.isSynthetic)
          .toList(),
      _writeTopLevelVariableElement,
    );
    _writeList(
      unitElement.accessors.where((e) => !e.isSynthetic).toList(),
      _writePropertyAccessorElement,
    );
  }

  static TypeParameterVarianceTag _encodeVariance(
      TypeParameterElementImpl element) {
    if (element.isLegacyCovariant) {
      return TypeParameterVarianceTag.legacy;
    }

    var variance = element.variance;
    if (variance == Variance.unrelated) {
      return TypeParameterVarianceTag.unrelated;
    } else if (variance == Variance.covariant) {
      return TypeParameterVarianceTag.covariant;
    } else if (variance == Variance.contravariant) {
      return TypeParameterVarianceTag.contravariant;
    } else if (variance == Variance.invariant) {
      return TypeParameterVarianceTag.invariant;
    } else {
      throw UnimplementedError('$variance');
    }
  }
}

class BundleWriterResult {
  final Uint8List astBytes;
  final Uint8List resolutionBytes;

  BundleWriterResult({
    required this.astBytes,
    required this.resolutionBytes,
  });
}

class ResolutionSink extends _SummaryDataWriter {
  final _BundleWriterReferences _references;
  final _LocalElementIndexer localElements = _LocalElementIndexer();

  ResolutionSink({
    required ByteSink sink,
    required StringIndexer stringIndexer,
    required _BundleWriterReferences references,
  })  : _references = references,
        super(
          sink: sink,
          stringIndexer: stringIndexer,
        );

  /// TODO(scheglov) Triage places where we write elements.
  /// Some of then cannot be members, e.g. type names.
  void writeElement(Element? element) {
    if (element is Member) {
      var declaration = element.declaration;
      var isLegacy = element.isLegacy;

      var typeArguments = _enclosingClassTypeArguments(
        declaration,
        element.substitution.map,
      );

      writeByte(
        isLegacy
            ? Tag.MemberLegacyWithTypeArguments
            : Tag.MemberWithTypeArguments,
      );

      _writeElement(declaration);
      _writeTypeList(typeArguments);
    } else {
      writeByte(Tag.RawElement);
      _writeElement(element);
    }
  }

  void writeInterfaceType(InterfaceType type) {
    _writeElement(type.element);
    var typeArguments = type.typeArguments;
    writeUInt30(typeArguments.length);
    for (var i = 0; i < typeArguments.length; ++i) {
      writeType(typeArguments[i]);
    }
    _writeNullabilitySuffix(type.nullabilitySuffix);
  }

  void writeOptionalInterfaceType(InterfaceType? type) {
    if (type != null) {
      writeByte(1);
      writeInterfaceType(type);
    } else {
      writeByte(0);
    }
  }

  void writeType(DartType? type) {
    if (type == null) {
      writeByte(Tag.NullType);
    } else if (type is DynamicType) {
      writeByte(Tag.DynamicType);
      _writeTypeAliasElementArguments(type);
    } else if (type is FunctionType) {
      _writeFunctionType(type);
      _writeTypeAliasElementArguments(type);
    } else if (type is InterfaceType) {
      var typeArguments = type.typeArguments;
      var nullabilitySuffix = type.nullabilitySuffix;
      if (typeArguments.isEmpty) {
        if (nullabilitySuffix == NullabilitySuffix.none) {
          writeByte(Tag.InterfaceType_noTypeArguments_none);
        } else if (nullabilitySuffix == NullabilitySuffix.question) {
          writeByte(Tag.InterfaceType_noTypeArguments_question);
        } else if (nullabilitySuffix == NullabilitySuffix.star) {
          writeByte(Tag.InterfaceType_noTypeArguments_star);
        }
        // TODO(scheglov) Write raw
        writeElement(type.element);
      } else {
        writeByte(Tag.InterfaceType);
        // TODO(scheglov) Write raw
        writeElement(type.element);
        writeUInt30(typeArguments.length);
        for (var i = 0; i < typeArguments.length; ++i) {
          writeType(typeArguments[i]);
        }
        _writeNullabilitySuffix(nullabilitySuffix);
      }
      _writeTypeAliasElementArguments(type);
    } else if (type is NeverType) {
      writeByte(Tag.NeverType);
      _writeNullabilitySuffix(type.nullabilitySuffix);
      _writeTypeAliasElementArguments(type);
    } else if (type is TypeParameterType) {
      writeByte(Tag.TypeParameterType);
      writeElement(type.element);
      _writeNullabilitySuffix(type.nullabilitySuffix);
      _writeTypeAliasElementArguments(type);
    } else if (type is VoidType) {
      writeByte(Tag.VoidType);
      _writeTypeAliasElementArguments(type);
    } else {
      throw UnimplementedError('${type.runtimeType}');
    }
  }

  int _indexOfElement(Element? element) {
    if (element == null) return 0;
    if (element is MultiplyDefinedElement) return 0;
    assert(element is! Member);

    // Positional parameters cannot be referenced outside of their scope,
    // so don't have a reference, so are stored as local elements.
    if (element is ParameterElementImpl && element.reference == null) {
      return localElements[element] << 1 | 0x1;
    }

    // Type parameters cannot be referenced outside of their scope,
    // so don't have a reference, so are stored as local elements.
    if (element is TypeParameterElement) {
      return localElements[element] << 1 | 0x1;
    }

    if (identical(element, DynamicElementImpl.instance)) {
      return _references._indexOfReference(_references.dynamicReference) << 1;
    }

    var reference = (element as ElementImpl).reference;
    return _references._indexOfReference(reference) << 1;
  }

  void _writeAliasedElement(Element? element) {
    if (element == null) {
      writeByte(AliasedElementTag.nothing);
    } else if (element is GenericFunctionTypeElement) {
      writeByte(AliasedElementTag.genericFunctionElement);
      _writeTypeParameters(element.typeParameters, () {
        _writeFormalParameters(element.parameters, withAnnotations: true);
        writeType(element.returnType);
      }, withAnnotations: true);
    } else {
      throw UnimplementedError('${element.runtimeType}');
    }
  }

  void _writeAnnotationList(List<ElementAnnotation> annotations) {
    writeUInt30(annotations.length);
    for (var annotation in annotations) {
      annotation as ElementAnnotationImpl;
      _writeNode(annotation.annotationAst);
    }
  }

  void _writeElement(Element? element) {
    assert(element is! Member, 'Use writeMemberOrElement()');
    var elementIndex = _indexOfElement(element);
    writeUInt30(elementIndex);
  }

  void _writeFormalParameters(
    List<ParameterElement> parameters, {
    required bool withAnnotations,
  }) {
    writeUInt30(parameters.length);
    for (var parameter in parameters) {
      _writeFormalParameterKind(parameter);
      writeBool(parameter.hasImplicitType);
      writeBool(parameter.isInitializingFormal);
      _writeTypeParameters(parameter.typeParameters, () {
        writeType(parameter.type);
        _writeStringReference(parameter.name);
        _writeFormalParameters(
          parameter.parameters,
          withAnnotations: withAnnotations,
        );
      }, withAnnotations: withAnnotations);
      if (withAnnotations) {
        _writeAnnotationList(parameter.metadata);
      }
    }
  }

  void _writeFunctionType(FunctionType type) {
    type = _toSyntheticFunctionType(type);

    writeByte(Tag.FunctionType);

    _writeTypeParameters(type.typeFormals, () {
      writeType(type.returnType);
      _writeFormalParameters(type.parameters, withAnnotations: false);
    }, withAnnotations: false);
    _writeNullabilitySuffix(type.nullabilitySuffix);
  }

  void _writeInterfaceTypeList(List<InterfaceType> types) {
    writeUInt30(types.length);
    for (var type in types) {
      writeInterfaceType(type);
    }
  }

  void _writeNode(AstNode node) {
    var astWriter = AstBinaryWriter(
      sink: this,
      stringIndexer: _stringIndexer,
    );
    node.accept(astWriter);
  }

  void _writeNodeList(List<AstNode> nodes) {
    writeUInt30(nodes.length);
    for (var node in nodes) {
      _writeNode(node);
    }
  }

  void _writeNullabilitySuffix(NullabilitySuffix suffix) {
    writeByte(suffix.index);
  }

  void _writeOptionalNode(Expression? node) {
    if (node != null) {
      writeBool(true);
      _writeNode(node);
    } else {
      writeBool(false);
    }
  }

  void _writeTypeAliasElementArguments(DartType type) {
    var aliasElement = type.aliasElement;
    _writeElement(aliasElement);
    if (aliasElement != null) {
      _writeTypeList(type.aliasArguments!);
    }
  }

  void _writeTypeList(List<DartType> types) {
    writeUInt30(types.length);
    for (var type in types) {
      writeType(type);
    }
  }

  void _writeTypeParameters(
    List<TypeParameterElement> typeParameters,
    void Function() f, {
    required bool withAnnotations,
  }) {
    localElements.pushScope();
    localElements.declareAll(typeParameters);
    try {
      writeUInt30(typeParameters.length);
      for (var typeParameter in typeParameters) {
        _writeStringReference(typeParameter.name);
      }
      for (var typeParameter in typeParameters) {
        writeType(typeParameter.bound);
        if (withAnnotations) {
          _writeAnnotationList(typeParameter.metadata);
        }
      }
      f();
    } finally {
      localElements.popScope();
    }
  }

  static List<DartType> _enclosingClassTypeArguments(
    Element declaration,
    Map<TypeParameterElement, DartType> substitution,
  ) {
    // TODO(scheglov) Just keep it null in class Member?
    if (substitution.isEmpty) {
      return const [];
    }

    var enclosing = declaration.enclosingElement;
    if (enclosing is TypeParameterizedElement) {
      if (enclosing is! ClassElement && enclosing is! ExtensionElement) {
        return const <DartType>[];
      }

      var typeParameters = enclosing.typeParameters;
      if (typeParameters.isEmpty) {
        return const <DartType>[];
      }

      return typeParameters
          .map((typeParameter) => substitution[typeParameter])
          .whereNotNull()
          .toList(growable: false);
    }

    return const <DartType>[];
  }

  static FunctionType _toSyntheticFunctionType(FunctionType type) {
    var typeParameters = type.typeFormals;
    if (typeParameters.isEmpty) return type;

    var fresh = getFreshTypeParameters(typeParameters);
    return fresh.applyToFunctionType(type);
  }
}

class StringIndexer {
  final Map<String, int> _index = {};

  int operator [](String string) {
    var result = _index[string];

    if (result == null) {
      result = _index.length;
      _index[string] = result;
    }

    return result;
  }

  int write(BufferedSink sink) {
    var bytesOffset = sink.offset;

    var length = _index.length;
    var lengths = Uint32List(length);
    var lengthsIndex = 0;
    for (var key in _index.keys) {
      var stringStart = sink.offset;
      _writeWtf8(sink, key);
      lengths[lengthsIndex++] = sink.offset - stringStart;
    }

    var resultOffset = sink.offset;

    var lengthOfBytes = sink.offset - bytesOffset;
    sink.writeUInt30(lengthOfBytes);
    sink.writeUint30List(lengths);

    return resultOffset;
  }

  /// Write [source] string into [sink].
  static void _writeWtf8(BufferedSink sink, String source) {
    var end = source.length;
    if (end == 0) {
      return;
    }

    int i = 0;
    do {
      var codeUnit = source.codeUnitAt(i++);
      if (codeUnit < 128) {
        // ASCII.
        sink.addByte(codeUnit);
      } else if (codeUnit < 0x800) {
        // Two-byte sequence (11-bit unicode value).
        sink.addByte(0xC0 | (codeUnit >> 6));
        sink.addByte(0x80 | (codeUnit & 0x3f));
      } else if ((codeUnit & 0xFC00) == 0xD800 &&
          i < end &&
          (source.codeUnitAt(i) & 0xFC00) == 0xDC00) {
        // Surrogate pair -> four-byte sequence (non-BMP unicode value).
        int codeUnit2 = source.codeUnitAt(i++);
        int unicode =
            0x10000 + ((codeUnit & 0x3FF) << 10) + (codeUnit2 & 0x3FF);
        sink.addByte(0xF0 | (unicode >> 18));
        sink.addByte(0x80 | ((unicode >> 12) & 0x3F));
        sink.addByte(0x80 | ((unicode >> 6) & 0x3F));
        sink.addByte(0x80 | (unicode & 0x3F));
      } else {
        // Three-byte sequence (16-bit unicode value), including lone
        // surrogates.
        sink.addByte(0xE0 | (codeUnit >> 12));
        sink.addByte(0x80 | ((codeUnit >> 6) & 0x3f));
        sink.addByte(0x80 | (codeUnit & 0x3f));
      }
    } while (i < end);
  }
}

class UnitToWriteAst {
  final CompilationUnit node;

  UnitToWriteAst({
    required this.node,
  });
}

class _BundleWriterReferences {
  /// The `dynamic` class is declared in `dart:core`, but is not a class.
  /// Also, it is static, so we cannot set `reference` for it.
  /// So, we have to push it in a separate way.
  final Reference dynamicReference;

  /// References used in all libraries being linked.
  /// Element references in nodes are indexes in this list.
  /// TODO(scheglov) Do we really use this list?
  final List<Reference?> references = [null];

  final List<int> _referenceParents = [0];
  final List<String> _referenceNames = [''];

  _BundleWriterReferences(this.dynamicReference);

  /// We need indexes for references during linking, but once we are done,
  /// we must clear indexes to make references ready for linking a next bundle.
  void _clearIndexes() {
    for (var reference in references) {
      if (reference != null) {
        reference.index = null;
      }
    }
  }

  int _indexOfReference(Reference? reference) {
    if (reference == null) return 0;
    if (reference.parent == null) return 0;

    var index = reference.index;
    if (index != null) return index;

    var parentIndex = _indexOfReference(reference.parent);
    _referenceParents.add(parentIndex);
    _referenceNames.add(reference.name);

    index = references.length;
    reference.index = index;
    references.add(reference);
    return index;
  }
}

class _Library {
  final String uriStr;
  final int offset;
  final List<int> classMembersOffsets;

  _Library({
    required this.uriStr,
    required this.offset,
    required this.classMembersOffsets,
  });
}

class _LocalElementIndexer {
  final Map<Element, int> _index = Map.identity();
  final List<int> _scopes = [];
  int _stackHeight = 0;

  int operator [](Element element) {
    return _index[element] ??
        (throw ArgumentError('Unexpectedly not indexed: $element'));
  }

  void declare(Element element) {
    _index[element] = _stackHeight++;
  }

  void declareAll(List<Element> elements) {
    for (var element in elements) {
      declare(element);
    }
  }

  void popScope() {
    _stackHeight = _scopes.removeLast();
  }

  void pushScope() {
    _scopes.add(_stackHeight);
  }
}

class _SummaryDataWriter extends BufferedSink {
  final StringIndexer _stringIndexer;

  _SummaryDataWriter({
    required ByteSink sink,
    required StringIndexer stringIndexer,
  })  : _stringIndexer = stringIndexer,
        super(sink);

  void _writeFormalParameterKind(ParameterElement p) {
    if (p.isRequiredPositional) {
      writeByte(Tag.ParameterKindRequiredPositional);
    } else if (p.isOptionalPositional) {
      writeByte(Tag.ParameterKindOptionalPositional);
    } else if (p.isRequiredNamed) {
      writeByte(Tag.ParameterKindRequiredNamed);
    } else if (p.isOptionalNamed) {
      writeByte(Tag.ParameterKindOptionalNamed);
    } else {
      throw StateError('Unexpected parameter kind: $p');
    }
  }

  void _writeOptionalStringReference(String? value) {
    if (value != null) {
      writeBool(true);
      _writeStringReference(value);
    } else {
      writeBool(false);
    }
  }

  void _writeStringList(List<String> values) {
    writeUInt30(values.length);
    for (var value in values) {
      _writeStringReference(value);
    }
  }

  void _writeStringReference(String string) {
    var index = _stringIndexer[string];
    writeUInt30(index);
  }

  void _writeTopLevelInferenceError(TopLevelInferenceError? error) {
    if (error != null) {
      writeByte(error.kind.index);
      _writeStringList(error.arguments);
    } else {
      writeByte(TopLevelInferenceErrorKind.none.index);
    }
  }
}
