// 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/ast/ast.dart';
import 'package:analyzer/dart/ast/token.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/source/line_info.dart';
import 'package:analyzer/src/dart/analysis/experiments.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/ast/ast_factory.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/dart/element/type_algebra.dart';
import 'package:analyzer/src/generated/testing/token_factory.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary2/apply_resolution.dart';
import 'package:analyzer/src/summary2/ast_binary_reader.dart';
import 'package:analyzer/src/summary2/ast_binary_tag.dart';
import 'package:analyzer/src/summary2/ast_binary_tokens.dart';
import 'package:analyzer/src/summary2/data_reader.dart';
import 'package:analyzer/src/summary2/linked_element_factory.dart';
import 'package:analyzer/src/summary2/linked_unit_context.dart';
import 'package:analyzer/src/summary2/reference.dart';
import 'package:pub_semver/pub_semver.dart';

Map<String, LibraryReader> createLibraryReadersWithAstBytes({
  required LinkedElementFactory elementFactory,
  required Uint8List resolutionBytes,
  required Map<String, Map<String, Uint8List>> uriToLibrary_uriToUnitAstBytes,
}) {
  var _resolutionReader = SummaryDataReader(resolutionBytes);

  _resolutionReader.offset = _resolutionReader.bytes.length - 4 * 3;
  var resolutionLibrariesOffset = _resolutionReader.readUint32();
  var resolutionReferencesOffset = _resolutionReader.readUint32();
  var resolutionStringsOffset = _resolutionReader.readUint32();
  _resolutionReader.createStringTable(resolutionStringsOffset);

  var referenceReader = _ReferenceReader(
    elementFactory,
    _resolutionReader,
    resolutionReferencesOffset,
  );

  _resolutionReader.offset = resolutionLibrariesOffset;
  var resolutionLibraryOffsets = _resolutionReader.readUint30List();

  assert(
    uriToLibrary_uriToUnitAstBytes.length == resolutionLibraryOffsets.length,
  );

  // TODO(scheglov) Don't read anything, we know URIs.
  var libraryMap = <String, LibraryReader>{};
  for (var i = 0; i < resolutionLibraryOffsets.length; i++) {
    _resolutionReader.offset = resolutionLibraryOffsets[i];
    var libraryUriStr = _resolutionReader.readStringReference();
    var resolutionUnitOffsets = _resolutionReader.readUint30List();
    var exportsIndexList = _resolutionReader.readUint30List();

    var uriToUnitAstBytes = uriToLibrary_uriToUnitAstBytes[libraryUriStr]!;

    var reference = elementFactory.rootReference.getChild(libraryUriStr);
    var libraryReader = LibraryReaderForAstBytes._(
      elementFactory,
      uriToUnitAstBytes,
      _resolutionReader,
      referenceReader,
      reference,
      resolutionUnitOffsets,
      exportsIndexList,
    );
    libraryMap[libraryUriStr] = libraryReader;
  }

  return libraryMap;
}

class BundleReader {
  final SummaryDataReader _astReader;
  final SummaryDataReader _resolutionReader;

  bool _withInformative = false;

  final Map<String, LibraryReader> libraryMap = {};

  BundleReader({
    required LinkedElementFactory elementFactory,
    required Uint8List astBytes,
    required Uint8List resolutionBytes,
  })   : _astReader = SummaryDataReader(astBytes),
        _resolutionReader = SummaryDataReader(resolutionBytes) {
    _astReader.offset = 0;
    _withInformative = _astReader.readByte() == 1;

    _astReader.offset = _astReader.bytes.length - 4 * 2;
    var astLibrariesOffset = _astReader.readUint32();
    var astStringsOffset = _astReader.readUint32();
    _astReader.createStringTable(astStringsOffset);

    _resolutionReader.offset = _resolutionReader.bytes.length - 4 * 3;
    var resolutionLibrariesOffset = _resolutionReader.readUint32();
    var resolutionReferencesOffset = _resolutionReader.readUint32();
    var resolutionStringsOffset = _resolutionReader.readUint32();
    _resolutionReader.createStringTable(resolutionStringsOffset);

    var referenceReader = _ReferenceReader(
      elementFactory,
      _resolutionReader,
      resolutionReferencesOffset,
    );

    _astReader.offset = astLibrariesOffset;
    var astLibraryOffsets = _astReader.readUint30List();

    _resolutionReader.offset = resolutionLibrariesOffset;
    var resolutionLibraryOffsets = _resolutionReader.readUint30List();

    assert(astLibraryOffsets.length == resolutionLibraryOffsets.length);

    for (var i = 0; i < astLibraryOffsets.length; i++) {
      _astReader.offset = astLibraryOffsets[i];
      var name = _astReader.readStringReference();
      var nameOffset = _astReader.readUInt30() - 1;
      var nameLength = _astReader.readUInt30();
      var hasPartOfDirective = _astReader.readByte() != 0;
      var astUnitOffsets = _astReader.readUint30List();

      _resolutionReader.offset = resolutionLibraryOffsets[i];
      var libraryUriStr = _resolutionReader.readStringReference();
      var resolutionUnitOffsets = _resolutionReader.readUint30List();
      assert(astUnitOffsets.length == resolutionUnitOffsets.length);
      var exportsIndexList = _resolutionReader.readUint30List();

      var reference = elementFactory.rootReference.getChild(libraryUriStr);
      var libraryReader = LibraryReaderFromBundle._(
        elementFactory,
        _withInformative,
        _astReader,
        _resolutionReader,
        referenceReader,
        reference,
        name,
        nameOffset,
        nameLength,
        hasPartOfDirective,
        astUnitOffsets,
        resolutionUnitOffsets,
        exportsIndexList,
      );
      libraryMap[libraryUriStr] = libraryReader;
    }
  }

  LibraryReader getLibrary(String uriStr) {
    return libraryMap[uriStr]!;
  }
}

class ClassReader {
  final int membersOffset;

  ClassReader(this.membersOffset);
}

abstract class LibraryReader {
  final LinkedElementFactory _elementFactory;
  final SummaryDataReader _resolutionReader;
  final _ReferenceReader _referenceReader;
  final Reference reference;

  final Uint32List _resolutionUnitOffsets;
  final Uint32List _exportsIndexList;
  List<Reference>? _exports;

  List<UnitReader>? _units;

  LibraryReader._(
    this._elementFactory,
    this._resolutionReader,
    this._referenceReader,
    this.reference,
    this._resolutionUnitOffsets,
    this._exportsIndexList,
  );

  List<Reference> get exports {
    return _exports ??= _exportsIndexList
        .map((index) => _referenceReader.referenceOfIndex(index))
        .toList();
  }

  /// Is `true` if the defining unit has [PartOfDirective].
  bool get hasPartOfDirective;

  String get name;

  int get nameLength;

  int get nameOffset;

  List<UnitReader> get units;

  bool get withInformative;
}

/// Implementation of [LibraryReader] that reads ASTs for units from separate
/// byte buffers.
class LibraryReaderForAstBytes extends LibraryReader {
  final Map<String, Uint8List> _uriToUnitAstBytes;

  bool _hasNameRead = false;
  late final bool _withInformative;
  late final String _name;
  late final int _nameOffset;
  late final int _nameLength;
  late final bool _hasPartOfDirective;

  LibraryReaderForAstBytes._(
    LinkedElementFactory elementFactory,
    Map<String, Uint8List> uriToUnitAstBytes,
    SummaryDataReader resolutionReader,
    _ReferenceReader referenceReader,
    Reference reference,
    Uint32List resolutionUnitOffsets,
    Uint32List exportsIndexList,
  )   : _uriToUnitAstBytes = uriToUnitAstBytes,
        super._(
          elementFactory,
          resolutionReader,
          referenceReader,
          reference,
          resolutionUnitOffsets,
          exportsIndexList,
        ) {
    // TODO(scheglov) This fails when there are invalid URIs.
    // assert(_uriToUnitAstBytes.length == _resolutionUnitOffsets.length);
  }

  @override
  bool get hasPartOfDirective {
    _readName();
    return _hasPartOfDirective;
  }

  @override
  String get name {
    _readName();
    return _name;
  }

  @override
  int get nameLength {
    _readName();
    return _nameLength;
  }

  @override
  int get nameOffset {
    _readName();
    return _nameOffset;
  }

  @override
  List<UnitReader> get units {
    if (_units != null) return _units!;
    _units = [];

    for (var i = 0; i < _resolutionUnitOffsets.length; i++) {
      _resolutionReader.offset = _resolutionUnitOffsets[i];
      var unitUriStr = _resolutionReader.readStringReference();
      var isSynthetic = _resolutionReader.readByte() != 0;
      var isPart = _resolutionReader.readByte() != 0;
      String? partUriStr = _resolutionReader.readStringReference();
      if (!isPart) {
        partUriStr = null;
      }
      var resolutionDirectivesOffset = _resolutionReader.readUInt30();
      var resolutionDeclarationOffsets = _resolutionReader.readUint30List();

      // TODO(scheglov) Is this right?
      if (unitUriStr.isEmpty) {
        unitUriStr = 'null';
      }

      var astBytes = _uriToUnitAstBytes[unitUriStr]!;
      var astReader = SummaryDataReader(astBytes);
      astReader.offset = astBytes.length - 4 * 4;
      var headerOffset = astReader.readUint32();
      var indexOffset = astReader.readUint32();
      astReader.readUint32(); // library data
      var astStringsOffset = astReader.readUint32();
      astReader.createStringTable(astStringsOffset);

      _units!.add(
        UnitReader._(
          this,
          resolutionDirectivesOffset,
          resolutionDeclarationOffsets,
          reference.getChild('@unit').getChild(unitUriStr),
          isSynthetic,
          partUriStr,
          astReader,
          headerOffset,
          indexOffset,
        ),
      );
    }

    return _units!;
  }

  @override
  bool get withInformative {
    _readName();
    return _withInformative;
  }

  void _readName() {
    if (_hasNameRead) return;
    _hasNameRead = true;

    var uriStr = reference.name;
    var definingUnitBytes = _uriToUnitAstBytes[uriStr]!;
    var reader = SummaryDataReader(definingUnitBytes);
    reader.offset = definingUnitBytes.length - 4 * 2;
    var libraryDataOffset = reader.readUint32();
    var astStringsOffset = reader.readUint32();
    reader.createStringTable(astStringsOffset);

    reader.offset = libraryDataOffset;
    _name = reader.readStringReference();
    _nameOffset = reader.readUInt30() - 1;
    _nameLength = reader.readUInt30();
    _hasPartOfDirective = reader.readByte() != 0;
    _withInformative = reader.readByte() != 0;
  }
}

class LibraryReaderFromBundle extends LibraryReader {
  final SummaryDataReader _astReader;
  final Uint32List _astUnitOffsets;

  @override
  final String name;

  @override
  final int nameOffset;

  @override
  final int nameLength;

  @override
  final bool hasPartOfDirective;

  @override
  final bool withInformative;

  LibraryReaderFromBundle._(
    LinkedElementFactory elementFactory,
    this.withInformative,
    SummaryDataReader astReader,
    SummaryDataReader resolutionReader,
    _ReferenceReader referenceReader,
    Reference reference,
    this.name,
    this.nameOffset,
    this.nameLength,
    this.hasPartOfDirective,
    Uint32List astUnitOffsets,
    Uint32List resolutionUnitOffsets,
    Uint32List exportsIndexList,
  )   : _astReader = astReader,
        _astUnitOffsets = astUnitOffsets,
        super._(
          elementFactory,
          resolutionReader,
          referenceReader,
          reference,
          resolutionUnitOffsets,
          exportsIndexList,
        ) {
    assert(_astUnitOffsets.length == _resolutionUnitOffsets.length);
  }

  @override
  List<UnitReader> get units {
    if (_units != null) return _units!;
    _units = [];

    for (var i = 0; i < _astUnitOffsets.length; i++) {
      var astUnitOffset = _astUnitOffsets[i];
      var resolutionUnitOffset = _resolutionUnitOffsets[i];

      _astReader.offset = astUnitOffset;
      var headerOffset = _astReader.readUInt30();
      var indexOffset = _astReader.offset;

      _resolutionReader.offset = resolutionUnitOffset;
      var unitUriStr = _resolutionReader.readStringReference();
      var isSynthetic = _resolutionReader.readByte() != 0;
      var isPart = _resolutionReader.readByte() != 0;
      String? partUriStr = _resolutionReader.readStringReference();
      if (!isPart) {
        partUriStr = null;
      }
      var resolutionDirectivesOffset = _resolutionReader.readUInt30();
      var resolutionDeclarationOffsets = _resolutionReader.readUint30List();

      _units!.add(
        UnitReader._(
          this,
          resolutionDirectivesOffset,
          resolutionDeclarationOffsets,
          reference.getChild('@unit').getChild(unitUriStr),
          isSynthetic,
          partUriStr,
          _astReader,
          headerOffset,
          indexOffset,
        ),
      );
    }

    return _units!;
  }
}

class LinkedContext implements AstLinkedContext {
  final UnitReader _unitReader;
  final AstNode _node;
  final int _resolutionIndex;
  final Uint32List? _codeOffsetLengthList;
  final Uint32List _documentationTokenIndexList;

  @override
  final int codeOffset;

  @override
  final int codeLength;

  @override
  final bool isClassWithConstConstructor;

  bool _isApplied = false;

  bool _hasDocumentationComment = false;

  late final _UnitMemberReader _reader;

  LinkedContext(
    this._unitReader,
    this._node, {
    required this.codeOffset,
    required this.codeLength,
    this.isClassWithConstConstructor = false,
    Uint32List? codeOffsetLengthList,
    required int resolutionIndex,
    required Uint32List documentationTokenIndexList,
  })   : _resolutionIndex = resolutionIndex,
        _codeOffsetLengthList = codeOffsetLengthList,
        _documentationTokenIndexList = documentationTokenIndexList;

  @override
  List<ClassMember> get classMembers {
    var reader = _reader;
    if (reader is _ClassReader) {
      return reader.classMembers;
    } else if (_node is ClassTypeAlias) {
      return const <ClassMember>[];
    } else {
      throw UnimplementedError();
    }
  }

  @override
  // TODO: implement unitDirectives
  List<Directive> get unitDirectives => throw UnimplementedError();

  @override
  void applyResolution(LinkedUnitContext unitContext) {
    if (_isApplied) {
      return;
    }
    _isApplied = true;

    var localElements = <Element>[];
    var resolutionReader = LinkedResolutionReader(
      _unitReader,
      localElements,
      _unitReader._resolutionDeclarationsOffset[_resolutionIndex],
    );
    _node.accept(
      ApplyResolutionVisitor(
        unitContext,
        localElements,
        resolutionReader,
      ),
    );
  }

  @override
  int getVariableDeclarationCodeLength(VariableDeclaration node) {
    var variableList = node.parent as VariableDeclarationList;
    var variables = variableList.variables;
    for (var i = 0; i < variables.length; i++) {
      if (identical(variables[i], node)) {
        return _codeOffsetLengthList![2 * i + 1];
      }
    }
    throw StateError('No |$node| in: $variableList');
  }

  @override
  int getVariableDeclarationCodeOffset(VariableDeclaration node) {
    var variableList = node.parent as VariableDeclarationList;
    var variables = variableList.variables;
    for (var i = 0; i < variables.length; i++) {
      if (identical(variables[i], node)) {
        return _codeOffsetLengthList![2 * i + 0];
      }
    }
    throw StateError('No |$node| in: $variableList');
  }

  @override
  void readDocumentationComment() {
    if (_hasDocumentationComment) {
      return;
    }
    _hasDocumentationComment = true;

    if (_documentationTokenIndexList.isEmpty) {
      return;
    }

    var tokens = <Token>[];
    for (var lexemeIndex in _documentationTokenIndexList) {
      var lexeme = _unitReader.astReader.stringOfIndex(lexemeIndex);
      var token = TokenFactory.tokenFromString(lexeme);
      tokens.add(token);
    }

    var comment = astFactory.documentationComment(tokens);
    (_node as AnnotatedNodeImpl).documentationComment = comment;
  }
}

/// Helper for reading elements and types from their binary encoding.
class LinkedResolutionReader {
  final UnitReader _unitReader;

  /// The stack of [TypeParameterElement]s and [ParameterElement] that are
  /// available in the scope of [nextElement] and [nextType].
  ///
  /// This stack is shared with the client of the reader, and update mostly
  /// by the client. However it is also updated during [_readFunctionType].
  final List<Element> _localElements;

  /// The offset in [_Reader.bytes] from which we read resolution now.
  int _byteOffset = 0;

  LinkedResolutionReader(
    this._unitReader,
    this._localElements,
    this._byteOffset,
  );

  /// TODO(scheglov) Remove after fixing http://dartbug.com/44449
  int get byteOffset => _byteOffset;

  /// TODO(scheglov) Remove after fixing http://dartbug.com/44449
  Uint8List get bytes => _unitReader._resolutionReader.bytes;

  Element? nextElement() {
    var memberFlags = readByte();
    var element = _readRawElement();

    if (element == null) {
      return null;
    }

    if (memberFlags == Tag.RawElement) {
      return element;
    }

    if (memberFlags == Tag.MemberLegacyWithTypeArguments ||
        memberFlags == Tag.MemberWithTypeArguments) {
      var arguments = _readTypeList();
      // TODO(scheglov) why to check for empty? If we have this flags.
      if (arguments.isNotEmpty) {
        var typeParameters =
            (element.enclosingElement as TypeParameterizedElement)
                .typeParameters;
        var substitution = Substitution.fromPairs(typeParameters, arguments);
        element =
            ExecutableMember.from2(element as ExecutableElement, substitution);
      }
    }

    if (memberFlags == Tag.MemberLegacyWithTypeArguments) {
      return Member.legacy(element);
    }

    if (memberFlags == Tag.MemberWithTypeArguments) {
      return element;
    }

    throw UnimplementedError('memberFlags: $memberFlags');
  }

  String nextString() {
    var index = _readUInt30();
    return _unitReader._resolutionReader.stringOfIndex(index);
  }

  DartType? nextType() {
    var tag = readByte();
    if (tag == Tag.NullType) {
      return null;
    } else if (tag == Tag.DynamicType) {
      var type = DynamicTypeImpl.instance;
      return _readAliasElementArguments(type);
    } else if (tag == Tag.FunctionType) {
      var type = _readFunctionType();
      return _readAliasElementArguments(type);
    } else if (tag == Tag.InterfaceType) {
      var element = nextElement() as ClassElement;
      var typeArguments = _readTypeList();
      var nullability = _readNullability();
      var type = InterfaceTypeImpl(
        element: element,
        typeArguments: typeArguments,
        nullabilitySuffix: nullability,
      );
      return _readAliasElementArguments(type);
    } else if (tag == Tag.InterfaceType_noTypeArguments_none) {
      var element = nextElement() as ClassElement;
      var type = InterfaceTypeImpl(
        element: element,
        typeArguments: const <DartType>[],
        nullabilitySuffix: NullabilitySuffix.none,
      );
      return _readAliasElementArguments(type);
    } else if (tag == Tag.InterfaceType_noTypeArguments_question) {
      var element = nextElement() as ClassElement;
      var type = InterfaceTypeImpl(
        element: element,
        typeArguments: const <DartType>[],
        nullabilitySuffix: NullabilitySuffix.question,
      );
      return _readAliasElementArguments(type);
    } else if (tag == Tag.InterfaceType_noTypeArguments_star) {
      var element = nextElement() as ClassElement;
      var type = InterfaceTypeImpl(
        element: element,
        typeArguments: const <DartType>[],
        nullabilitySuffix: NullabilitySuffix.star,
      );
      return _readAliasElementArguments(type);
    } else if (tag == Tag.NeverType) {
      var nullability = _readNullability();
      var type = NeverTypeImpl.instance.withNullability(nullability);
      return _readAliasElementArguments(type);
    } else if (tag == Tag.TypeParameterType) {
      var element = nextElement() as TypeParameterElement;
      var nullability = _readNullability();
      var type = TypeParameterTypeImpl(
        element: element,
        nullabilitySuffix: nullability,
      );
      return _readAliasElementArguments(type);
    } else if (tag == Tag.VoidType) {
      var type = VoidTypeImpl.instance;
      return _readAliasElementArguments(type);
    } else {
      throw UnimplementedError('$tag');
    }
  }

  int readByte() {
    return _unitReader._resolutionReader.bytes[_byteOffset++];
  }

  List<String> readStringList() {
    var values = <String>[];
    var length = _readUInt30();
    for (var i = 0; i < length; i++) {
      var value = _readStringReference();
      values.add(value);
    }
    return values;
  }

  int readUInt30() {
    var byte = readByte();
    if (byte & 0x80 == 0) {
      // 0xxxxxxx
      return byte;
    } else if (byte & 0x40 == 0) {
      // 10xxxxxx
      return ((byte & 0x3F) << 8) | readByte();
    } else {
      // 11xxxxxx
      return ((byte & 0x3F) << 24) |
          (readByte() << 16) |
          (readByte() << 8) |
          readByte();
    }
  }

  DartType _readAliasElementArguments(DartType type) {
    var aliasElement = _readRawElement();
    if (aliasElement is TypeAliasElement) {
      var aliasArguments = _readTypeList();
      if (type is DynamicType) {
        // TODO(scheglov) add support for `dynamic` aliasing
        return type;
      } else if (type is FunctionType) {
        return FunctionTypeImpl(
          typeFormals: type.typeFormals,
          parameters: type.parameters,
          returnType: type.returnType,
          nullabilitySuffix: type.nullabilitySuffix,
          aliasElement: aliasElement,
          aliasArguments: aliasArguments,
        );
      } else if (type is InterfaceType) {
        return InterfaceTypeImpl(
          element: type.element,
          typeArguments: type.typeArguments,
          nullabilitySuffix: type.nullabilitySuffix,
          aliasElement: aliasElement,
          aliasArguments: aliasArguments,
        );
      } else if (type is TypeParameterType) {
        return TypeParameterTypeImpl(
          element: type.element,
          nullabilitySuffix: type.nullabilitySuffix,
          aliasElement: aliasElement,
          aliasArguments: aliasArguments,
        );
      } else if (type is VoidType) {
        // TODO(scheglov) add support for `void` aliasing
        return type;
      } else {
        throw UnimplementedError('${type.runtimeType}');
      }
    }
    return type;
  }

  /// TODO(scheglov) Optimize for write/read of types without type parameters.
  FunctionType _readFunctionType() {
    var typeParameters = <TypeParameterElement>[];
    var typeParametersLength = _readUInt30();
    for (var i = 0; i < typeParametersLength; i++) {
      var name = _readStringReference();
      var element = TypeParameterElementImpl.synthetic(name);
      typeParameters.add(element);
      _localElements.add(element);
    }
    for (var i = 0; i < typeParametersLength; i++) {
      var element = typeParameters[i] as TypeParameterElementImpl;
      var bound = nextType();
      element.bound = bound;
    }

    var returnType = nextType()!;

    var formalParameters = <ParameterElement>[];
    var formalParametersLength = _readUInt30();
    for (var i = 0; i < formalParametersLength; i++) {
      var kindIndex = readByte();
      var type = nextType()!;
      var name = nextString();
      formalParameters.add(
        ParameterElementImpl.synthetic(
          name,
          type,
          _formalParameterKind(kindIndex),
        ),
      );
    }

    var nullability = _readNullability();

    _localElements.length -= typeParametersLength;

    return FunctionTypeImpl(
      typeFormals: typeParameters,
      parameters: formalParameters,
      returnType: returnType,
      nullabilitySuffix: nullability,
    );
  }

  NullabilitySuffix _readNullability() {
    var index = readByte();
    return NullabilitySuffix.values[index];
  }

  Element? _readRawElement() {
    var index = _readUInt30();

    if ((index & 0x1) == 0x1) {
      return _localElements[index >> 1];
    }

    var referenceIndex = index >> 1;
    var referenceReader = _unitReader._referenceReader;
    var reference = referenceReader.referenceOfIndex(referenceIndex);

    var elementFactory = _unitReader.elementFactory;
    return elementFactory.elementOfReference(reference);
  }

  String _readStringReference() {
    var index = _readUInt30();
    return _unitReader._resolutionReader.stringOfIndex(index);
  }

  List<DartType> _readTypeList() {
    var types = <DartType>[];
    var length = _readUInt30();
    for (var i = 0; i < length; i++) {
      var argument = nextType()!;
      types.add(argument);
    }
    return types;
  }

  int _readUInt30() {
    var byte = readByte();
    if (byte & 0x80 == 0) {
      // 0xxxxxxx
      return byte;
    } else if (byte & 0x40 == 0) {
      // 10xxxxxx
      return ((byte & 0x3F) << 8) | readByte();
    } else {
      // 11xxxxxx
      return ((byte & 0x3F) << 24) |
          (readByte() << 16) |
          (readByte() << 8) |
          readByte();
    }
  }

  static ParameterKind _formalParameterKind(int encoding) {
    if (encoding == Tag.ParameterKindRequiredPositional) {
      return ParameterKind.REQUIRED;
    } else if (encoding == Tag.ParameterKindOptionalPositional) {
      return ParameterKind.POSITIONAL;
    } else if (encoding == Tag.ParameterKindRequiredNamed) {
      return ParameterKind.NAMED_REQUIRED;
    } else if (encoding == Tag.ParameterKindOptionalNamed) {
      return ParameterKind.NAMED;
    } else {
      throw StateError('Unexpected parameter kind encoding: $encoding');
    }
  }
}

class SummaryDataForCompilationUnit {
  final int codeLength;

  SummaryDataForCompilationUnit(this.codeLength);
}

class SummaryDataForFormalParameter {
  final int codeOffset;
  final int codeLength;

  SummaryDataForFormalParameter({
    required this.codeOffset,
    required this.codeLength,
  });
}

class SummaryDataForLibraryDirective {
  final UnitReader _unitReader;
  final LibraryDirectiveImpl _node;
  final Uint32List _documentationTokenIndexList;
  bool _hasDocumentationComment = false;

  SummaryDataForLibraryDirective(
    this._unitReader,
    this._node, {
    required Uint32List documentationTokenIndexList,
  }) : _documentationTokenIndexList = documentationTokenIndexList {
    _node.summaryData = this;
  }

  void readDocumentationComment() {
    if (_hasDocumentationComment) {
      return;
    }
    _hasDocumentationComment = true;

    if (_documentationTokenIndexList.isEmpty) {
      return;
    }

    var tokens = <Token>[];
    for (var lexemeIndex in _documentationTokenIndexList) {
      var lexeme = _unitReader.astReader.stringOfIndex(lexemeIndex);
      var token = TokenFactory.tokenFromString(lexeme);
      tokens.add(token);
    }

    var comment = astFactory.documentationComment(tokens);
    _node.documentationComment = comment;
  }
}

class SummaryDataForTypeParameter {
  final int codeOffset;
  final int codeLength;

  SummaryDataForTypeParameter({
    required this.codeOffset,
    required this.codeLength,
  });
}

class UnitReader implements ReferenceNodeAccessor {
  final LibraryReader libraryReader;

  final Reference reference;

  final bool isSynthetic;

  /// If a part, the URI that is used in the [PartDirective].
  /// Or `null` for the defining unit.
  final String? partUriStr;

  final int _directivesResolutionOffset;
  bool _isDirectivesResolutionApplied = false;

  final Uint32List _resolutionDeclarationsOffset;

  final SummaryDataReader astReader;

  late final int _directivesOffset;
  final List<_UnitMemberReader> _memberReaders = [];

  late final CompilationUnitImpl _unit;
  bool _hasDirectives = false;
  bool _hasDeclarations = false;

  UnitReader._(
    this.libraryReader,
    this._directivesResolutionOffset,
    this._resolutionDeclarationsOffset,
    this.reference,
    this.isSynthetic,
    this.partUriStr,
    this.astReader,
    int headerOffset,
    int indexOffset,
  ) {
    reference.nodeAccessor = this;

    astReader.offset = headerOffset;
    var languageVersion = _readLanguageVersion();
    var featureSetEncoded = astReader.readUint8List();
    var lineInfo = _readLineInfo();
    var codeLength = astReader.readUInt30();
    var featureSet = ExperimentStatus.fromStorage(featureSetEncoded);
    _directivesOffset = astReader.offset;

    _unit = astFactory.compilationUnit(
      beginToken: Tokens.BANG,
      // TODO(scheglov)
      // scriptTag: _readNode(data.compilationUnit_scriptTag),
      directives: [],
      declarations: [],
      endToken: Tokens.BANG,
      featureSet: featureSet,
    );
    _unit.languageVersion = languageVersion;
    _unit.lineInfo = lineInfo;
    _unit.summaryData = SummaryDataForCompilationUnit(codeLength);

    astReader.offset = indexOffset;
    _readIndex2();
  }

  LinkedElementFactory get elementFactory => libraryReader._elementFactory;

  /// TODO(scheglov)
  /// This methods breaks lazy loading, and loads everything eagerly.
  /// We use it because of `unitElement.types` for example, when we are
  /// explicitly asked for all [ClassDeclaration]s and [ClassTypeAlias]s.
  @Deprecated('review it')
  @override
  CompilationUnit get node {
    readDirectives();
    readDeclarations();
    return _unit;
  }

  CompilationUnit get unit => _unit;

  String get uriStr => reference.name;

  bool get withInformative => libraryReader.withInformative;

  _ReferenceReader get _referenceReader => libraryReader._referenceReader;

  SummaryDataReader get _resolutionReader => libraryReader._resolutionReader;

  /// Apply resolution to directives.
  void applyDirectivesResolution(LinkedUnitContext unitContext) {
    if (_isDirectivesResolutionApplied) {
      return;
    }
    _isDirectivesResolutionApplied = true;

    var localElements = <Element>[];
    var resolutionReader = LinkedResolutionReader(
      this,
      localElements,
      _directivesResolutionOffset,
    );
    for (var directive in _unit.directives) {
      directive.accept(
        ApplyResolutionVisitor(
          unitContext,
          localElements,
          resolutionReader,
        ),
      );
    }
  }

  void readDeclarations() {
    if (!_hasDeclarations) {
      _hasDeclarations = true;
      for (var reader in _memberReaders) {
        reader.node;
      }
    }
  }

  /// Ensure that directives are read in this unit.
  void readDirectives() {
    if (!_hasDirectives) {
      _hasDirectives = true;
      astReader.offset = _directivesOffset;
      var length = astReader.readUInt30();
      for (var i = 0; i < length; i++) {
        var astReader = AstBinaryReader(
          reader: this,
        );
        var directive = astReader.readNode() as Directive;
        _unit.directives.add(directive);
      }
    }
  }

  @override
  void readIndex() {}

  /// Read the index of declarations in this unit, and add `null`s into
  /// [CompilationUnit.declarations] as placeholders.
  ///
  /// TODO(scheglov) we don't need both this method, and [readIndex].
  void _readIndex2() {
    var unitReference = reference;
    var length = astReader.readUInt30();
    for (var i = 0; i < length; i++) {
      var offset = astReader.readUInt30();
      var tag = astReader.readByte();
      if (tag == Tag.Class) {
        var name = astReader.readStringReference();
        var indexOffset = astReader.readUInt30();
        var reference = unitReference.getChild('@class').getChild(name);
        _memberReaders.add(
          _ClassReader(
            unitReader: this,
            reference: reference,
            offset: offset,
            unit: _unit,
            indexOffset: indexOffset,
          ),
        );
      } else if (tag == Tag.ClassTypeAlias) {
        var name = astReader.readStringReference();
        var reader = _UnitMemberReader(this, offset, _unit);
        _memberReaders.add(reader);
        unitReference.getChild('@class').getChild(name).nodeAccessor = reader;
      } else if (tag == Tag.EnumDeclaration) {
        var name = astReader.readStringReference();
        var reader = _UnitMemberReader(this, offset, _unit);
        _memberReaders.add(reader);
        unitReference.getChild('@enum').getChild(name).nodeAccessor = reader;
      } else if (tag == Tag.ExtensionDeclaration) {
        var name = astReader.readStringReference();
        var indexOffset = astReader.readUInt30();
        var reference = unitReference.getChild('@extension').getChild(name);
        _memberReaders.add(
          _ClassReader(
            unitReader: this,
            reference: reference,
            offset: offset,
            unit: _unit,
            indexOffset: indexOffset,
          ),
        );
      } else if (tag == Tag.FunctionDeclaration) {
        var name = astReader.readStringReference();
        var reader = _UnitMemberReader(this, offset, _unit);
        _memberReaders.add(reader);
        var containerRef = unitReference.getChild('@function');
        containerRef.getChild(name).nodeAccessor = reader;
      } else if (tag == Tag.FunctionDeclaration_getter) {
        var name = astReader.readStringReference();
        var reader = _UnitMemberReader(this, offset, _unit);
        _memberReaders.add(reader);
        var getterRef = unitReference.getChild('@getter');
        getterRef.getChild(name).nodeAccessor = reader;
        var variableRef = unitReference.getChild('@variable');
        variableRef.getChild(name).nodeAccessor ??= reader;
      } else if (tag == Tag.FunctionDeclaration_setter) {
        var name = astReader.readStringReference();
        var reader = _UnitMemberReader(this, offset, _unit);
        _memberReaders.add(reader);
        var setterRef = unitReference.getChild('@setter');
        setterRef.getChild(name).nodeAccessor = reader;
        var variableRef = unitReference.getChild('@variable');
        variableRef.getChild(name).nodeAccessor ??= reader;
      } else if (tag == Tag.GenericTypeAlias) {
        var name = astReader.readStringReference();
        var reader = _UnitMemberReader(this, offset, _unit);
        _memberReaders.add(reader);
        unitReference.getChild('@typeAlias').getChild(name).nodeAccessor =
            reader;
      } else if (tag == Tag.FunctionTypeAlias) {
        var name = astReader.readStringReference();
        var reader = _UnitMemberReader(this, offset, _unit);
        _memberReaders.add(reader);
        unitReference.getChild('@typeAlias').getChild(name).nodeAccessor =
            reader;
      } else if (tag == Tag.MixinDeclaration) {
        var name = astReader.readStringReference();
        var indexOffset = astReader.readUInt30();
        var reference = unitReference.getChild('@mixin').getChild(name);
        _memberReaders.add(
          _ClassReader(
            unitReader: this,
            reference: reference,
            offset: offset,
            unit: _unit,
            indexOffset: indexOffset,
          ),
        );
      } else if (tag == Tag.TopLevelVariableDeclaration) {
        var reader = _UnitMemberReader(this, offset, _unit);
        var length = astReader.readUInt30();
        for (var i = 0; i < length; i++) {
          var name = astReader.readStringReference();
          _memberReaders.add(reader);
          unitReference.getChild('@getter').getChild(name).nodeAccessor =
              reader;
          // TODO(scheglov) only if not final/const
          // Crash in language_2/export/local_export_test.dart
          unitReference.getChild('@setter').getChild(name).nodeAccessor =
              reader;
        }
      } else {
        // TODO(scheglov) implement
      }
    }
  }

  LibraryLanguageVersion _readLanguageVersion() {
    var packageMajor = astReader.readUInt30();
    var packageMinor = astReader.readUInt30();
    var overrideMajor = astReader.readUInt30();
    var overrideMinor = astReader.readUInt30();
    return LibraryLanguageVersion(
      package: Version(packageMajor, packageMinor, 0),
      override: overrideMajor > 0
          ? Version(overrideMajor - 1, overrideMinor - 1, 0)
          : null,
    );
  }

  LineInfo _readLineInfo() {
    var lineStarts = astReader.readUint30List();
    return LineInfo(lineStarts);
  }
}

class _ClassMemberMock extends AstNodeImpl implements ClassMemberImpl {
  static final instance = _ClassMemberMock();

  @override
  AstNode? parent;

  @override
  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}

class _ClassMemberReader implements ReferenceNodeAccessor {
  final UnitReader unitReader;
  final int offset;
  final List<ClassMember> _members;
  final int _membersIndex;
  ClassMemberImpl? _node;

  _ClassMemberReader(this.unitReader, this.offset, this._members)
      : _membersIndex = _members.length {
    _members.add(_ClassMemberMock.instance);
  }

  @override
  AstNode get node {
    if (_node == null) {
      var astReader = AstBinaryReader(
        reader: unitReader,
      );
      unitReader.astReader.offset = offset;
      _node = astReader.readNode() as ClassMemberImpl;
      _members[_membersIndex] = _node!;
    }
    return _node!;
  }

  @override
  void readIndex() {}
}

class _ClassReader extends _UnitMemberReader {
  final Reference reference;
  final int indexOffset;

  bool _hasIndex = false;
  final List<_ClassMemberReader> _classMemberReaders = [];
  late final List<ClassMember> _classMembers;

  _ClassReader({
    required this.reference,
    required UnitReader unitReader,
    required int offset,
    required CompilationUnitImpl unit,
    required this.indexOffset,
  }) : super(unitReader, offset, unit) {
    reference.nodeAccessor ??= this;
  }

  List<_ClassMemberReader> get classMemberReaders {
    readIndex();
    return _classMemberReaders;
  }

  List<ClassMember> get classMembers {
    return classMemberReaders.map((e) => e.node as ClassMember).toList();
  }

  @override
  void readIndex() {
    if (_hasIndex) return;
    _hasIndex = true;

    var node = _node;
    if (node == null) {
      throw StateError('The class node must be read before reading members.');
    }

    if (node is ClassDeclarationImpl) {
      _classMembers = node.members;
    } else if (node is ExtensionDeclarationImpl) {
      _classMembers = node.members;
    } else if (node is MixinDeclarationImpl) {
      _classMembers = node.members;
    } else {
      throw StateError('(${node.runtimeType}) $node');
    }

    unitReader.astReader.offset = indexOffset;

    var length = unitReader.astReader.readUInt30();
    for (var i = 0; i < length; i++) {
      var offset = unitReader.astReader.readUInt30();
      var tag = unitReader.astReader.readByte();
      if (tag == Tag.ConstructorDeclaration) {
        var reader = _ClassMemberReader(unitReader, offset, _classMembers);
        _classMemberReaders.add(reader);
        var name = unitReader.astReader.readStringReference();
        var reference = this.reference.getChild('@constructor').getChild(name);
        reference.nodeAccessor ??= reader;
      } else if (tag == Tag.MethodDeclaration) {
        var reader = _ClassMemberReader(unitReader, offset, _classMembers);
        _classMemberReaders.add(reader);
        var name = unitReader.astReader.readStringReference();
        var reference = this.reference.getChild('@method').getChild(name);
        reference.nodeAccessor ??= reader;
      } else if (tag == Tag.MethodDeclaration_getter) {
        var reader = _ClassMemberReader(unitReader, offset, _classMembers);
        _classMemberReaders.add(reader);
        var name = unitReader.astReader.readStringReference();
        var reference = this.reference.getChild('@getter').getChild(name);
        reference.nodeAccessor ??= reader;
      } else if (tag == Tag.MethodDeclaration_setter) {
        var reader = _ClassMemberReader(unitReader, offset, _classMembers);
        _classMemberReaders.add(reader);
        var name = unitReader.astReader.readStringReference();
        var reference = this.reference.getChild('@setter').getChild(name);
        reference.nodeAccessor ??= reader;
      } else if (tag == Tag.FieldDeclaration) {
        var reader = _ClassMemberReader(unitReader, offset, _classMembers);
        _classMemberReaders.add(reader);
        var length = unitReader.astReader.readUInt30();
        for (var i = 0; i < length; i++) {
          var name = unitReader.astReader.readStringReference();
          var fieldRef = reference.getChild('@field').getChild(name);
          fieldRef.nodeAccessor ??= reader;
          var getterRef = reference.getChild('@getter').getChild(name);
          getterRef.nodeAccessor ??= reader;
          var setterRef = reference.getChild('@setter').getChild(name);
          setterRef.nodeAccessor ??= reader;
        }
      } else {
        throw UnimplementedError('tag: $tag');
      }
    }
  }
}

class _CompilationUnitMemberMock extends AstNodeImpl
    implements CompilationUnitMemberImpl {
  static final instance = _CompilationUnitMemberMock();

  @override
  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}

class _ReferenceReader {
  final LinkedElementFactory elementFactory;
  final SummaryDataReader _reader;
  late final Uint32List _parents;
  late final Uint32List _names;
  late final List<Reference?> _references;

  _ReferenceReader(this.elementFactory, this._reader, int offset) {
    _reader.offset = offset;
    _parents = _reader.readUint30List();
    _names = _reader.readUint30List();
    assert(_parents.length == _names.length);

    _references = List.filled(_names.length, null);
  }

  Reference referenceOfIndex(int index) {
    var reference = _references[index];
    if (reference != null) {
      return reference;
    }

    if (index == 0) {
      reference = elementFactory.rootReference;
      _references[index] = reference;
      return reference;
    }

    var nameIndex = _names[index];
    var name = _reader.stringOfIndex(nameIndex);

    var parentIndex = _parents[index];
    var parent = referenceOfIndex(parentIndex);

    reference = parent.getChild(name);
    _references[index] = reference;

    return reference;
  }
}

class _UnitMemberReader implements ReferenceNodeAccessor {
  final UnitReader unitReader;
  final int offset;
  final CompilationUnitImpl _unit;
  final int _index;
  CompilationUnitMemberImpl? _node;

  _UnitMemberReader(this.unitReader, this.offset, this._unit)
      : _index = _unit.declarations.length {
    _unit.declarations.add(_CompilationUnitMemberMock.instance);
  }

  @override
  AstNode get node {
    if (_node == null) {
      var astReader = AstBinaryReader(
        reader: unitReader,
      );
      unitReader.astReader.offset = offset;
      _node = astReader.readNode() as CompilationUnitMemberImpl;
      _unit.declarations[_index] = _node!;

      var hasLinkedContext = _node as HasAstLinkedContext;
      var linkedContext = hasLinkedContext.linkedContext as LinkedContext;
      linkedContext._reader = this;
    }
    return _node!;
  }

  @override
  void readIndex() {}
}
