// Copyright (c) 2019, 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/src/binary/binary_reader.dart';
import 'package:analyzer/src/binary/binary_writer.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/utilities/growable_type_data.dart';
import 'package:analyzer/src/utilities/uri_cache.dart';

final class BuiltInReference extends Reference implements ExportableReference {
  final LibraryReference library;

  final _BuiltInReferenceKind _kind;

  BuiltInReference._({
    required this.library,
    required _BuiltInReferenceKind kind,
  }) : _kind = kind,
       super._();
}

sealed class DeclarationReference extends Reference {
  /// The stable identity component for this declaration under its enclosing
  /// reference.
  ///
  /// This key is internal to reference identity. It is not necessarily the
  /// user-visible name written in source, because unnamed and duplicate
  /// declarations receive generated keys.
  final String _key;

  DeclarationReference._({required String key}) : _key = key, super._();
}

sealed class ExportableReference implements Reference {}

final class LeafTopLevelReference extends TopLevelReference {
  LeafTopLevelReference._({
    required super.library,
    required super.key,
    required super.kind,
  }) : super._();
}

final class LibraryReference extends Reference {
  final String uriString;

  final List<Map<String, TopLevelReference>?> _topLevelsByKind = List.filled(
    _TopLevelReferenceKind.values.length,
    null,
  );
  List<BuiltInReference?>? _builtInByKind;

  LibraryReference._({required this.uriString}) : super._();

  @override
  List<Reference> get children => [
    for (var byKey in _topLevelsByKind) ...?byKey?.values,
    if (_builtInByKind case var builtInByKind?)
      for (var builtIn in builtInByKind) ?builtIn,
  ];

  BuiltInReference get dynamicRef {
    assert(uriString == 'dart:core');
    return _builtIn(_BuiltInReferenceKind.dynamic_);
  }

  BuiltInReference get neverRef {
    assert(uriString == 'dart:core');
    return _builtIn(_BuiltInReferenceKind.never_);
  }

  Uri get uri => uriCache.parse(uriString);

  MemberContainerReference declareClass(String key) {
    return _declareMemberContainer(
      kind: _TopLevelReferenceKind.class_,
      key: key,
    );
  }

  MemberContainerReference declareEnum(String key) {
    return _declareMemberContainer(
      kind: _TopLevelReferenceKind.enum_,
      key: key,
    );
  }

  MemberContainerReference declareExtension(String key) {
    return _declareMemberContainer(
      kind: _TopLevelReferenceKind.extension_,
      key: key,
    );
  }

  MemberContainerReference declareExtensionType(String key) {
    return _declareMemberContainer(
      kind: _TopLevelReferenceKind.extensionType,
      key: key,
    );
  }

  TopLevelReference declareGetter(String key) {
    return _declareTopLevel(kind: _TopLevelReferenceKind.getter, key: key);
  }

  MemberContainerReference declareMixin(String key) {
    return _declareMemberContainer(
      kind: _TopLevelReferenceKind.mixin_,
      key: key,
    );
  }

  TopLevelReference declareSetter(String key) {
    return _declareTopLevel(kind: _TopLevelReferenceKind.setter, key: key);
  }

  TopLevelReference declareTopLevelFunction(String key) {
    return _declareTopLevel(kind: _TopLevelReferenceKind.function, key: key);
  }

  TopLevelReference declareTopLevelVariable(String key) {
    return _declareTopLevel(
      kind: _TopLevelReferenceKind.topLevelVariable,
      key: key,
    );
  }

  TopLevelReference declareTypeAlias(String key) {
    return _declareTopLevel(kind: _TopLevelReferenceKind.typeAlias, key: key);
  }

  MemberContainerReference getOrCreateClass(String key) {
    return _getOrCreateMemberContainer(
      kind: _TopLevelReferenceKind.class_,
      key: key,
    );
  }

  MemberContainerReference getOrCreateEnum(String key) {
    return _getOrCreateMemberContainer(
      kind: _TopLevelReferenceKind.enum_,
      key: key,
    );
  }

  MemberContainerReference getOrCreateExtension(String key) {
    return _getOrCreateMemberContainer(
      kind: _TopLevelReferenceKind.extension_,
      key: key,
    );
  }

  MemberContainerReference getOrCreateExtensionType(String key) {
    return _getOrCreateMemberContainer(
      kind: _TopLevelReferenceKind.extensionType,
      key: key,
    );
  }

  TopLevelReference getOrCreateGetter(String key) {
    return _getOrCreateTopLevel(kind: _TopLevelReferenceKind.getter, key: key);
  }

  MemberContainerReference getOrCreateMixin(String key) {
    return _getOrCreateMemberContainer(
      kind: _TopLevelReferenceKind.mixin_,
      key: key,
    );
  }

  TopLevelReference getOrCreateSetter(String key) {
    return _getOrCreateTopLevel(kind: _TopLevelReferenceKind.setter, key: key);
  }

  TopLevelReference getOrCreateTopLevelFunction(String key) {
    return _getOrCreateTopLevel(
      kind: _TopLevelReferenceKind.function,
      key: key,
    );
  }

  TopLevelReference getOrCreateTopLevelVariable(String key) {
    return _getOrCreateTopLevel(
      kind: _TopLevelReferenceKind.topLevelVariable,
      key: key,
    );
  }

  TopLevelReference getOrCreateTypeAlias(String key) {
    return _getOrCreateTopLevel(
      kind: _TopLevelReferenceKind.typeAlias,
      key: key,
    );
  }

  BuiltInReference _builtIn(_BuiltInReferenceKind kind) {
    var builtInByKind = _builtInByKind ??= List.filled(
      _BuiltInReferenceKind.values.length,
      null,
    );
    return builtInByKind[kind.index] ??= BuiltInReference._(
      library: this,
      kind: kind,
    );
  }

  TopLevelReference _createTopLevelReference(
    _TopLevelReferenceKind kind,
    String key,
  ) {
    if (kind.hasMembers) {
      return MemberContainerReference._(library: this, key: key, kind: kind);
    }
    return LeafTopLevelReference._(library: this, key: key, kind: kind);
  }

  MemberContainerReference _declareMemberContainer({
    required _TopLevelReferenceKind kind,
    required String key,
  }) {
    var byKey = _topLevelByKey(kind);
    if (byKey[key] != null) {
      throw StateError('Duplicate reference key: $key');
    }

    return byKey[key] = MemberContainerReference._(
      library: this,
      key: key,
      kind: kind,
    );
  }

  TopLevelReference _declareTopLevel({
    required _TopLevelReferenceKind kind,
    required String key,
  }) {
    return Reference._declare(
      byKey: _topLevelByKey(kind),
      key: key,
      create: (key) => _createTopLevelReference(kind, key),
    );
  }

  MemberContainerReference _getOrCreateMemberContainer({
    required _TopLevelReferenceKind kind,
    required String key,
  }) {
    var byKey = _topLevelByKey(kind);
    if (byKey[key] case MemberContainerReference existing) {
      return existing;
    }

    var result = MemberContainerReference._(
      library: this,
      key: key,
      kind: kind,
    );
    byKey[key] = result;
    return result;
  }

  TopLevelReference _getOrCreateTopLevel({
    required _TopLevelReferenceKind kind,
    required String key,
  }) {
    return _topLevelByKey(kind)[key] ??= _createTopLevelReference(kind, key);
  }

  Map<String, TopLevelReference> _topLevelByKey(_TopLevelReferenceKind kind) {
    return _topLevelsByKind[kind.index] ??= {};
  }
}

final class LibraryReferenceBuilder {
  final LibraryReference reference;
  final Map<Reference, _KeyAllocator> _keyAllocatorByReference = Map.identity();

  LibraryReferenceBuilder(this.reference);

  MemberContainerReference declareClass(String? name) {
    return reference.declareClass(
      _allocateTopLevelKey(kind: _TopLevelReferenceKind.class_, name: name),
    );
  }

  MemberContainerReference declareEnum(String? name) {
    return reference.declareEnum(
      _allocateTopLevelKey(kind: _TopLevelReferenceKind.enum_, name: name),
    );
  }

  MemberContainerReference declareExtension(String? name) {
    return reference.declareExtension(
      _allocateTopLevelKey(kind: _TopLevelReferenceKind.extension_, name: name),
    );
  }

  MemberContainerReference declareExtensionType(String? name) {
    return reference.declareExtensionType(
      _allocateTopLevelKey(
        kind: _TopLevelReferenceKind.extensionType,
        name: name,
      ),
    );
  }

  TopLevelReference declareGetter(String? name) {
    return reference.declareGetter(
      _allocateTopLevelKey(kind: _TopLevelReferenceKind.getter, name: name),
    );
  }

  MemberReference declareMemberConstructor({
    required MemberContainerReference container,
    required String? name,
  }) {
    return container.declareConstructor(
      _allocateMemberKey(
        container: container,
        kind: _MemberReferenceKind.constructor,
        name: name,
      ),
    );
  }

  MemberReference declareMemberField({
    required MemberContainerReference container,
    required String? name,
  }) {
    return container.declareField(
      _allocateMemberKey(
        container: container,
        kind: _MemberReferenceKind.field,
        name: name,
      ),
    );
  }

  MemberReference declareMemberGetter({
    required MemberContainerReference container,
    required String? name,
  }) {
    return container.declareGetter(
      _allocateMemberKey(
        container: container,
        kind: _MemberReferenceKind.getter,
        name: name,
      ),
    );
  }

  MemberReference declareMemberMethod({
    required MemberContainerReference container,
    required String? name,
  }) {
    return container.declareMethod(
      _allocateMemberKey(
        container: container,
        kind: _MemberReferenceKind.method,
        name: name,
      ),
    );
  }

  MemberReference declareMemberSetter({
    required MemberContainerReference container,
    required String? name,
  }) {
    return container.declareSetter(
      _allocateMemberKey(
        container: container,
        kind: _MemberReferenceKind.setter,
        name: name,
      ),
    );
  }

  MemberContainerReference declareMixin(String? name) {
    return reference.declareMixin(
      _allocateTopLevelKey(kind: _TopLevelReferenceKind.mixin_, name: name),
    );
  }

  TopLevelReference declareSetter(String? name) {
    return reference.declareSetter(
      _allocateTopLevelKey(kind: _TopLevelReferenceKind.setter, name: name),
    );
  }

  TopLevelReference declareTopLevelFunction(String? name) {
    return reference.declareTopLevelFunction(
      _allocateTopLevelKey(kind: _TopLevelReferenceKind.function, name: name),
    );
  }

  TopLevelReference declareTopLevelVariable(String? name) {
    return reference.declareTopLevelVariable(
      _allocateTopLevelKey(
        kind: _TopLevelReferenceKind.topLevelVariable,
        name: name,
      ),
    );
  }

  TopLevelReference declareTypeAlias(String? name) {
    return reference.declareTypeAlias(
      _allocateTopLevelKey(kind: _TopLevelReferenceKind.typeAlias, name: name),
    );
  }

  String _allocateMemberKey({
    required MemberContainerReference container,
    required _MemberReferenceKind kind,
    required String? name,
  }) {
    return (_keyAllocatorByReference[container] ??= _KeyAllocator(
      kindCount: _MemberReferenceKind.values.length,
    )).allocate(kindIndex: kind.index, name: name);
  }

  String _allocateTopLevelKey({
    required _TopLevelReferenceKind kind,
    required String? name,
  }) {
    return (_keyAllocatorByReference[reference] ??= _KeyAllocator(
      kindCount: _TopLevelReferenceKind.values.length,
    )).allocate(kindIndex: kind.index, name: name);
  }
}

final class MemberContainerReference extends TopLevelReference {
  final List<Map<String, MemberReference>?> _membersByKind = List.filled(
    _MemberReferenceKind.values.length,
    null,
  );

  MemberContainerReference._({
    required super.library,
    required super.key,
    required super.kind,
  }) : super._();

  @override
  List<Reference> get children => [
    for (var byKey in _membersByKind) ...?byKey?.values,
  ];

  MemberReference declareConstructor(String key) {
    return _declareMember(kind: _MemberReferenceKind.constructor, key: key);
  }

  MemberReference declareField(String key) {
    return _declareMember(kind: _MemberReferenceKind.field, key: key);
  }

  MemberReference declareGetter(String key) {
    return _declareMember(kind: _MemberReferenceKind.getter, key: key);
  }

  MemberReference declareMethod(String key) {
    return _declareMember(kind: _MemberReferenceKind.method, key: key);
  }

  MemberReference declareSetter(String key) {
    return _declareMember(kind: _MemberReferenceKind.setter, key: key);
  }

  MemberReference getOrCreateConstructor(String key) {
    return _getOrCreateMember(kind: _MemberReferenceKind.constructor, key: key);
  }

  MemberReference getOrCreateField(String key) {
    return _getOrCreateMember(kind: _MemberReferenceKind.field, key: key);
  }

  MemberReference getOrCreateGetter(String key) {
    return _getOrCreateMember(kind: _MemberReferenceKind.getter, key: key);
  }

  MemberReference getOrCreateMethod(String key) {
    return _getOrCreateMember(kind: _MemberReferenceKind.method, key: key);
  }

  MemberReference getOrCreateSetter(String key) {
    return _getOrCreateMember(kind: _MemberReferenceKind.setter, key: key);
  }

  MemberReference _declareMember({
    required _MemberReferenceKind kind,
    required String key,
  }) {
    return Reference._declare(
      byKey: _memberByKey(kind),
      key: key,
      create: (key) => MemberReference._(container: this, key: key, kind: kind),
    );
  }

  MemberReference _getOrCreateMember({
    required _MemberReferenceKind kind,
    required String key,
  }) {
    return _memberByKey(kind)[key] ??= MemberReference._(
      container: this,
      key: key,
      kind: kind,
    );
  }

  Map<String, MemberReference> _memberByKey(_MemberReferenceKind kind) {
    return _membersByKind[kind.index] ??= {};
  }
}

final class MemberReference extends DeclarationReference {
  final MemberContainerReference container;
  final _MemberReferenceKind _kind;

  MemberReference._({
    required this.container,
    required super.key,
    required _MemberReferenceKind kind,
  }) : _kind = kind,
       super._();
}

/// A canonical identity node for an analyzer element.
///
/// References are the lightweight tree that summary reading and writing use to
/// name elements without requiring the corresponding [ElementImpl] to be built
/// yet. When an element is materialized, [element] is filled in with that
/// implementation object.
///
/// The tree shape is intentionally small:
///
/// - [RootReference] owns libraries.
/// - [LibraryReference] owns top-level declarations and `dart:core` built-ins.
/// - [MemberContainerReference] owns members of classes, enums, mixins,
///   extensions, and extension types.
/// - [LeafTopLevelReference], [MemberReference], and [BuiltInReference] have no
///   children.
///
/// Declaration references are identified under their enclosing reference by
/// kind and by an internal key. The key is not always the source name;
/// generated keys are used for unnamed declarations and duplicate source names.
sealed class Reference {
  /// The corresponding [ElementImpl], or `null` if not created yet.
  ElementImpl? element;

  Reference._();

  List<Reference> get children => const [];

  /// The reference that must be materialized before this reference, or `null`
  /// if this reference can be materialized directly.
  Reference? get enclosingReference {
    return switch (this) {
      TopLevelReference(:var library) => library,
      MemberReference(:var container) => container,
      BuiltInReference(:var library) => library,
      _ => null,
    };
  }

  String debugString({String Function(String uriString)? formatLibraryUri}) {
    String recurse(Reference reference) {
      return reference.debugString(formatLibraryUri: formatLibraryUri);
    }

    switch (this) {
      case RootReference():
        return 'root';
      case LibraryReference ref:
        return formatLibraryUri?.call(ref.uriString) ?? ref.uriString;
      case TopLevelReference ref:
        var libraryStr = recurse(ref.library);
        var kindStr = ref._kind.debugName;
        return '$libraryStr::$kindStr::${ref._key}';
      case MemberReference ref:
        var containerStr = recurse(ref.container);
        var kindStr = ref._kind.debugName;
        return '$containerStr::$kindStr::${ref._key}';
      case BuiltInReference ref:
        var libraryStr = recurse(ref.library);
        return '$libraryStr::${ref._kind.identifier}';
    }
  }

  @override
  String toString() => debugString();

  static T _declare<T extends Reference>({
    required Map<String, T> byKey,
    required String key,
    required T Function(String key) create,
  }) {
    if (byKey[key] != null) {
      throw StateError('Duplicate reference key: $key');
    }
    return byKey[key] = create(key);
  }
}

final class ReferenceTableReader {
  final String Function(int index) _stringOfIndex;
  final RootReference _rootReference;
  late final Uint8List _tagIndexes;
  late final Uint32List _parentIndexes;
  late final Uint8List _kindIndexes;
  late final Uint32List _keyStringIndexes;
  late final Uint32List _uriStringIndexes;
  late final List<Reference?> _referenceByIndex;

  ReferenceTableReader({
    required BinaryReader reader,
    required RootReference rootReference,
  }) : _stringOfIndex = reader.stringOfIndex,
       _rootReference = rootReference {
    _tagIndexes = reader.readUint8List();
    _parentIndexes = reader.readUint30List();
    _kindIndexes = reader.readUint8List();
    _keyStringIndexes = reader.readUint30List();
    _uriStringIndexes = reader.readUint30List();
    assert(_tagIndexes.length == _parentIndexes.length);
    assert(_tagIndexes.length == _kindIndexes.length);
    assert(_tagIndexes.length == _keyStringIndexes.length);
    assert(_tagIndexes.length == _uriStringIndexes.length);

    _referenceByIndex = List.filled(_tagIndexes.length, null);
    _referenceByIndex[0] = _rootReference;
  }

  DeclarationReference readDeclarationReference(BinaryReader reader) {
    var index = reader.readUint30();
    return _referenceOfIndex(index) as DeclarationReference;
  }

  ExportableReference readExportableReference(BinaryReader reader) {
    var index = reader.readUint30();
    return _referenceOfIndex(index) as ExportableReference;
  }

  LibraryReference readLibraryReference(BinaryReader reader) {
    var index = reader.readUint30();
    return _referenceOfIndex(index) as LibraryReference;
  }

  MemberContainerReference readMemberContainerReference(BinaryReader reader) {
    var index = reader.readUint30();
    return _referenceOfIndex(index) as MemberContainerReference;
  }

  MemberReference readMemberReference(BinaryReader reader) {
    var index = reader.readUint30();
    return _referenceOfIndex(index) as MemberReference;
  }

  Reference readReference(BinaryReader reader) {
    var index = reader.readUint30();
    return _referenceOfIndex(index);
  }

  TopLevelReference readTopLevelReference(BinaryReader reader) {
    var index = reader.readUint30();
    return _referenceOfIndex(index) as TopLevelReference;
  }

  LibraryReference _libraryReferenceOfIndex(int index) {
    return _referenceOfIndex(index) as LibraryReference;
  }

  MemberContainerReference _memberContainerReferenceOfIndex(int index) {
    return _referenceOfIndex(index) as MemberContainerReference;
  }

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

    var tag = _SerializedReferenceTag.values[_tagIndexes[index]];
    switch (tag) {
      case _SerializedReferenceTag.root:
        reference = _rootReference;
      case _SerializedReferenceTag.library:
        var uriString = _stringOfIndex(_uriStringIndexes[index]);
        reference = _rootReference.getOrCreateLibrary(
          uriCache.parse(uriString),
        );
      case _SerializedReferenceTag.topLevel:
        var library = _libraryReferenceOfIndex(_parentIndexes[index]);
        var kind = _TopLevelReferenceKind.values[_kindIndexes[index]];
        var key = _stringOfIndex(_keyStringIndexes[index]);
        reference = library._getOrCreateTopLevel(kind: kind, key: key);
      case _SerializedReferenceTag.member:
        var container = _memberContainerReferenceOfIndex(_parentIndexes[index]);
        reference = container._getOrCreateMember(
          kind: _MemberReferenceKind.values[_kindIndexes[index]],
          key: _stringOfIndex(_keyStringIndexes[index]),
        );
      case _SerializedReferenceTag.builtIn:
        var library = _libraryReferenceOfIndex(_parentIndexes[index]);
        var kind = _BuiltInReferenceKind.values[_kindIndexes[index]];
        reference = library._builtIn(kind);
    }
    _referenceByIndex[index] = reference;

    return reference;
  }
}

final class ReferenceTableWriter {
  static const int _rootIndex = 0;

  final Map<Reference, int> _indexByReference = Map.identity();

  final GrowableUint8List _tagIndexes = GrowableUint8List();
  final List<int> _parentIndexes = [];
  final GrowableUint8List _kindIndexes = GrowableUint8List();
  final List<String> _keyStrings = [];
  final List<String> _uriStrings = [];

  ReferenceTableWriter() {
    _appendRow(
      reference: null,
      tag: _SerializedReferenceTag.root,
      parentIndex: _rootIndex,
      kindIndex: 0,
      key: '',
      uriString: '',
    );
  }

  void write(BinaryWriter sink) {
    sink.writeUint8List(_tagIndexes.takeAndReset());
    sink.writeUint30List(_parentIndexes);
    sink.writeUint8List(_kindIndexes.takeAndReset());
    sink.writeStringList(_keyStrings);
    sink.writeStringList(_uriStrings);
  }

  void writeReference(BinaryWriter sink, Reference reference) {
    var index = _indexOfReference(reference);
    sink.writeUint30(index);
  }

  int _appendRow({
    required Reference? reference,
    required _SerializedReferenceTag tag,
    required int parentIndex,
    required int kindIndex,
    required String key,
    required String uriString,
  }) {
    assert(tag.index <= 0xFF);
    assert(kindIndex <= 0xFF);
    var index = _tagIndexes.length;
    _tagIndexes.add(tag.index);
    _parentIndexes.add(parentIndex);
    _kindIndexes.add(kindIndex);
    _keyStrings.add(key);
    _uriStrings.add(uriString);
    if (reference != null) {
      _indexByReference[reference] = index;
    }
    return index;
  }

  int _indexOfReference(Reference reference) {
    var index = _indexByReference[reference];
    if (index != null) return index;

    switch (reference) {
      case RootReference():
        return _rootIndex;
      case LibraryReference():
        return _appendRow(
          reference: reference,
          tag: _SerializedReferenceTag.library,
          parentIndex: _rootIndex,
          kindIndex: 0,
          key: '',
          uriString: reference.uriString,
        );
      case TopLevelReference():
        return _appendRow(
          reference: reference,
          tag: _SerializedReferenceTag.topLevel,
          parentIndex: _indexOfReference(reference.library),
          kindIndex: reference._kind.index,
          key: reference._key,
          uriString: '',
        );
      case MemberReference():
        return _appendRow(
          reference: reference,
          tag: _SerializedReferenceTag.member,
          parentIndex: _indexOfReference(reference.container),
          kindIndex: reference._kind.index,
          key: reference._key,
          uriString: '',
        );
      case BuiltInReference():
        return _appendRow(
          reference: reference,
          tag: _SerializedReferenceTag.builtIn,
          parentIndex: _indexOfReference(reference.library),
          kindIndex: reference._kind.index,
          key: '',
          uriString: '',
        );
    }
  }
}

final class RootReference extends Reference {
  final Map<String, LibraryReference> _libraries = {};

  RootReference() : super._();

  @override
  List<LibraryReference> get children => [..._libraries.values];

  LibraryReference getOrCreateLibrary(Uri uri) {
    var uriString = '$uri';
    return _libraries[uriString] ??= LibraryReference._(uriString: uriString);
  }

  LibraryReference? libraryIfExists(Uri uri) {
    var uriString = '$uri';
    return _libraries[uriString];
  }

  LibraryReference? removeLibrary(Uri uri) {
    var uriString = '$uri';
    return _libraries.remove(uriString);
  }
}

sealed class TopLevelReference extends DeclarationReference
    implements ExportableReference {
  final LibraryReference library;
  final _TopLevelReferenceKind _kind;

  TopLevelReference._({
    required this.library,
    required super.key,
    required _TopLevelReferenceKind kind,
  }) : _kind = kind,
       super._();
}

enum _BuiltInReferenceKind {
  dynamic_('dynamic'),
  never_('Never');

  final String identifier;

  const _BuiltInReferenceKind(this.identifier);
}

final class _KeyAllocator {
  final List<Map<String, int>?> _nextDuplicateIndexByKind;
  int _nextUnnamedIndex = 0;

  _KeyAllocator({required int kindCount})
    : _nextDuplicateIndexByKind = List.filled(kindCount, null);

  String allocate({required int kindIndex, required String? name}) {
    var baseName = name ?? _unnamedName(_nextUnnamedIndex++);
    var byBaseName = _nextDuplicateIndexByKind[kindIndex] ??= {};
    var duplicateIndex = byBaseName[baseName] ?? 0;
    byBaseName[baseName] = duplicateIndex + 1;

    if (duplicateIndex == 0) {
      return baseName;
    }
    return _duplicateName(baseName, duplicateIndex);
  }

  String _duplicateName(String baseName, int index) => '$baseName#$index';

  String _unnamedName(int index) => '#$index';
}

enum _MemberReferenceKind {
  constructor('@constructor'),
  field('@field'),
  getter('@getter'),
  setter('@setter'),
  method('@method');

  final String debugName;

  const _MemberReferenceKind(this.debugName);
}

enum _SerializedReferenceTag { root, library, topLevel, member, builtIn }

enum _TopLevelReferenceKind {
  class_('@class', hasMembers: true),
  enum_('@enum', hasMembers: true),
  extension_('@extension', hasMembers: true),
  extensionType('@extensionType', hasMembers: true),
  mixin_('@mixin', hasMembers: true),
  typeAlias('@typeAlias'),
  function('@function'),
  getter('@getter'),
  setter('@setter'),
  topLevelVariable('@topLevelVariable');

  final String debugName;
  final bool hasMembers;

  const _TopLevelReferenceKind(this.debugName, {this.hasMembers = false});
}
