// Copyright (c) 2024, 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' show Uint8List;

import 'package:kernel/ast.dart' show TreeNode, listHashCode, listEquals;
import 'package:kernel/core_types.dart' show CoreTypes;
import 'bytecode_serialization.dart'
    show
        BufferedWriter,
        BufferedReader,
        BytecodeDeclaration,
        BytecodeSizeStatistics,
        StringTable;
import 'constant_pool.dart' show ConstantPool;
import 'dbc.dart' show bytecodeFormatVersion;
import 'disassembler.dart' show BytecodeDisassembler;
import 'exceptions.dart' show ExceptionsTable;
import 'local_variable_table.dart' show LocalVariableTable;
import 'local_vars.dart' show AwaiterLink;
import 'object_table.dart'
    show
        ObjectTable,
        ObjectHandle,
        NameAndType,
        ParameterFlags,
        TypeParameterDeclaration;
import 'source_positions.dart'
    show LineStarts, RecordedCoverageArray, SourcePositions;

class LibraryDeclaration extends BytecodeDeclaration {
  static const usesDartMirrorsFlag = 1 << 0;
  static const usesDartFfiFlag = 1 << 1;

  ObjectHandle? importUri;
  final int flags;
  final ObjectHandle name;
  final ObjectHandle script;
  final List<ClassDeclaration> classes;

  LibraryDeclaration(
    this.importUri,
    this.flags,
    this.name,
    this.script,
    this.classes,
  );

  void write(BufferedWriter writer) {
    final start = writer.offset;
    writer.writePackedUInt30(flags);
    writer.writePackedObject(name);
    writer.writePackedObject(script);
    writer.writePackedUInt30(classes.length);
    for (var cls in classes) {
      writer.writePackedObject(cls.name!);
      writer.writeLinkOffset(cls);
    }
    BytecodeSizeStatistics.librariesSize += (writer.offset - start);
  }

  factory LibraryDeclaration.read(BufferedReader reader) {
    final flags = reader.readPackedUInt30();
    final ObjectHandle name = reader.readPackedObject();
    final ObjectHandle script = reader.readPackedObject();
    final classes = List<ClassDeclaration>.generate(reader.readPackedUInt30(), (
      _,
    ) {
      final ObjectHandle className = reader.readPackedObject();
      return reader.readLinkOffset<ClassDeclaration>()..name = className;
    });
    return new LibraryDeclaration(null, flags, name, script, classes);
  }

  @override
  String toString() {
    final StringBuffer sb = new StringBuffer();
    sb.writeln('Library $importUri');
    sb.writeln('    name $name');
    sb.writeln('    script $script');
    if ((flags & usesDartMirrorsFlag) != 0) {
      sb.writeln('    uses dart:mirrors');
    }
    if ((flags & usesDartFfiFlag) != 0) {
      sb.writeln('    uses dart:ffi');
    }
    sb.writeln();
    for (var cls in classes) {
      sb.write(cls);
    }
    return sb.toString();
  }
}

class ClassDeclaration extends BytecodeDeclaration {
  static const isAbstractFlag = 1 << 0;
  static const isEnumFlag = 1 << 1;
  static const hasTypeParamsFlag = 1 << 2;
  static const hasTypeArgumentsFlag = 1 << 3;
  static const isTransformedMixinApplicationFlag = 1 << 4;
  static const hasSourcePositionsFlag = 1 << 5;
  static const hasAnnotationsFlag = 1 << 6;
  static const hasPragmaFlag = 1 << 7;
  static const hasConstConstructorFlag = 1 << 8;
  static const isSealedFlag = 1 << 9;
  static const isMixinClassFlag = 1 << 10;
  static const isBaseClassFlag = 1 << 11;
  static const isInterfaceFlag = 1 << 12;
  static const isFinalFlag = 1 << 13;
  static const isDeeplyImmutableFlag = 1 << 14;

  ObjectHandle? name;
  final int flags;
  final ObjectHandle script;
  final int position;
  final int endPosition;
  final TypeParametersDeclaration? typeParameters;
  final int numTypeArguments;
  final ObjectHandle? superType;
  final List<ObjectHandle> interfaces;
  final Members members;
  final AnnotationsDeclaration? annotations;

  ClassDeclaration(
    this.name,
    this.flags,
    this.script,
    this.position,
    this.endPosition,
    this.typeParameters,
    this.numTypeArguments,
    this.superType,
    this.interfaces,
    this.members,
    this.annotations,
  );

  void write(BufferedWriter writer) {
    final start = writer.offset;
    writer.writePackedUInt30(flags);
    writer.writePackedObject(script);

    if ((flags & hasSourcePositionsFlag) != 0) {
      writer.writePackedUInt30(position + 1);
      writer.writePackedUInt30(endPosition + 1);
    }
    if ((flags & hasTypeArgumentsFlag) != 0) {
      writer.writePackedUInt30(numTypeArguments);
    }
    if ((flags & hasTypeParamsFlag) != 0) {
      typeParameters!.write(writer);
    }
    writer.writePackedObject(superType);
    writer.writePackedList(interfaces);
    if ((flags & hasAnnotationsFlag) != 0) {
      writer.writeLinkOffset(annotations!);
    }
    writer.writeLinkOffset(members);
    BytecodeSizeStatistics.classesSize += (writer.offset - start);
  }

  factory ClassDeclaration.read(BufferedReader reader) {
    final flags = reader.readPackedUInt30();
    final ObjectHandle script = reader.readPackedObject();
    final position = ((flags & hasSourcePositionsFlag) != 0)
        ? reader.readPackedUInt30() - 1
        : TreeNode.noOffset;
    final endPosition = ((flags & hasSourcePositionsFlag) != 0)
        ? reader.readPackedUInt30() - 1
        : TreeNode.noOffset;
    final numTypeArguments = ((flags & hasTypeArgumentsFlag) != 0)
        ? reader.readPackedUInt30()
        : 0;
    final typeParameters = ((flags & hasTypeParamsFlag) != 0)
        ? new TypeParametersDeclaration.read(reader)
        : null;
    final ObjectHandle? superType = reader.readPackedObject();
    final interfaces = reader.readPackedList<ObjectHandle>();
    final annotations = ((flags & hasAnnotationsFlag) != 0)
        ? reader.readLinkOffset<AnnotationsDeclaration>()
        : null;
    final members = reader.readLinkOffset<Members>();
    return new ClassDeclaration(
      null,
      flags,
      script,
      position,
      endPosition,
      typeParameters,
      numTypeArguments,
      superType,
      interfaces,
      members,
      annotations,
    );
  }

  @override
  String toString() {
    final StringBuffer sb = new StringBuffer();
    sb.write('Class $name, script = $script');
    if ((flags & isAbstractFlag) != 0) {
      sb.write(', abstract');
    }
    if ((flags & isEnumFlag) != 0) {
      sb.write(', enum');
    }
    if ((flags & isTransformedMixinApplicationFlag) != 0) {
      sb.write(', mixin-application');
    }
    if ((flags & hasPragmaFlag) != 0) {
      sb.write(', has-pragma');
    }
    if ((flags & isDeeplyImmutableFlag) != 0) {
      sb.write(', deeply-immutable');
    }
    if ((flags & hasSourcePositionsFlag) != 0) {
      sb.write(', pos = $position, end-pos = $endPosition');
    }
    sb.writeln();
    if ((flags & hasTypeParamsFlag) != 0) {
      sb.write('    type-params $typeParameters (args: $numTypeArguments)\n');
    }
    if (superType != null) {
      sb.write('    extends $superType\n');
    }
    if (interfaces.isNotEmpty) {
      sb.write('    implements $interfaces\n');
    }
    if ((flags & hasAnnotationsFlag) != 0) {
      sb.write('    annotations $annotations\n');
    }
    sb.writeln();
    sb.write(members.toString());
    return sb.toString();
  }
}

class SourceFile extends BytecodeDeclaration {
  static const hasLineStartsFlag = 1 << 0;
  static const hasSourceFlag = 1 << 1;
  static const hasConstConstructorCoverageFlag = 1 << 2;

  final ObjectHandle importUri;
  LineStarts? lineStarts;
  String? source;
  List<ObjectHandle>? coveredConstConstructors;

  SourceFile(
    this.importUri, [
    this.coveredConstConstructors,
    this.lineStarts,
    this.source,
  ]);

  void write(BufferedWriter writer) {
    int flags = 0;
    if (lineStarts != null) {
      flags |= hasLineStartsFlag;
    }
    if (coveredConstConstructors?.isNotEmpty ?? false) {
      flags |= hasConstConstructorCoverageFlag;
    }
    if (source != null && source != '') {
      flags |= hasSourceFlag;
    }
    writer.writePackedUInt30(flags);
    writer.writePackedObject(importUri);
    if ((flags & hasLineStartsFlag) != 0) {
      writer.writeLinkOffset(lineStarts!);
    }
    if ((flags & hasSourceFlag) != 0) {
      writer.writePackedStringReference(source!);
    }
    if ((flags & hasConstConstructorCoverageFlag) != 0) {
      writer.writePackedList(coveredConstConstructors!);
    }
  }

  factory SourceFile.read(BufferedReader reader) {
    final flags = reader.readPackedUInt30();
    final ObjectHandle importUri = reader.readPackedObject();
    final lineStarts = ((flags & hasLineStartsFlag) != 0)
        ? reader.readLinkOffset<LineStarts>()
        : null;
    final source = ((flags & hasSourceFlag) != 0)
        ? reader.readPackedStringReference()
        : null;
    final coveredConstConstructors =
        ((flags & hasConstConstructorCoverageFlag) != 0)
        ? reader.readPackedList<ObjectHandle>()
        : null;
    return new SourceFile(
      importUri,
      coveredConstConstructors,
      lineStarts,
      source,
    );
  }

  @override
  String toString() {
    final StringBuffer sb = new StringBuffer();
    sb.write('source: import-uri $importUri');
    if (source != null && source != '') {
      sb.write(', ${source!.length} text chars');
    }
    if (lineStarts != null) {
      sb.write(', ${lineStarts!.lineStarts.length} line starts');
    }
    if (coveredConstConstructors?.isNotEmpty ?? false) {
      sb.write(', covered const constructors: [');
      sb.writeAll(coveredConstConstructors!, ', ');
      sb.write(']');
    }
    return sb.toString();
  }
}

class Members extends BytecodeDeclaration {
  final List<FieldDeclaration> fields;
  final List<FunctionDeclaration> functions;

  Members(this.fields, this.functions);

  int countFunctions() {
    int count = functions.length;
    for (var field in fields) {
      if ((field.flags & FieldDeclaration.hasGetterFlag) != 0) {
        ++count;
      }
      if ((field.flags & FieldDeclaration.hasSetterFlag) != 0) {
        ++count;
      }
    }
    return count;
  }

  void write(BufferedWriter writer) {
    final start = writer.offset;
    writer.writePackedUInt30(countFunctions());
    writer.writePackedUInt30(fields.length);
    for (var field in fields) {
      field.write(writer);
    }
    writer.writePackedUInt30(functions.length);
    for (var func in functions) {
      func.write(writer);
    }
    BytecodeSizeStatistics.membersSize += (writer.offset - start);
  }

  factory Members.read(BufferedReader reader) {
    reader.readPackedUInt30(); // numFunctions
    final fields = new List<FieldDeclaration>.generate(
      reader.readPackedUInt30(),
      (_) => new FieldDeclaration.read(reader),
    );
    final functions = new List<FunctionDeclaration>.generate(
      reader.readPackedUInt30(),
      (_) => new FunctionDeclaration.read(reader),
    );
    return new Members(fields, functions);
  }

  @override
  String toString() =>
      "${fields.join('\n')}\n"
      "${functions.join('\n')}";
}

class FieldDeclaration {
  static const isStaticFlag = 1 << 0;
  static const isConstFlag = 1 << 1;
  static const isFinalFlag = 1 << 2;
  static const isLateFlag = 1 << 3;
  static const isCovariantFlag = 1 << 4;
  static const isCovariantByClassFlag = 1 << 5;
  static const isExtensionMemberFlag = 1 << 6;
  static const isReflectableFlag = 1 << 7;
  static const hasGetterFlag = 1 << 8;
  static const hasSetterFlag = 1 << 9;
  static const hasInitializerFlag = 1 << 10;
  static const hasNontrivialInitializerFlag = 1 << 11;
  static const hasInitializerCodeFlag = 1 << 12;
  static const hasSourcePositionsFlag = 1 << 13;
  static const hasAnnotationsFlag = 1 << 14;
  static const hasPragmaFlag = 1 << 15;
  static const hasCustomScriptFlag = 1 << 16;
  static const isExtensionTypeMemberFlag = 1 << 17;
  static const isShared = 1 << 18;

  final int flags;
  final ObjectHandle name;
  final ObjectHandle type;
  final ObjectHandle? value;
  final ObjectHandle? script;
  final int position;
  final int endPosition;
  final ObjectHandle? getterName;
  final ObjectHandle? setterName;
  final Code? initializerCode;
  final AnnotationsDeclaration? annotations;

  FieldDeclaration(
    this.flags,
    this.name,
    this.type,
    this.value,
    this.script,
    this.position,
    this.endPosition,
    this.getterName,
    this.setterName,
    this.initializerCode,
    this.annotations,
  );

  void write(BufferedWriter writer) {
    writer.writePackedUInt30(flags);
    writer.writePackedObject(name);
    writer.writePackedObject(type);

    if ((flags & hasCustomScriptFlag) != 0) {
      writer.writePackedObject(script);
    }
    if ((flags & hasSourcePositionsFlag) != 0) {
      writer.writePackedUInt30(position + 1);
      writer.writePackedUInt30(endPosition + 1);
    }
    if ((flags & hasInitializerCodeFlag) != 0) {
      writer.writeLinkOffset(initializerCode!);
    }
    if ((flags & hasNontrivialInitializerFlag) == 0) {
      writer.writePackedObject(value);
    }
    if ((flags & hasGetterFlag) != 0) {
      writer.writePackedObject(getterName);
    }
    if ((flags & hasSetterFlag) != 0) {
      writer.writePackedObject(setterName);
    }
    if ((flags & hasAnnotationsFlag) != 0) {
      writer.writeLinkOffset(annotations!);
    }
  }

  factory FieldDeclaration.read(BufferedReader reader) {
    final flags = reader.readPackedUInt30();
    final ObjectHandle name = reader.readPackedObject();
    final ObjectHandle type = reader.readPackedObject();
    final script = ((flags & hasCustomScriptFlag) != 0)
        ? reader.readPackedObject<ObjectHandle>()
        : null;
    final position = ((flags & hasSourcePositionsFlag) != 0)
        ? reader.readPackedUInt30() - 1
        : TreeNode.noOffset;
    final endPosition = ((flags & hasSourcePositionsFlag) != 0)
        ? reader.readPackedUInt30() - 1
        : TreeNode.noOffset;
    final initializerCode = ((flags & hasInitializerCodeFlag) != 0)
        ? reader.readLinkOffset<Code>()
        : null;
    final value = ((flags & hasNontrivialInitializerFlag) == 0)
        ? reader.readPackedObject<ObjectHandle?>()
        : null;
    final getterName = ((flags & hasGetterFlag) != 0)
        ? reader.readPackedObject<ObjectHandle>()
        : null;
    final setterName = ((flags & hasSetterFlag) != 0)
        ? reader.readPackedObject<ObjectHandle>()
        : null;
    final annotations = ((flags & hasAnnotationsFlag) != 0)
        ? reader.readLinkOffset<AnnotationsDeclaration>()
        : null;
    return new FieldDeclaration(
      flags,
      name,
      type,
      value,
      script,
      position,
      endPosition,
      getterName,
      setterName,
      initializerCode,
      annotations,
    );
  }

  @override
  String toString() {
    final StringBuffer sb = new StringBuffer();
    sb.write('Field $name, type = $type');
    if ((flags & hasGetterFlag) != 0) {
      sb.write(', getter = $getterName');
    }
    if ((flags & hasSetterFlag) != 0) {
      sb.write(', setter = $setterName');
    }
    if ((flags & isReflectableFlag) != 0) {
      sb.write(', reflectable');
    }
    if ((flags & isStaticFlag) != 0) {
      sb.write(', static');
    }
    if ((flags & isConstFlag) != 0) {
      sb.write(', const');
    }
    if ((flags & isFinalFlag) != 0) {
      sb.write(', final');
    }
    if ((flags & isLateFlag) != 0) {
      sb.write(', is-late');
    }
    if ((flags & isExtensionMemberFlag) != 0) {
      sb.write(', extension-member');
    }
    if ((flags & isExtensionTypeMemberFlag) != 0) {
      sb.write(', extension-type-member');
    }
    if ((flags & hasPragmaFlag) != 0) {
      sb.write(', has-pragma');
    }
    if ((flags & hasCustomScriptFlag) != 0) {
      sb.write(', custom-script = $script');
    }
    if ((flags & hasSourcePositionsFlag) != 0) {
      sb.write(', pos = $position, end-pos = $endPosition');
    }
    if ((flags & hasInitializerFlag) != 0) {
      sb.write(', has-initializer');
    }
    if ((flags & isShared) != 0) {
      sb.write(', shared');
    }
    sb.writeln();
    if ((flags & hasInitializerCodeFlag) != 0) {
      sb.write('    initializer\n$initializerCode\n');
    }
    if ((flags & hasNontrivialInitializerFlag) == 0) {
      sb.write('    value = $value\n');
    }
    if ((flags & hasAnnotationsFlag) != 0) {
      sb.write('    annotations $annotations\n');
    }
    return sb.toString();
  }
}

class FunctionDeclaration {
  static const isStaticFlag = 1 << 0;
  static const isAbstractFlag = 1 << 1;
  static const isGetterFlag = 1 << 2;
  static const isSetterFlag = 1 << 3;
  static const isConstructorFlag = 1 << 4;
  static const isFactoryFlag = 1 << 5;
  static const isConstFlag = 1 << 6;
  static const hasOptionalPositionalParamsFlag = 1 << 7;
  static const hasOptionalNamedParamsFlag = 1 << 8;
  static const hasTypeParamsFlag = 1 << 9;
  static const hasParameterFlagsFlag = 1 << 10;
  static const isExtensionMemberFlag = 1 << 11;
  static const isReflectableFlag = 1 << 12;
  static const isDebuggableFlag = 1 << 13;
  static const isAsyncFlag = 1 << 14;
  static const isAsyncStarFlag = 1 << 15;
  static const isSyncStarFlag = 1 << 16;
  static const isNoSuchMethodForwarderFlag = 1 << 17;
  static const isExternalFlag = 1 << 18;
  static const isNativeFlag = 1 << 19;
  static const hasSourcePositionsFlag = 1 << 20;
  static const hasAnnotationsFlag = 1 << 21;
  static const hasPragmaFlag = 1 << 22;
  static const hasCustomScriptFlag = 1 << 23;
  static const isExtensionTypeMemberFlag = 1 << 24;
  static const isInvisibleFlag = 1 << 25;

  final int flags;
  final ObjectHandle name;
  final ObjectHandle? script;
  final int position;
  final int endPosition;
  final TypeParametersDeclaration? typeParameters;
  final int numRequiredParameters;
  final List<ParameterDeclaration> parameters;
  // Only contains the required flag for named parameters when present.
  final List<int>? parameterFlags;
  final ObjectHandle returnType;
  final ObjectHandle? nativeName;
  final Code? code;
  final AnnotationsDeclaration? annotations;

  FunctionDeclaration(
    this.flags,
    this.name,
    this.script,
    this.position,
    this.endPosition,
    this.typeParameters,
    this.numRequiredParameters,
    this.parameters,
    this.parameterFlags,
    this.returnType,
    this.nativeName,
    this.code,
    this.annotations,
  );

  void write(BufferedWriter writer) {
    writer.writePackedUInt30(flags);
    writer.writePackedObject(name);
    if ((flags & hasCustomScriptFlag) != 0) {
      writer.writePackedObject(script);
    }
    if ((flags & hasSourcePositionsFlag) != 0) {
      writer.writePackedUInt30(position + 1);
      writer.writePackedUInt30(endPosition + 1);
    }
    if ((flags & hasTypeParamsFlag) != 0) {
      typeParameters!.write(writer);
    }
    writer.writePackedUInt30(parameters.length);
    if ((flags & hasOptionalPositionalParamsFlag) != 0 ||
        (flags & hasOptionalNamedParamsFlag) != 0) {
      writer.writePackedUInt30(numRequiredParameters);
    }
    for (var param in parameters) {
      param.write(writer);
    }
    if ((flags & hasParameterFlagsFlag) != 0) {
      final parameterFlags = this.parameterFlags!;
      writer.writePackedUInt30(parameterFlags.length);
      parameterFlags.forEach((flags) => writer.writePackedUInt30(flags));
    }
    writer.writePackedObject(returnType);
    if ((flags & isNativeFlag) != 0) {
      writer.writePackedObject(nativeName);
    }
    if ((flags & isAbstractFlag) == 0) {
      writer.writeLinkOffset(code!);
    }
    if ((flags & hasAnnotationsFlag) != 0) {
      writer.writeLinkOffset(annotations!);
    }
  }

  factory FunctionDeclaration.read(BufferedReader reader) {
    final flags = reader.readPackedUInt30();
    final ObjectHandle name = reader.readPackedObject();

    final script = ((flags & hasCustomScriptFlag) != 0)
        ? reader.readPackedObject<ObjectHandle>()
        : null;
    final position = ((flags & hasSourcePositionsFlag) != 0)
        ? reader.readPackedUInt30() - 1
        : TreeNode.noOffset;
    final endPosition = ((flags & hasSourcePositionsFlag) != 0)
        ? reader.readPackedUInt30() - 1
        : TreeNode.noOffset;
    final typeParameters = ((flags & hasTypeParamsFlag) != 0)
        ? new TypeParametersDeclaration.read(reader)
        : null;

    final numParameters = reader.readPackedUInt30();
    final numRequiredParameters =
        ((flags & hasOptionalPositionalParamsFlag) != 0 ||
            (flags & hasOptionalNamedParamsFlag) != 0)
        ? reader.readPackedUInt30()
        : numParameters;

    final parameters = new List<ParameterDeclaration>.generate(
      numParameters,
      (_) => new ParameterDeclaration.read(reader),
    );
    final parameterFlags = ((flags & hasParameterFlagsFlag) != 0)
        ? List<int>.generate(
            reader.readPackedUInt30(),
            (_) => reader.readPackedUInt30(),
          )
        : null;
    final ObjectHandle returnType = reader.readPackedObject();
    final nativeName = ((flags & isNativeFlag) != 0)
        ? reader.readPackedObject<ObjectHandle>()
        : null;
    final code = ((flags & isAbstractFlag) == 0)
        ? reader.readLinkOffset<Code>()
        : null;
    final annotations = ((flags & hasAnnotationsFlag) != 0)
        ? reader.readLinkOffset<AnnotationsDeclaration>()
        : null;
    return new FunctionDeclaration(
      flags,
      name,
      script,
      position,
      endPosition,
      typeParameters,
      numRequiredParameters,
      parameters,
      parameterFlags,
      returnType,
      nativeName,
      code,
      annotations,
    );
  }

  @override
  String toString() {
    final StringBuffer sb = new StringBuffer();
    sb.write('Function $name');
    if ((flags & isConstructorFlag) != 0) {
      sb.write(', constructor');
    }
    if ((flags & isGetterFlag) != 0) {
      sb.write(', getter');
    }
    if ((flags & isSetterFlag) != 0) {
      sb.write(', setter');
    }
    if ((flags & isFactoryFlag) != 0) {
      sb.write(', factory');
    }
    if ((flags & isStaticFlag) != 0) {
      sb.write(', static');
    }
    if ((flags & isAbstractFlag) != 0) {
      sb.write(', abstract');
    }
    if ((flags & isConstFlag) != 0) {
      sb.write(', const');
    }
    if ((flags & isExtensionMemberFlag) != 0) {
      sb.write(', extension-member');
    }
    if ((flags & isExtensionTypeMemberFlag) != 0) {
      sb.write(', extension-type-member');
    }
    if ((flags & hasOptionalPositionalParamsFlag) != 0) {
      sb.write(', has-optional-positional-params');
    }
    if ((flags & hasOptionalNamedParamsFlag) != 0) {
      sb.write(', has-optional-named-params');
    }
    if ((flags & isReflectableFlag) != 0) {
      sb.write(', reflectable');
    }
    if ((flags & isDebuggableFlag) != 0) {
      sb.write(', debuggable');
    }
    if ((flags & isAsyncFlag) != 0) {
      sb.write(', async');
    }
    if ((flags & isAsyncStarFlag) != 0) {
      sb.write(', async*');
    }
    if ((flags & isSyncStarFlag) != 0) {
      sb.write(', sync*');
    }
    if ((flags & isNoSuchMethodForwarderFlag) != 0) {
      sb.write(', no-such-method-forwarder');
    }
    if ((flags & isNativeFlag) != 0) {
      sb.write(', native $nativeName');
    }
    if ((flags & isExternalFlag) != 0) {
      sb.write(', external');
    }
    if ((flags & isInvisibleFlag) != 0) {
      sb.write(', invisible');
    }
    if ((flags & hasPragmaFlag) != 0) {
      sb.write(', has-pragma');
    }
    if ((flags & hasCustomScriptFlag) != 0) {
      sb.write(', custom-script = $script');
    }
    if ((flags & hasSourcePositionsFlag) != 0) {
      sb.write(', pos = $position, end-pos = $endPosition');
    }
    sb.writeln();
    if ((flags & hasTypeParamsFlag) != 0) {
      sb.write('    type-params $typeParameters\n');
    }
    sb.write('    parameters $parameters (required: $numRequiredParameters)\n');
    if ((flags & hasParameterFlagsFlag) != 0) {
      sb.write('    parameter-flags $parameterFlags\n');
    }
    sb.write('    return-type $returnType\n');
    if ((flags & hasAnnotationsFlag) != 0) {
      sb.write('    annotations $annotations\n');
    }
    if ((flags & isAbstractFlag) == 0 && (flags & isExternalFlag) == 0) {
      sb.write('\n$code\n');
    }
    return sb.toString();
  }
}

class TypeParametersDeclaration {
  final List<TypeParameterDeclaration> typeParams;

  TypeParametersDeclaration(this.typeParams);

  void write(BufferedWriter writer) {
    writer.writePackedUInt30(typeParams.length);
    for (var tp in typeParams) {
      writer.writePackedObject(tp.name);
    }
    for (var tp in typeParams) {
      writer.writePackedObject(tp.bound);
      writer.writePackedObject(tp.defaultType);
    }
  }

  factory TypeParametersDeclaration.read(BufferedReader reader) {
    final int numTypeParams = reader.readPackedUInt30();
    final names = List<ObjectHandle>.generate(
      numTypeParams,
      (_) => reader.readPackedObject(),
    );
    return TypeParametersDeclaration(
      List<TypeParameterDeclaration>.generate(
        numTypeParams,
        (int i) => TypeParameterDeclaration(
          names[i],
          reader.readPackedObject(),
          reader.readPackedObject(),
        ),
      ),
    );
  }

  @override
  int get hashCode => listHashCode(typeParams);

  @override
  bool operator ==(other) =>
      other is TypeParametersDeclaration &&
      listEquals(this.typeParams, other.typeParams);

  @override
  String toString() => '<${typeParams.join(', ')}>';
}

class ParameterDeclaration {
  final ObjectHandle name;
  final ObjectHandle type;

  ParameterDeclaration(this.name, this.type);

  void write(BufferedWriter writer) {
    writer.writePackedObject(name);
    writer.writePackedObject(type);
  }

  factory ParameterDeclaration.read(BufferedReader reader) {
    final ObjectHandle name = reader.readPackedObject();
    final ObjectHandle type = reader.readPackedObject();
    return new ParameterDeclaration(name, type);
  }

  @override
  String toString() => '$type $name';
}

class Code extends BytecodeDeclaration {
  static const hasExceptionsTableFlag = 1 << 0;
  static const hasSourcePositionsFlag = 1 << 1;
  static const hasNullableFieldsFlag = 1 << 2;
  static const hasClosuresFlag = 1 << 3;
  static const hasParameterFlagsFlag = 1 << 4;
  static const hasForwardingStubTargetFlag = 1 << 5;
  static const hasDefaultFunctionTypeArgsFlag = 1 << 6;
  static const hasLocalVariablesFlag = 1 << 7;
  static const hasRecordedCoverageFlag = 1 << 8;

  final ConstantPool constantPool;
  final Uint8List bytecodes;
  final ExceptionsTable exceptionsTable;
  final SourcePositions? sourcePositions;
  final LocalVariableTable? localVariables;
  final RecordedCoverageArray? recordedCoverage;
  final List<ObjectHandle> nullableFields;
  final List<ClosureDeclaration> closures;
  // Covariant and CovariantByClass flags for all parameters.
  final List<int>? parameterFlags;
  final int? forwardingStubTargetCpIndex;
  final int? defaultFunctionTypeArgsCpIndex;

  bool get hasExceptionsTable => exceptionsTable.blocks.isNotEmpty;
  bool get hasSourcePositions => sourcePositions?.isNotEmpty ?? false;
  bool get hasLocalVariables => localVariables?.isNotEmpty ?? false;
  bool get hasRecordedCoverage => recordedCoverage?.isNotEmpty ?? false;
  bool get hasNullableFields => nullableFields.isNotEmpty;
  bool get hasClosures => closures.isNotEmpty;

  int get flags =>
      (hasExceptionsTable ? hasExceptionsTableFlag : 0) |
      (hasSourcePositions ? hasSourcePositionsFlag : 0) |
      (hasNullableFields ? hasNullableFieldsFlag : 0) |
      (hasClosures ? hasClosuresFlag : 0) |
      (parameterFlags != null ? hasParameterFlagsFlag : 0) |
      (forwardingStubTargetCpIndex != null ? hasForwardingStubTargetFlag : 0) |
      (defaultFunctionTypeArgsCpIndex != null
          ? hasDefaultFunctionTypeArgsFlag
          : 0) |
      (hasLocalVariables ? hasLocalVariablesFlag : 0) |
      (hasRecordedCoverage ? hasRecordedCoverageFlag : 0);

  Code(
    this.constantPool,
    this.bytecodes,
    this.exceptionsTable,
    this.sourcePositions,
    this.localVariables,
    this.recordedCoverage,
    this.nullableFields,
    this.closures,
    this.parameterFlags,
    this.forwardingStubTargetCpIndex,
    this.defaultFunctionTypeArgsCpIndex,
  );

  void write(BufferedWriter writer) {
    final start = writer.offset;
    writer.writePackedUInt30(flags);
    final parameterFlags = this.parameterFlags;
    if (parameterFlags != null) {
      writer.writePackedUInt30(parameterFlags.length);
      parameterFlags.forEach((flags) => writer.writePackedUInt30(flags));
    }
    final forwardingStubTargetCpIndex = this.forwardingStubTargetCpIndex;
    if (forwardingStubTargetCpIndex != null) {
      writer.writePackedUInt30(forwardingStubTargetCpIndex);
    }
    final defaultFunctionTypeArgsCpIndex = this.defaultFunctionTypeArgsCpIndex;
    if (defaultFunctionTypeArgsCpIndex != null) {
      writer.writePackedUInt30(defaultFunctionTypeArgsCpIndex);
    }
    if (hasClosures) {
      writer.writePackedUInt30(closures.length);
      closures.forEach((c) => c.write(writer));
    }
    constantPool.write(writer);
    _writeBytecodeInstructions(writer, bytecodes);
    if (hasExceptionsTable) {
      exceptionsTable.write(writer);
    }
    if (hasSourcePositions) {
      writer.writeLinkOffset(sourcePositions!);
    }
    if (hasLocalVariables) {
      writer.writeLinkOffset(localVariables!);
    }
    if (hasRecordedCoverage) {
      writer.writeLinkOffset(recordedCoverage!);
    }
    if (hasNullableFields) {
      writer.writePackedList(nullableFields);
    }
    if (hasClosures) {
      closures.forEach((c) => c.code!.write(writer));
    }
    BytecodeSizeStatistics.codeSize += (writer.offset - start);
  }

  factory Code.read(BufferedReader reader) {
    int flags = reader.readPackedUInt30();
    final parameterFlags = ((flags & hasParameterFlagsFlag) != 0)
        ? new List<int>.generate(
            reader.readPackedUInt30(),
            (_) => reader.readPackedUInt30(),
          )
        : null;
    final forwardingStubTargetCpIndex =
        ((flags & hasForwardingStubTargetFlag) != 0)
        ? reader.readPackedUInt30()
        : null;
    final defaultFunctionTypeArgsCpIndex =
        ((flags & hasDefaultFunctionTypeArgsFlag) != 0)
        ? reader.readPackedUInt30()
        : null;
    final List<ClosureDeclaration> closures = ((flags & hasClosuresFlag) != 0)
        ? new List<ClosureDeclaration>.generate(
            reader.readPackedUInt30(),
            (_) => new ClosureDeclaration.read(reader),
          )
        : const <ClosureDeclaration>[];
    final ConstantPool constantPool = new ConstantPool.read(reader);
    final Uint8List bytecodes = _readBytecodeInstructions(reader);
    final exceptionsTable = ((flags & hasExceptionsTableFlag) != 0)
        ? new ExceptionsTable.read(reader)
        : new ExceptionsTable();
    final sourcePositions = ((flags & hasSourcePositionsFlag) != 0)
        ? reader.readLinkOffset<SourcePositions>()
        : null;
    final localVariables = ((flags & hasLocalVariablesFlag) != 0)
        ? reader.readLinkOffset<LocalVariableTable>()
        : null;
    final recordedCoverage = ((flags & hasRecordedCoverageFlag) != 0)
        ? reader.readLinkOffset<RecordedCoverageArray>()
        : null;
    final List<ObjectHandle> nullableFields =
        ((flags & hasNullableFieldsFlag) != 0)
        ? reader.readPackedList<ObjectHandle>()
        : const <ObjectHandle>[];
    for (var c in closures) {
      c.code = new ClosureCode.read(reader);
    }
    return new Code(
      constantPool,
      bytecodes,
      exceptionsTable,
      sourcePositions,
      localVariables,
      recordedCoverage,
      nullableFields,
      closures,
      parameterFlags,
      forwardingStubTargetCpIndex,
      defaultFunctionTypeArgsCpIndex,
    );
  }

  // TODO(alexmarkov): Consider printing constant pool before bytecode.
  @override
  String toString() =>
      "Bytecode {\n"
      "${new BytecodeDisassembler().disassemble(bytecodes, exceptionsTable, annotations: [hasSourcePositions ? sourcePositions!.getBytecodeAnnotations() : const <int, String>{}, hasLocalVariables ? localVariables!.getBytecodeAnnotations() : const <int, String>{}])}}\n"
      "$exceptionsTable"
      "${recordedCoverage == null ? '' : 'Coverage array: $recordedCoverage\n'}"
      "${nullableFields.isEmpty ? '' : 'Nullable fields: $nullableFields\n'}"
      "${parameterFlags == null ? '' : 'Parameter flags: $parameterFlags\n'}"
      "${forwardingStubTargetCpIndex == null ? '' : 'Forwarding stub target: CP#$forwardingStubTargetCpIndex\n'}"
      "${defaultFunctionTypeArgsCpIndex == null ? '' : 'Default function type arguments: CP#$defaultFunctionTypeArgsCpIndex\n'}"
      "$constantPool"
      "${closures.join('\n')}";
}

class ClosureDeclaration {
  static const hasOptionalPositionalParamsFlag = 1 << 0;
  static const hasOptionalNamedParamsFlag = 1 << 1;
  static const hasTypeParamsFlag = 1 << 2;
  static const hasSourcePositionsFlag = 1 << 3;
  static const isAsyncFlag = 1 << 4;
  static const isAsyncStarFlag = 1 << 5;
  static const isSyncStarFlag = 1 << 6;
  static const isDebuggableFlag = 1 << 7;
  static const hasParameterFlagsFlag = 1 << 8;
  static const hasAnnotationsFlag = 1 << 9;
  static const hasPragmaFlag = 1 << 10;
  static const isInvisibleFlag = 1 << 11;

  int flags;
  final ObjectHandle parent;
  final ObjectHandle name;
  final int position;
  final int endPosition;
  final TypeParametersDeclaration? typeParameters;
  final int numRequiredParams;
  final int numNamedParams;
  final List<NameAndType> parameters;
  // Only contains the required flag for named parameters when present.
  final List<int>? parameterFlags;
  final ObjectHandle returnType;
  final AnnotationsDeclaration? annotations;
  ClosureCode? code;

  ClosureDeclaration(
    this.flags,
    this.parent,
    this.name,
    this.position,
    this.endPosition,
    this.typeParameters,
    this.numRequiredParams,
    this.numNamedParams,
    this.parameters,
    this.parameterFlags,
    this.returnType,
    this.annotations,
  );

  void write(BufferedWriter writer) {
    writer.writePackedUInt30(flags);
    writer.writePackedObject(parent);
    writer.writePackedObject(name);

    if (flags & hasSourcePositionsFlag != 0) {
      writer.writePackedUInt30(position + 1);
      writer.writePackedUInt30(endPosition + 1);
    }

    if (flags & hasTypeParamsFlag != 0) {
      typeParameters!.write(writer);
    }
    writer.writePackedUInt30(parameters.length);
    if (flags &
            (hasOptionalPositionalParamsFlag | hasOptionalNamedParamsFlag) !=
        0) {
      writer.writePackedUInt30(numRequiredParams);
    }
    for (var param in parameters) {
      writer.writePackedObject(param.name);
      writer.writePackedObject(param.type);
    }
    if ((flags & hasParameterFlagsFlag) != 0) {
      final parameterFlags = this.parameterFlags!;
      writer.writePackedUInt30(parameterFlags.length);
      for (var pf in parameterFlags) {
        writer.writePackedUInt30(pf);
      }
    }
    writer.writePackedObject(returnType);
    if ((flags & hasAnnotationsFlag) != 0) {
      writer.writeLinkOffset(annotations!);
    }
  }

  factory ClosureDeclaration.read(BufferedReader reader) {
    final int flags = reader.readPackedUInt30();
    final ObjectHandle parent = reader.readPackedObject();
    final ObjectHandle name = reader.readPackedObject();
    final position = ((flags & hasSourcePositionsFlag) != 0)
        ? reader.readPackedUInt30() - 1
        : TreeNode.noOffset;
    final endPosition = ((flags & hasSourcePositionsFlag) != 0)
        ? reader.readPackedUInt30() - 1
        : TreeNode.noOffset;
    final TypeParametersDeclaration? typeParameters =
        ((flags & hasTypeParamsFlag) != 0)
        ? TypeParametersDeclaration.read(reader)
        : null;
    final numParams = reader.readPackedUInt30();
    final numRequiredParams =
        (flags &
                (hasOptionalPositionalParamsFlag |
                    hasOptionalNamedParamsFlag) !=
            0)
        ? reader.readPackedUInt30()
        : numParams;
    final numNamedParams = (flags & hasOptionalNamedParamsFlag != 0)
        ? (numParams - numRequiredParams)
        : 0;
    final List<NameAndType> parameters = new List<NameAndType>.generate(
      numParams,
      (_) =>
          new NameAndType(reader.readPackedObject(), reader.readPackedObject()),
    );
    List<int>? parameterFlags;
    if ((flags & hasParameterFlagsFlag) != 0) {
      final int numParameterFlags = reader.readPackedUInt30();
      parameterFlags = List<int>.generate(
        numParameterFlags,
        (_) => reader.readPackedUInt30(),
      );
    }
    final ObjectHandle returnType = reader.readPackedObject();
    final annotations = ((flags & hasAnnotationsFlag) != 0)
        ? reader.readLinkOffset<AnnotationsDeclaration>()
        : null;
    return new ClosureDeclaration(
      flags,
      parent,
      name,
      position,
      endPosition,
      typeParameters,
      numRequiredParams,
      numNamedParams,
      parameters,
      parameterFlags,
      returnType,
      annotations,
    );
  }

  void _writeParamsToBuffer(
    StringBuffer sb,
    List<NameAndType> params,
    List<int>? flags,
  ) {
    assert(flags == null || (params.length == flags.length));
    for (int i = 0; i < params.length; i++) {
      if (i != 0) {
        sb.write(', ');
      }
      // We only store the required flag for ClosureDeclarations.
      if (flags != null && (flags[i] & ParameterFlags.isRequiredFlag) != 0) {
        sb.write('required ');
      }
      sb.write(params[i]);
    }
  }

  @override
  String toString() {
    final StringBuffer sb = new StringBuffer();
    sb.write('Closure $parent::$name');
    if ((flags & isInvisibleFlag) != 0) {
      sb.write(' invisible');
    }
    if ((flags & isAsyncFlag) != 0) {
      sb.write(' async');
    }
    if ((flags & isAsyncStarFlag) != 0) {
      sb.write(' async*');
    }
    if ((flags & isSyncStarFlag) != 0) {
      sb.write(' sync*');
    }
    if (position != TreeNode.noOffset) {
      sb.write(' pos = $position, end-pos = $endPosition');
    }
    if ((flags & hasAnnotationsFlag) != 0) {
      sb.write(' annotations $annotations\n');
    }
    if ((flags & hasTypeParamsFlag) != 0) {
      sb.write(' type-params $typeParameters');
    }
    sb.write(' (');
    _writeParamsToBuffer(sb, parameters.sublist(0, numRequiredParams), null);
    if (numRequiredParams != parameters.length) {
      if (numRequiredParams > 0) {
        sb.write(', ');
      }
      sb.write(numNamedParams > 0 ? '{ ' : '[ ');
      _writeParamsToBuffer(
        sb,
        parameters.sublist(numRequiredParams),
        parameterFlags,
      );
      sb.write(numNamedParams > 0 ? ' }' : ' ]');
    }
    sb.write(') -> ');
    sb.writeln(returnType);
    if (code != null) {
      sb.write(code.toString());
    }
    return sb.toString();
  }
}

/// Bytecode of a nested function (closure).
/// Closures share the constant pool of a top-level member.
class ClosureCode {
  static const hasExceptionsTableFlag = 1 << 0;
  static const hasSourcePositionsFlag = 1 << 1;
  static const hasLocalVariablesFlag = 1 << 2;
  static const capturesOnlyFinalNotLateVarsFlag = 1 << 3;
  static const hasLocalFunctionIdFlag = 1 << 4;
  static const hasRecordedCoverageFlag = 1 << 5;
  static const hasAwaiterLinkFlag = 1 << 6;

  final Uint8List bytecodes;
  final ExceptionsTable exceptionsTable;
  final SourcePositions? sourcePositions;
  final LocalVariableTable? localVariables;
  final RecordedCoverageArray? recordedCoverage;
  final AwaiterLink? awaiterLink;
  final bool capturesOnlyFinalNotLateVars;
  final int localFunctionId;
  bool get hasExceptionsTable => exceptionsTable.blocks.isNotEmpty;
  bool get hasSourcePositions => sourcePositions?.isNotEmpty ?? false;
  bool get hasLocalVariables => localVariables?.isNotEmpty ?? false;
  bool get hasRecordedCoverage => recordedCoverage?.isNotEmpty ?? false;
  bool get hasLocalFunctionId => localFunctionId > 0;
  bool get hasAwaiterLink => awaiterLink != null;

  int get flags =>
      (hasExceptionsTable ? hasExceptionsTableFlag : 0) |
      (hasSourcePositions ? hasSourcePositionsFlag : 0) |
      (hasLocalVariables ? hasLocalVariablesFlag : 0) |
      (capturesOnlyFinalNotLateVars ? capturesOnlyFinalNotLateVarsFlag : 0) |
      (hasLocalFunctionId ? hasLocalFunctionIdFlag : 0) |
      (hasAwaiterLink ? hasAwaiterLinkFlag : 0) |
      (hasRecordedCoverage ? hasRecordedCoverageFlag : 0);

  ClosureCode(
    this.bytecodes,
    this.exceptionsTable,
    this.sourcePositions,
    this.localVariables,
    this.recordedCoverage,
    this.awaiterLink,
    this.capturesOnlyFinalNotLateVars,
    this.localFunctionId,
  );

  void write(BufferedWriter writer) {
    writer.writePackedUInt30(flags);
    if (hasLocalFunctionId) {
      writer.writePackedUInt30(localFunctionId);
    }
    if (hasAwaiterLink) {
      final (:depth, :index) = awaiterLink!;
      writer.writePackedUInt30(depth);
      writer.writePackedUInt30(index);
    }
    _writeBytecodeInstructions(writer, bytecodes);
    if (hasExceptionsTable) {
      exceptionsTable.write(writer);
    }
    if (hasSourcePositions) {
      writer.writeLinkOffset(sourcePositions!);
    }
    if (hasLocalVariables) {
      writer.writeLinkOffset(localVariables!);
    }
    if (hasRecordedCoverage) {
      writer.writeLinkOffset(recordedCoverage!);
    }
  }

  factory ClosureCode.read(BufferedReader reader) {
    final int flags = reader.readPackedUInt30();
    final localFunctionId = ((flags & hasLocalFunctionIdFlag) != 0)
        ? reader.readPackedUInt30()
        : -1;
    final awaiterLink = (flags & hasAwaiterLinkFlag != 0)
        ? (depth: reader.readPackedUInt30(), index: reader.readPackedUInt30())
        : null;
    final Uint8List bytecodes = _readBytecodeInstructions(reader);
    final exceptionsTable = ((flags & hasExceptionsTableFlag) != 0)
        ? new ExceptionsTable.read(reader)
        : new ExceptionsTable();
    final sourcePositions = ((flags & hasSourcePositionsFlag) != 0)
        ? reader.readLinkOffset<SourcePositions>()
        : null;
    final localVariables = ((flags & hasLocalVariablesFlag) != 0)
        ? reader.readLinkOffset<LocalVariableTable>()
        : null;
    final recordedCoverage = ((flags & hasRecordedCoverageFlag) != 0)
        ? reader.readLinkOffset<RecordedCoverageArray>()
        : null;
    final capturesOnlyFinalNotLateVars =
        (flags & capturesOnlyFinalNotLateVarsFlag) != 0;

    return new ClosureCode(
      bytecodes,
      exceptionsTable,
      sourcePositions,
      localVariables,
      recordedCoverage,
      awaiterLink,
      capturesOnlyFinalNotLateVars,
      localFunctionId,
    );
  }

  @override
  String toString() {
    StringBuffer sb = new StringBuffer();
    sb.writeln('ClosureCode {');
    sb.write(
      new BytecodeDisassembler().disassemble(
        bytecodes,
        exceptionsTable,
        annotations: [
          hasSourcePositions
              ? sourcePositions!.getBytecodeAnnotations()
              : const <int, String>{},
          hasLocalVariables
              ? localVariables!.getBytecodeAnnotations()
              : const <int, String>{},
        ],
      ),
    );
    if (hasRecordedCoverage) {
      sb.writeln('Coverage array: $recordedCoverage');
    }
    if (hasAwaiterLink) {
      sb.writeln('Awaiter link: $awaiterLink');
    }
    sb.writeln('}');
    return sb.toString();
  }
}

class AnnotationsDeclaration extends BytecodeDeclaration {
  final ObjectHandle? object;

  AnnotationsDeclaration(this.object);

  void write(BufferedWriter writer) {
    writer.writePackedObject(object);
  }

  factory AnnotationsDeclaration.read(BufferedReader reader) {
    return new AnnotationsDeclaration(reader.readPackedObject());
  }

  @override
  String toString() => object.toString();
}

class _Section {
  int numItems;
  int? offset;
  BufferedWriter? writer;

  _Section(this.numItems, this.writer);

  int get size => writer!.offset;
}

class Component {
  static const int magicValue = 0x44424333; // 'DBC3'
  static const int numSections = 14;
  static const int sectionAlignment = 4;

  //  UInt32 magic, version, numSections x (numItems, offset)
  static const int headerSize = (2 + numSections * 2) * 4;

  late StringTable stringTable;
  late ObjectTable objectTable;
  final List<LibraryDeclaration> libraries = <LibraryDeclaration>[];
  final List<ClassDeclaration> classes = <ClassDeclaration>[];
  final List<Members> members = <Members>[];
  final List<Code> codes = <Code>[];
  final List<SourcePositions> sourcePositions = <SourcePositions>[];
  final List<LineStarts> lineStarts = <LineStarts>[];
  final List<SourceFile> sourceFiles = <SourceFile>[];
  final Map<Uri, SourceFile> uriToSource = <Uri, SourceFile>{};
  final List<LocalVariableTable> localVariables = <LocalVariableTable>[];
  final List<RecordedCoverageArray> recordedCoverage =
      <RecordedCoverageArray>[];
  final List<AnnotationsDeclaration> annotations = <AnnotationsDeclaration>[];
  ObjectHandle? dynModuleEntryPoint;

  Component(CoreTypes coreTypes)
    : stringTable = new StringTable(),
      objectTable = new ObjectTable(coreTypes);

  void write(BufferedWriter writer) {
    objectTable.allocateIndexTable();

    // Write sections to their own buffers in reverse order as section may
    // reference data structures from successor sections by offsets.

    final annotationsWriter = new BufferedWriter.fromWriter(writer);
    for (var annot in annotations) {
      writer.linkWriter.put(annot, annotationsWriter.offset);
      annot.write(annotationsWriter);
    }
    BytecodeSizeStatistics.annotationsSize += annotationsWriter.offset;

    final recordedCoverageWriter = new BufferedWriter.fromWriter(writer);
    for (var rc in recordedCoverage) {
      writer.linkWriter.put(rc, recordedCoverageWriter.offset);
      rc.write(recordedCoverageWriter);
    }
    BytecodeSizeStatistics.recordedCoverageSize +=
        recordedCoverageWriter.offset;

    final localVariablesWriter = new BufferedWriter.fromWriter(writer);
    for (var lv in localVariables) {
      writer.linkWriter.put(lv, localVariablesWriter.offset);
      lv.write(localVariablesWriter);
    }
    BytecodeSizeStatistics.localVariablesSize += localVariablesWriter.offset;

    final lineStartsWriter = new BufferedWriter.fromWriter(writer);
    for (var ls in lineStarts) {
      writer.linkWriter.put(ls, lineStartsWriter.offset);
      ls.write(lineStartsWriter);
    }
    BytecodeSizeStatistics.lineStartsSize += lineStartsWriter.offset;

    final sourceFilesWriter = new BufferedWriter.fromWriter(writer);
    for (var sf in sourceFiles) {
      writer.linkWriter.put(sf, sourceFilesWriter.offset);
      sf.write(sourceFilesWriter);
    }
    BytecodeSizeStatistics.sourceFilesSize += sourceFilesWriter.offset;

    final sourcePositionsWriter = new BufferedWriter.fromWriter(writer);
    for (var sp in sourcePositions) {
      writer.linkWriter.put(sp, sourcePositionsWriter.offset);
      sp.write(sourcePositionsWriter);
    }
    BytecodeSizeStatistics.sourcePositionsSize += sourcePositionsWriter.offset;

    final codesWriter = new BufferedWriter.fromWriter(writer);
    for (var code in codes) {
      writer.linkWriter.put(code, codesWriter.offset);
      code.write(codesWriter);
    }

    final membersWriter = new BufferedWriter.fromWriter(writer);
    for (var m in members) {
      writer.linkWriter.put(m, membersWriter.offset);
      m.write(membersWriter);
    }

    final classesWriter = new BufferedWriter.fromWriter(writer);
    for (var cls in classes) {
      writer.linkWriter.put(cls, classesWriter.offset);
      cls.write(classesWriter);
    }

    final librariesWriter = new BufferedWriter.fromWriter(writer);
    for (var library in libraries) {
      writer.linkWriter.put(library, librariesWriter.offset);
      library.write(librariesWriter);
    }

    final libraryIndexWriter = new BufferedWriter.fromWriter(writer);
    for (var library in libraries) {
      libraryIndexWriter.writePackedObject(library.importUri);
      libraryIndexWriter.writeLinkOffset(library);
    }
    BytecodeSizeStatistics.librariesSize += libraryIndexWriter.offset;

    BufferedWriter? mainWriter;
    if (dynModuleEntryPoint != null) {
      mainWriter = new BufferedWriter.fromWriter(writer);
      mainWriter.writePackedObject(dynModuleEntryPoint);
    }

    final objectsWriter = new BufferedWriter.fromWriter(writer);
    objectTable.write(objectsWriter);

    final stringsWriter = new BufferedWriter.fromWriter(writer);
    stringTable.write(stringsWriter);

    List<_Section> sections = [
      new _Section(0, stringsWriter),
      new _Section(0, objectsWriter),
      new _Section(0, mainWriter),
      new _Section(libraries.length, libraryIndexWriter),
      new _Section(libraries.length, librariesWriter),
      new _Section(classes.length, classesWriter),
      new _Section(members.length, membersWriter),
      new _Section(codes.length, codesWriter),
      new _Section(sourcePositions.length, sourcePositionsWriter),
      new _Section(sourceFiles.length, sourceFilesWriter),
      new _Section(lineStarts.length, lineStartsWriter),
      new _Section(localVariables.length, localVariablesWriter),
      new _Section(recordedCoverage.length, recordedCoverageWriter),
      new _Section(annotations.length, annotationsWriter),
    ];
    if (sections.length != numSections) {
      throw StateError(
        'Expected $numSections sections, got ${sections.length}',
      );
    }

    int offset = headerSize;
    for (var section in sections) {
      if (section.writer != null) {
        section.offset = offset;
        offset += section.size;
      } else {
        section.offset = 0;
      }
    }

    final start = writer.offset;

    writer.writeUInt32(magicValue);
    writer.writeUInt32(bytecodeFormatVersion);
    for (var section in sections) {
      writer.writeUInt32(section.numItems);
      writer.writeUInt32(section.offset!);
    }
    assert(writer.offset - start == headerSize);
    for (var section in sections) {
      final sectionWriter = section.writer;
      if (sectionWriter != null) {
        assert(writer.offset - start == section.offset);
        writer.appendWriter(sectionWriter);
      }
    }

    BytecodeSizeStatistics.componentSize += (writer.offset - start);
  }

  Component.read(BufferedReader reader) {
    final int start = reader.offset;

    final int magic = reader.readUInt32();
    if (magic != magicValue) {
      throw 'Error: unexpected bytecode magic $magic';
    }

    final version = reader.readUInt32();
    if (version != bytecodeFormatVersion) {
      throw 'Error: unexpected bytecode format version $version (expected $bytecodeFormatVersion)';
    }

    reader.readUInt32();
    final stringTableOffset = reader.readUInt32();

    reader.readUInt32();
    final objectTableOffset = reader.readUInt32();

    reader.readUInt32();
    final mainOffset = reader.readUInt32();

    final librariesNum = reader.readUInt32();
    final libraryIndexOffset = reader.readUInt32();

    reader.readUInt32();
    final librariesOffset = reader.readUInt32();

    final classesNum = reader.readUInt32();
    final classesOffset = reader.readUInt32();

    final membersNum = reader.readUInt32();
    final membersOffset = reader.readUInt32();

    final codesNum = reader.readUInt32();
    final codesOffset = reader.readUInt32();

    final sourcePositionsNum = reader.readUInt32();
    final sourcePositionsOffset = reader.readUInt32();

    final sourceFilesNum = reader.readUInt32();
    final sourceFilesOffset = reader.readUInt32();

    final lineStartsNum = reader.readUInt32();
    final lineStartsOffset = reader.readUInt32();

    final localVariablesNum = reader.readUInt32();
    final localVariablesOffset = reader.readUInt32();

    final recordedCoverageNum = reader.readUInt32();
    final recordedCoverageOffset = reader.readUInt32();

    final annotationsNum = reader.readUInt32();
    final annotationsOffset = reader.readUInt32();

    reader.offset = start + stringTableOffset;
    stringTable = new StringTable.read(reader);
    reader.stringReader = stringTable;

    reader.offset = start + objectTableOffset;
    objectTable = new ObjectTable.read(reader);
    reader.objectReader = objectTable;

    // Read sections in the reverse order as section may reference
    // successor sections by offsets.

    final annotationsStart = start + annotationsOffset;
    reader.offset = annotationsStart;
    for (int i = 0; i < annotationsNum; ++i) {
      int offset = reader.offset - annotationsStart;
      AnnotationsDeclaration annot = new AnnotationsDeclaration.read(reader);
      reader.linkReader.setOffset(annot, offset);
      annotations.add(annot);
    }

    final recordedCoverageStart = start + recordedCoverageOffset;
    reader.offset = recordedCoverageStart;
    for (int i = 0; i < recordedCoverageNum; ++i) {
      int offset = reader.offset - recordedCoverageStart;
      RecordedCoverageArray rc = new RecordedCoverageArray.read(reader);
      reader.linkReader.setOffset(rc, offset);
      recordedCoverage.add(rc);
    }

    final localVariablesStart = start + localVariablesOffset;
    reader.offset = localVariablesStart;
    for (int i = 0; i < localVariablesNum; ++i) {
      int offset = reader.offset - localVariablesStart;
      LocalVariableTable lv = new LocalVariableTable.read(reader);
      reader.linkReader.setOffset(lv, offset);
      localVariables.add(lv);
    }

    final lineStartsStart = start + lineStartsOffset;
    reader.offset = lineStartsStart;
    for (int i = 0; i < lineStartsNum; ++i) {
      int offset = reader.offset - lineStartsStart;
      LineStarts ls = new LineStarts.read(reader);
      reader.linkReader.setOffset(ls, offset);
      lineStarts.add(ls);
    }

    final sourceFilesStart = start + sourceFilesOffset;
    reader.offset = sourceFilesStart;
    for (int i = 0; i < sourceFilesNum; ++i) {
      int offset = reader.offset - sourceFilesStart;
      SourceFile sf = new SourceFile.read(reader);
      reader.linkReader.setOffset(sf, offset);
      sourceFiles.add(sf);
    }

    final sourcePositionsStart = start + sourcePositionsOffset;
    reader.offset = sourcePositionsStart;
    for (int i = 0; i < sourcePositionsNum; ++i) {
      int offset = reader.offset - sourcePositionsStart;
      SourcePositions sp = new SourcePositions.read(reader);
      reader.linkReader.setOffset(sp, offset);
      sourcePositions.add(sp);
    }

    final codesStart = start + codesOffset;
    reader.offset = codesStart;
    for (int i = 0; i < codesNum; ++i) {
      int offset = reader.offset - codesStart;
      Code code = new Code.read(reader);
      reader.linkReader.setOffset(code, offset);
      codes.add(code);
    }

    final membersStart = start + membersOffset;
    reader.offset = membersStart;
    for (int i = 0; i < membersNum; ++i) {
      int offset = reader.offset - membersStart;
      Members m = new Members.read(reader);
      reader.linkReader.setOffset(m, offset);
      members.add(m);
    }

    final classesStart = start + classesOffset;
    reader.offset = classesStart;
    for (int i = 0; i < classesNum; ++i) {
      int offset = reader.offset - classesStart;
      ClassDeclaration cls = new ClassDeclaration.read(reader);
      reader.linkReader.setOffset(cls, offset);
      classes.add(cls);
    }

    final librariesStart = start + librariesOffset;
    reader.offset = librariesStart;
    for (int i = 0; i < librariesNum; ++i) {
      int offset = reader.offset - librariesStart;
      LibraryDeclaration library = new LibraryDeclaration.read(reader);
      reader.linkReader.setOffset(library, offset);
      libraries.add(library);
    }

    final libraryIndexStart = start + libraryIndexOffset;
    reader.offset = libraryIndexStart;
    for (int i = 0; i < librariesNum; ++i) {
      final ObjectHandle importUri = reader.readPackedObject();
      final library = reader.readLinkOffset<LibraryDeclaration>();
      library.importUri = importUri;
    }

    if (mainOffset != 0) {
      reader.offset = start + mainOffset;
      dynModuleEntryPoint = reader.readPackedObject();
    }
  }

  @override
  String toString() {
    final StringBuffer sb = new StringBuffer();
    sb.writeln("Bytecode");
    if (dynModuleEntryPoint != null) {
      sb.writeln("Dynamic Module Entry Point: $dynModuleEntryPoint");
    }
    for (var library in libraries) {
      sb.write(library);
    }
    return sb.toString();
  }
}

void _writeBytecodeInstructions(BufferedWriter writer, Uint8List bytecodes) {
  writer.writePackedUInt30(bytecodes.length);
  writer.appendUint8List(bytecodes);
  BytecodeSizeStatistics.instructionsSize += bytecodes.length;
}

Uint8List _readBytecodeInstructions(BufferedReader reader) {
  int len = reader.readPackedUInt30();
  return reader.readBytesAsUint8List(len);
}
