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

  final Uint8List bytecodes;
  final ExceptionsTable exceptionsTable;
  final SourcePositions? sourcePositions;
  final LocalVariableTable? localVariables;
  final RecordedCoverageArray? recordedCoverage;
  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;

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

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

  void write(BufferedWriter writer) {
    writer.writePackedUInt30(flags);
    if (hasLocalFunctionId) {
      writer.writePackedUInt30(localFunctionId);
    }
    _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 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,
      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');
    }
    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);
}
