///
//  Generated code. Do not modify.
//  source: info.proto
//
// @dart = 2.12
// ignore_for_file: annotate_overrides,camel_case_types,unnecessary_const,non_constant_identifier_names,library_prefixes,unused_import,unused_shown_name,return_of_invalid_type,unnecessary_this,prefer_final_fields

import 'dart:core' as $core;

import 'package:fixnum/fixnum.dart' as $fixnum;
import 'package:protobuf/protobuf.dart' as $pb;

class DependencyInfoPB extends $pb.GeneratedMessage {
  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
      const $core.bool.fromEnvironment('protobuf.omit_message_names')
          ? ''
          : 'DependencyInfoPB',
      package: const $pb.PackageName(
          const $core.bool.fromEnvironment('protobuf.omit_message_names')
              ? ''
              : 'dart2js_info.proto'),
      createEmptyInstance: create)
    ..aOS(
        1,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'targetId')
    ..aOS(
        2,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'mask')
    ..hasRequiredFields = false;

  DependencyInfoPB._() : super();
  factory DependencyInfoPB({
    $core.String? targetId,
    $core.String? mask,
  }) {
    final _result = create();
    if (targetId != null) {
      _result.targetId = targetId;
    }
    if (mask != null) {
      _result.mask = mask;
    }
    return _result;
  }
  factory DependencyInfoPB.fromBuffer($core.List<$core.int> i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromBuffer(i, r);
  factory DependencyInfoPB.fromJson($core.String i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromJson(i, r);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
      'Will be removed in next major version')
  DependencyInfoPB clone() => DependencyInfoPB()..mergeFromMessage(this);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
      'Will be removed in next major version')
  DependencyInfoPB copyWith(void Function(DependencyInfoPB) updates) =>
      super.copyWith((message) => updates(message as DependencyInfoPB))
          as DependencyInfoPB; // ignore: deprecated_member_use
  $pb.BuilderInfo get info_ => _i;
  @$core.pragma('dart2js:noInline')
  static DependencyInfoPB create() => DependencyInfoPB._();
  DependencyInfoPB createEmptyInstance() => create();
  static $pb.PbList<DependencyInfoPB> createRepeated() =>
      $pb.PbList<DependencyInfoPB>();
  @$core.pragma('dart2js:noInline')
  static DependencyInfoPB getDefault() => _defaultInstance ??=
      $pb.GeneratedMessage.$_defaultFor<DependencyInfoPB>(create);
  static DependencyInfoPB? _defaultInstance;

  @$pb.TagNumber(1)
  $core.String get targetId => $_getSZ(0);
  @$pb.TagNumber(1)
  set targetId($core.String v) {
    $_setString(0, v);
  }

  @$pb.TagNumber(1)
  $core.bool hasTargetId() => $_has(0);
  @$pb.TagNumber(1)
  void clearTargetId() => clearField(1);

  @$pb.TagNumber(2)
  $core.String get mask => $_getSZ(1);
  @$pb.TagNumber(2)
  set mask($core.String v) {
    $_setString(1, v);
  }

  @$pb.TagNumber(2)
  $core.bool hasMask() => $_has(1);
  @$pb.TagNumber(2)
  void clearMask() => clearField(2);
}

class AllInfoPB extends $pb.GeneratedMessage {
  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
      const $core.bool.fromEnvironment('protobuf.omit_message_names')
          ? ''
          : 'AllInfoPB',
      package: const $pb.PackageName(
          const $core.bool.fromEnvironment('protobuf.omit_message_names')
              ? ''
              : 'dart2js_info.proto'),
      createEmptyInstance: create)
    ..aOM<ProgramInfoPB>(
        1,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'program',
        subBuilder: ProgramInfoPB.create)
    ..m<$core.String, InfoPB>(
        2,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'allInfos',
        entryClassName: 'AllInfoPB.AllInfosEntry',
        keyFieldType: $pb.PbFieldType.OS,
        valueFieldType: $pb.PbFieldType.OM,
        valueCreator: InfoPB.create,
        packageName: const $pb.PackageName('dart2js_info.proto'))
    ..pc<LibraryDeferredImportsPB>(
        3,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'deferredImports',
        $pb.PbFieldType.PM,
        subBuilder: LibraryDeferredImportsPB.create)
    ..hasRequiredFields = false;

  AllInfoPB._() : super();
  factory AllInfoPB({
    ProgramInfoPB? program,
    $core.Map<$core.String, InfoPB>? allInfos,
    $core.Iterable<LibraryDeferredImportsPB>? deferredImports,
  }) {
    final _result = create();
    if (program != null) {
      _result.program = program;
    }
    if (allInfos != null) {
      _result.allInfos.addAll(allInfos);
    }
    if (deferredImports != null) {
      _result.deferredImports.addAll(deferredImports);
    }
    return _result;
  }
  factory AllInfoPB.fromBuffer($core.List<$core.int> i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromBuffer(i, r);
  factory AllInfoPB.fromJson($core.String i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromJson(i, r);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
      'Will be removed in next major version')
  AllInfoPB clone() => AllInfoPB()..mergeFromMessage(this);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
      'Will be removed in next major version')
  AllInfoPB copyWith(void Function(AllInfoPB) updates) =>
      super.copyWith((message) => updates(message as AllInfoPB))
          as AllInfoPB; // ignore: deprecated_member_use
  $pb.BuilderInfo get info_ => _i;
  @$core.pragma('dart2js:noInline')
  static AllInfoPB create() => AllInfoPB._();
  AllInfoPB createEmptyInstance() => create();
  static $pb.PbList<AllInfoPB> createRepeated() => $pb.PbList<AllInfoPB>();
  @$core.pragma('dart2js:noInline')
  static AllInfoPB getDefault() =>
      _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<AllInfoPB>(create);
  static AllInfoPB? _defaultInstance;

  @$pb.TagNumber(1)
  ProgramInfoPB get program => $_getN(0);
  @$pb.TagNumber(1)
  set program(ProgramInfoPB v) {
    setField(1, v);
  }

  @$pb.TagNumber(1)
  $core.bool hasProgram() => $_has(0);
  @$pb.TagNumber(1)
  void clearProgram() => clearField(1);
  @$pb.TagNumber(1)
  ProgramInfoPB ensureProgram() => $_ensure(0);

  @$pb.TagNumber(2)
  $core.Map<$core.String, InfoPB> get allInfos => $_getMap(1);

  @$pb.TagNumber(3)
  $core.List<LibraryDeferredImportsPB> get deferredImports => $_getList(2);
}

enum InfoPB_Concrete {
  libraryInfo,
  classInfo,
  functionInfo,
  fieldInfo,
  constantInfo,
  outputUnitInfo,
  typedefInfo,
  closureInfo,
  classTypeInfo,
  notSet
}

class InfoPB extends $pb.GeneratedMessage {
  static const $core.Map<$core.int, InfoPB_Concrete> _InfoPB_ConcreteByTag = {
    100: InfoPB_Concrete.libraryInfo,
    101: InfoPB_Concrete.classInfo,
    102: InfoPB_Concrete.functionInfo,
    103: InfoPB_Concrete.fieldInfo,
    104: InfoPB_Concrete.constantInfo,
    105: InfoPB_Concrete.outputUnitInfo,
    106: InfoPB_Concrete.typedefInfo,
    107: InfoPB_Concrete.closureInfo,
    108: InfoPB_Concrete.classTypeInfo,
    0: InfoPB_Concrete.notSet
  };
  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
      const $core.bool.fromEnvironment('protobuf.omit_message_names')
          ? ''
          : 'InfoPB',
      package: const $pb.PackageName(
          const $core.bool.fromEnvironment('protobuf.omit_message_names')
              ? ''
              : 'dart2js_info.proto'),
      createEmptyInstance: create)
    ..oo(0, [100, 101, 102, 103, 104, 105, 106, 107, 108])
    ..aOS(
        1,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'name')
    ..a<$core.int>(
        2,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'id',
        $pb.PbFieldType.O3)
    ..aOS(
        3,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'serializedId')
    ..aOS(
        4,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'coverageId')
    ..a<$core.int>(
        5,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'size',
        $pb.PbFieldType.O3)
    ..aOS(
        6,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'parentId')
    ..pc<DependencyInfoPB>(
        7,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'uses',
        $pb.PbFieldType.PM,
        subBuilder: DependencyInfoPB.create)
    ..aOS(
        8,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'outputUnitId')
    ..aOM<LibraryInfoPB>(
        100,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'libraryInfo',
        subBuilder: LibraryInfoPB.create)
    ..aOM<ClassInfoPB>(
        101,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'classInfo',
        subBuilder: ClassInfoPB.create)
    ..aOM<FunctionInfoPB>(
        102,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'functionInfo',
        subBuilder: FunctionInfoPB.create)
    ..aOM<FieldInfoPB>(
        103,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'fieldInfo',
        subBuilder: FieldInfoPB.create)
    ..aOM<ConstantInfoPB>(
        104,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'constantInfo',
        subBuilder: ConstantInfoPB.create)
    ..aOM<OutputUnitInfoPB>(
        105,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'outputUnitInfo',
        subBuilder: OutputUnitInfoPB.create)
    ..aOM<TypedefInfoPB>(
        106,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'typedefInfo',
        subBuilder: TypedefInfoPB.create)
    ..aOM<ClosureInfoPB>(
        107,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'closureInfo',
        subBuilder: ClosureInfoPB.create)
    ..aOM<ClassTypeInfoPB>(
        108,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'classTypeInfo',
        subBuilder: ClassTypeInfoPB.create)
    ..hasRequiredFields = false;

  InfoPB._() : super();
  factory InfoPB({
    $core.String? name,
    $core.int? id,
    $core.String? serializedId,
    $core.String? coverageId,
    $core.int? size,
    $core.String? parentId,
    $core.Iterable<DependencyInfoPB>? uses,
    $core.String? outputUnitId,
    LibraryInfoPB? libraryInfo,
    ClassInfoPB? classInfo,
    FunctionInfoPB? functionInfo,
    FieldInfoPB? fieldInfo,
    ConstantInfoPB? constantInfo,
    OutputUnitInfoPB? outputUnitInfo,
    TypedefInfoPB? typedefInfo,
    ClosureInfoPB? closureInfo,
    ClassTypeInfoPB? classTypeInfo,
  }) {
    final _result = create();
    if (name != null) {
      _result.name = name;
    }
    if (id != null) {
      _result.id = id;
    }
    if (serializedId != null) {
      _result.serializedId = serializedId;
    }
    if (coverageId != null) {
      _result.coverageId = coverageId;
    }
    if (size != null) {
      _result.size = size;
    }
    if (parentId != null) {
      _result.parentId = parentId;
    }
    if (uses != null) {
      _result.uses.addAll(uses);
    }
    if (outputUnitId != null) {
      _result.outputUnitId = outputUnitId;
    }
    if (libraryInfo != null) {
      _result.libraryInfo = libraryInfo;
    }
    if (classInfo != null) {
      _result.classInfo = classInfo;
    }
    if (functionInfo != null) {
      _result.functionInfo = functionInfo;
    }
    if (fieldInfo != null) {
      _result.fieldInfo = fieldInfo;
    }
    if (constantInfo != null) {
      _result.constantInfo = constantInfo;
    }
    if (outputUnitInfo != null) {
      _result.outputUnitInfo = outputUnitInfo;
    }
    if (typedefInfo != null) {
      _result.typedefInfo = typedefInfo;
    }
    if (closureInfo != null) {
      _result.closureInfo = closureInfo;
    }
    if (classTypeInfo != null) {
      _result.classTypeInfo = classTypeInfo;
    }
    return _result;
  }
  factory InfoPB.fromBuffer($core.List<$core.int> i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromBuffer(i, r);
  factory InfoPB.fromJson($core.String i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromJson(i, r);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
      'Will be removed in next major version')
  InfoPB clone() => InfoPB()..mergeFromMessage(this);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
      'Will be removed in next major version')
  InfoPB copyWith(void Function(InfoPB) updates) =>
      super.copyWith((message) => updates(message as InfoPB))
          as InfoPB; // ignore: deprecated_member_use
  $pb.BuilderInfo get info_ => _i;
  @$core.pragma('dart2js:noInline')
  static InfoPB create() => InfoPB._();
  InfoPB createEmptyInstance() => create();
  static $pb.PbList<InfoPB> createRepeated() => $pb.PbList<InfoPB>();
  @$core.pragma('dart2js:noInline')
  static InfoPB getDefault() =>
      _defaultInstance ??= $pb.GeneratedMessage.$_defaultFor<InfoPB>(create);
  static InfoPB? _defaultInstance;

  InfoPB_Concrete whichConcrete() => _InfoPB_ConcreteByTag[$_whichOneof(0)]!;
  void clearConcrete() => clearField($_whichOneof(0));

  @$pb.TagNumber(1)
  $core.String get name => $_getSZ(0);
  @$pb.TagNumber(1)
  set name($core.String v) {
    $_setString(0, v);
  }

  @$pb.TagNumber(1)
  $core.bool hasName() => $_has(0);
  @$pb.TagNumber(1)
  void clearName() => clearField(1);

  @$pb.TagNumber(2)
  $core.int get id => $_getIZ(1);
  @$pb.TagNumber(2)
  set id($core.int v) {
    $_setSignedInt32(1, v);
  }

  @$pb.TagNumber(2)
  $core.bool hasId() => $_has(1);
  @$pb.TagNumber(2)
  void clearId() => clearField(2);

  @$pb.TagNumber(3)
  $core.String get serializedId => $_getSZ(2);
  @$pb.TagNumber(3)
  set serializedId($core.String v) {
    $_setString(2, v);
  }

  @$pb.TagNumber(3)
  $core.bool hasSerializedId() => $_has(2);
  @$pb.TagNumber(3)
  void clearSerializedId() => clearField(3);

  @$pb.TagNumber(4)
  $core.String get coverageId => $_getSZ(3);
  @$pb.TagNumber(4)
  set coverageId($core.String v) {
    $_setString(3, v);
  }

  @$pb.TagNumber(4)
  $core.bool hasCoverageId() => $_has(3);
  @$pb.TagNumber(4)
  void clearCoverageId() => clearField(4);

  @$pb.TagNumber(5)
  $core.int get size => $_getIZ(4);
  @$pb.TagNumber(5)
  set size($core.int v) {
    $_setSignedInt32(4, v);
  }

  @$pb.TagNumber(5)
  $core.bool hasSize() => $_has(4);
  @$pb.TagNumber(5)
  void clearSize() => clearField(5);

  @$pb.TagNumber(6)
  $core.String get parentId => $_getSZ(5);
  @$pb.TagNumber(6)
  set parentId($core.String v) {
    $_setString(5, v);
  }

  @$pb.TagNumber(6)
  $core.bool hasParentId() => $_has(5);
  @$pb.TagNumber(6)
  void clearParentId() => clearField(6);

  @$pb.TagNumber(7)
  $core.List<DependencyInfoPB> get uses => $_getList(6);

  @$pb.TagNumber(8)
  $core.String get outputUnitId => $_getSZ(7);
  @$pb.TagNumber(8)
  set outputUnitId($core.String v) {
    $_setString(7, v);
  }

  @$pb.TagNumber(8)
  $core.bool hasOutputUnitId() => $_has(7);
  @$pb.TagNumber(8)
  void clearOutputUnitId() => clearField(8);

  @$pb.TagNumber(100)
  LibraryInfoPB get libraryInfo => $_getN(8);
  @$pb.TagNumber(100)
  set libraryInfo(LibraryInfoPB v) {
    setField(100, v);
  }

  @$pb.TagNumber(100)
  $core.bool hasLibraryInfo() => $_has(8);
  @$pb.TagNumber(100)
  void clearLibraryInfo() => clearField(100);
  @$pb.TagNumber(100)
  LibraryInfoPB ensureLibraryInfo() => $_ensure(8);

  @$pb.TagNumber(101)
  ClassInfoPB get classInfo => $_getN(9);
  @$pb.TagNumber(101)
  set classInfo(ClassInfoPB v) {
    setField(101, v);
  }

  @$pb.TagNumber(101)
  $core.bool hasClassInfo() => $_has(9);
  @$pb.TagNumber(101)
  void clearClassInfo() => clearField(101);
  @$pb.TagNumber(101)
  ClassInfoPB ensureClassInfo() => $_ensure(9);

  @$pb.TagNumber(102)
  FunctionInfoPB get functionInfo => $_getN(10);
  @$pb.TagNumber(102)
  set functionInfo(FunctionInfoPB v) {
    setField(102, v);
  }

  @$pb.TagNumber(102)
  $core.bool hasFunctionInfo() => $_has(10);
  @$pb.TagNumber(102)
  void clearFunctionInfo() => clearField(102);
  @$pb.TagNumber(102)
  FunctionInfoPB ensureFunctionInfo() => $_ensure(10);

  @$pb.TagNumber(103)
  FieldInfoPB get fieldInfo => $_getN(11);
  @$pb.TagNumber(103)
  set fieldInfo(FieldInfoPB v) {
    setField(103, v);
  }

  @$pb.TagNumber(103)
  $core.bool hasFieldInfo() => $_has(11);
  @$pb.TagNumber(103)
  void clearFieldInfo() => clearField(103);
  @$pb.TagNumber(103)
  FieldInfoPB ensureFieldInfo() => $_ensure(11);

  @$pb.TagNumber(104)
  ConstantInfoPB get constantInfo => $_getN(12);
  @$pb.TagNumber(104)
  set constantInfo(ConstantInfoPB v) {
    setField(104, v);
  }

  @$pb.TagNumber(104)
  $core.bool hasConstantInfo() => $_has(12);
  @$pb.TagNumber(104)
  void clearConstantInfo() => clearField(104);
  @$pb.TagNumber(104)
  ConstantInfoPB ensureConstantInfo() => $_ensure(12);

  @$pb.TagNumber(105)
  OutputUnitInfoPB get outputUnitInfo => $_getN(13);
  @$pb.TagNumber(105)
  set outputUnitInfo(OutputUnitInfoPB v) {
    setField(105, v);
  }

  @$pb.TagNumber(105)
  $core.bool hasOutputUnitInfo() => $_has(13);
  @$pb.TagNumber(105)
  void clearOutputUnitInfo() => clearField(105);
  @$pb.TagNumber(105)
  OutputUnitInfoPB ensureOutputUnitInfo() => $_ensure(13);

  @$pb.TagNumber(106)
  TypedefInfoPB get typedefInfo => $_getN(14);
  @$pb.TagNumber(106)
  set typedefInfo(TypedefInfoPB v) {
    setField(106, v);
  }

  @$pb.TagNumber(106)
  $core.bool hasTypedefInfo() => $_has(14);
  @$pb.TagNumber(106)
  void clearTypedefInfo() => clearField(106);
  @$pb.TagNumber(106)
  TypedefInfoPB ensureTypedefInfo() => $_ensure(14);

  @$pb.TagNumber(107)
  ClosureInfoPB get closureInfo => $_getN(15);
  @$pb.TagNumber(107)
  set closureInfo(ClosureInfoPB v) {
    setField(107, v);
  }

  @$pb.TagNumber(107)
  $core.bool hasClosureInfo() => $_has(15);
  @$pb.TagNumber(107)
  void clearClosureInfo() => clearField(107);
  @$pb.TagNumber(107)
  ClosureInfoPB ensureClosureInfo() => $_ensure(15);

  @$pb.TagNumber(108)
  ClassTypeInfoPB get classTypeInfo => $_getN(16);
  @$pb.TagNumber(108)
  set classTypeInfo(ClassTypeInfoPB v) {
    setField(108, v);
  }

  @$pb.TagNumber(108)
  $core.bool hasClassTypeInfo() => $_has(16);
  @$pb.TagNumber(108)
  void clearClassTypeInfo() => clearField(108);
  @$pb.TagNumber(108)
  ClassTypeInfoPB ensureClassTypeInfo() => $_ensure(16);
}

class ProgramInfoPB extends $pb.GeneratedMessage {
  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
      const $core.bool.fromEnvironment('protobuf.omit_message_names')
          ? ''
          : 'ProgramInfoPB',
      package: const $pb.PackageName(
          const $core.bool.fromEnvironment('protobuf.omit_message_names')
              ? ''
              : 'dart2js_info.proto'),
      createEmptyInstance: create)
    ..aOS(
        1,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'entrypointId')
    ..a<$core.int>(
        2,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'size',
        $pb.PbFieldType.O3)
    ..aOS(
        3,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'dart2jsVersion')
    ..aInt64(
        4,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'compilationMoment')
    ..aInt64(
        5,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'compilationDuration')
    ..aInt64(
        6,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'toProtoDuration')
    ..aInt64(
        7,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'dumpInfoDuration')
    ..aOB(
        8,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'noSuchMethodEnabled')
    ..aOB(
        9,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'isRuntimeTypeUsed')
    ..aOB(
        10,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'isIsolateUsed')
    ..aOB(
        11,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'isFunctionApplyUsed')
    ..aOB(
        12,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'isMirrorsUsed')
    ..aOB(
        13,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'minified')
    ..hasRequiredFields = false;

  ProgramInfoPB._() : super();
  factory ProgramInfoPB({
    $core.String? entrypointId,
    $core.int? size,
    $core.String? dart2jsVersion,
    $fixnum.Int64? compilationMoment,
    $fixnum.Int64? compilationDuration,
    $fixnum.Int64? toProtoDuration,
    $fixnum.Int64? dumpInfoDuration,
    $core.bool? noSuchMethodEnabled,
    $core.bool? isRuntimeTypeUsed,
    $core.bool? isIsolateUsed,
    $core.bool? isFunctionApplyUsed,
    $core.bool? isMirrorsUsed,
    $core.bool? minified,
  }) {
    final _result = create();
    if (entrypointId != null) {
      _result.entrypointId = entrypointId;
    }
    if (size != null) {
      _result.size = size;
    }
    if (dart2jsVersion != null) {
      _result.dart2jsVersion = dart2jsVersion;
    }
    if (compilationMoment != null) {
      _result.compilationMoment = compilationMoment;
    }
    if (compilationDuration != null) {
      _result.compilationDuration = compilationDuration;
    }
    if (toProtoDuration != null) {
      _result.toProtoDuration = toProtoDuration;
    }
    if (dumpInfoDuration != null) {
      _result.dumpInfoDuration = dumpInfoDuration;
    }
    if (noSuchMethodEnabled != null) {
      _result.noSuchMethodEnabled = noSuchMethodEnabled;
    }
    if (isRuntimeTypeUsed != null) {
      _result.isRuntimeTypeUsed = isRuntimeTypeUsed;
    }
    if (isIsolateUsed != null) {
      _result.isIsolateUsed = isIsolateUsed;
    }
    if (isFunctionApplyUsed != null) {
      _result.isFunctionApplyUsed = isFunctionApplyUsed;
    }
    if (isMirrorsUsed != null) {
      _result.isMirrorsUsed = isMirrorsUsed;
    }
    if (minified != null) {
      _result.minified = minified;
    }
    return _result;
  }
  factory ProgramInfoPB.fromBuffer($core.List<$core.int> i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromBuffer(i, r);
  factory ProgramInfoPB.fromJson($core.String i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromJson(i, r);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
      'Will be removed in next major version')
  ProgramInfoPB clone() => ProgramInfoPB()..mergeFromMessage(this);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
      'Will be removed in next major version')
  ProgramInfoPB copyWith(void Function(ProgramInfoPB) updates) =>
      super.copyWith((message) => updates(message as ProgramInfoPB))
          as ProgramInfoPB; // ignore: deprecated_member_use
  $pb.BuilderInfo get info_ => _i;
  @$core.pragma('dart2js:noInline')
  static ProgramInfoPB create() => ProgramInfoPB._();
  ProgramInfoPB createEmptyInstance() => create();
  static $pb.PbList<ProgramInfoPB> createRepeated() =>
      $pb.PbList<ProgramInfoPB>();
  @$core.pragma('dart2js:noInline')
  static ProgramInfoPB getDefault() => _defaultInstance ??=
      $pb.GeneratedMessage.$_defaultFor<ProgramInfoPB>(create);
  static ProgramInfoPB? _defaultInstance;

  @$pb.TagNumber(1)
  $core.String get entrypointId => $_getSZ(0);
  @$pb.TagNumber(1)
  set entrypointId($core.String v) {
    $_setString(0, v);
  }

  @$pb.TagNumber(1)
  $core.bool hasEntrypointId() => $_has(0);
  @$pb.TagNumber(1)
  void clearEntrypointId() => clearField(1);

  @$pb.TagNumber(2)
  $core.int get size => $_getIZ(1);
  @$pb.TagNumber(2)
  set size($core.int v) {
    $_setSignedInt32(1, v);
  }

  @$pb.TagNumber(2)
  $core.bool hasSize() => $_has(1);
  @$pb.TagNumber(2)
  void clearSize() => clearField(2);

  @$pb.TagNumber(3)
  $core.String get dart2jsVersion => $_getSZ(2);
  @$pb.TagNumber(3)
  set dart2jsVersion($core.String v) {
    $_setString(2, v);
  }

  @$pb.TagNumber(3)
  $core.bool hasDart2jsVersion() => $_has(2);
  @$pb.TagNumber(3)
  void clearDart2jsVersion() => clearField(3);

  @$pb.TagNumber(4)
  $fixnum.Int64 get compilationMoment => $_getI64(3);
  @$pb.TagNumber(4)
  set compilationMoment($fixnum.Int64 v) {
    $_setInt64(3, v);
  }

  @$pb.TagNumber(4)
  $core.bool hasCompilationMoment() => $_has(3);
  @$pb.TagNumber(4)
  void clearCompilationMoment() => clearField(4);

  @$pb.TagNumber(5)
  $fixnum.Int64 get compilationDuration => $_getI64(4);
  @$pb.TagNumber(5)
  set compilationDuration($fixnum.Int64 v) {
    $_setInt64(4, v);
  }

  @$pb.TagNumber(5)
  $core.bool hasCompilationDuration() => $_has(4);
  @$pb.TagNumber(5)
  void clearCompilationDuration() => clearField(5);

  @$pb.TagNumber(6)
  $fixnum.Int64 get toProtoDuration => $_getI64(5);
  @$pb.TagNumber(6)
  set toProtoDuration($fixnum.Int64 v) {
    $_setInt64(5, v);
  }

  @$pb.TagNumber(6)
  $core.bool hasToProtoDuration() => $_has(5);
  @$pb.TagNumber(6)
  void clearToProtoDuration() => clearField(6);

  @$pb.TagNumber(7)
  $fixnum.Int64 get dumpInfoDuration => $_getI64(6);
  @$pb.TagNumber(7)
  set dumpInfoDuration($fixnum.Int64 v) {
    $_setInt64(6, v);
  }

  @$pb.TagNumber(7)
  $core.bool hasDumpInfoDuration() => $_has(6);
  @$pb.TagNumber(7)
  void clearDumpInfoDuration() => clearField(7);

  @$pb.TagNumber(8)
  $core.bool get noSuchMethodEnabled => $_getBF(7);
  @$pb.TagNumber(8)
  set noSuchMethodEnabled($core.bool v) {
    $_setBool(7, v);
  }

  @$pb.TagNumber(8)
  $core.bool hasNoSuchMethodEnabled() => $_has(7);
  @$pb.TagNumber(8)
  void clearNoSuchMethodEnabled() => clearField(8);

  @$pb.TagNumber(9)
  $core.bool get isRuntimeTypeUsed => $_getBF(8);
  @$pb.TagNumber(9)
  set isRuntimeTypeUsed($core.bool v) {
    $_setBool(8, v);
  }

  @$pb.TagNumber(9)
  $core.bool hasIsRuntimeTypeUsed() => $_has(8);
  @$pb.TagNumber(9)
  void clearIsRuntimeTypeUsed() => clearField(9);

  @$pb.TagNumber(10)
  $core.bool get isIsolateUsed => $_getBF(9);
  @$pb.TagNumber(10)
  set isIsolateUsed($core.bool v) {
    $_setBool(9, v);
  }

  @$pb.TagNumber(10)
  $core.bool hasIsIsolateUsed() => $_has(9);
  @$pb.TagNumber(10)
  void clearIsIsolateUsed() => clearField(10);

  @$pb.TagNumber(11)
  $core.bool get isFunctionApplyUsed => $_getBF(10);
  @$pb.TagNumber(11)
  set isFunctionApplyUsed($core.bool v) {
    $_setBool(10, v);
  }

  @$pb.TagNumber(11)
  $core.bool hasIsFunctionApplyUsed() => $_has(10);
  @$pb.TagNumber(11)
  void clearIsFunctionApplyUsed() => clearField(11);

  @$pb.TagNumber(12)
  $core.bool get isMirrorsUsed => $_getBF(11);
  @$pb.TagNumber(12)
  set isMirrorsUsed($core.bool v) {
    $_setBool(11, v);
  }

  @$pb.TagNumber(12)
  $core.bool hasIsMirrorsUsed() => $_has(11);
  @$pb.TagNumber(12)
  void clearIsMirrorsUsed() => clearField(12);

  @$pb.TagNumber(13)
  $core.bool get minified => $_getBF(12);
  @$pb.TagNumber(13)
  set minified($core.bool v) {
    $_setBool(12, v);
  }

  @$pb.TagNumber(13)
  $core.bool hasMinified() => $_has(12);
  @$pb.TagNumber(13)
  void clearMinified() => clearField(13);
}

class LibraryInfoPB extends $pb.GeneratedMessage {
  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
      const $core.bool.fromEnvironment('protobuf.omit_message_names')
          ? ''
          : 'LibraryInfoPB',
      package: const $pb.PackageName(
          const $core.bool.fromEnvironment('protobuf.omit_message_names')
              ? ''
              : 'dart2js_info.proto'),
      createEmptyInstance: create)
    ..aOS(
        1,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'uri')
    ..pPS(
        2,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'childrenIds')
    ..hasRequiredFields = false;

  LibraryInfoPB._() : super();
  factory LibraryInfoPB({
    $core.String? uri,
    $core.Iterable<$core.String>? childrenIds,
  }) {
    final _result = create();
    if (uri != null) {
      _result.uri = uri;
    }
    if (childrenIds != null) {
      _result.childrenIds.addAll(childrenIds);
    }
    return _result;
  }
  factory LibraryInfoPB.fromBuffer($core.List<$core.int> i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromBuffer(i, r);
  factory LibraryInfoPB.fromJson($core.String i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromJson(i, r);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
      'Will be removed in next major version')
  LibraryInfoPB clone() => LibraryInfoPB()..mergeFromMessage(this);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
      'Will be removed in next major version')
  LibraryInfoPB copyWith(void Function(LibraryInfoPB) updates) =>
      super.copyWith((message) => updates(message as LibraryInfoPB))
          as LibraryInfoPB; // ignore: deprecated_member_use
  $pb.BuilderInfo get info_ => _i;
  @$core.pragma('dart2js:noInline')
  static LibraryInfoPB create() => LibraryInfoPB._();
  LibraryInfoPB createEmptyInstance() => create();
  static $pb.PbList<LibraryInfoPB> createRepeated() =>
      $pb.PbList<LibraryInfoPB>();
  @$core.pragma('dart2js:noInline')
  static LibraryInfoPB getDefault() => _defaultInstance ??=
      $pb.GeneratedMessage.$_defaultFor<LibraryInfoPB>(create);
  static LibraryInfoPB? _defaultInstance;

  @$pb.TagNumber(1)
  $core.String get uri => $_getSZ(0);
  @$pb.TagNumber(1)
  set uri($core.String v) {
    $_setString(0, v);
  }

  @$pb.TagNumber(1)
  $core.bool hasUri() => $_has(0);
  @$pb.TagNumber(1)
  void clearUri() => clearField(1);

  @$pb.TagNumber(2)
  $core.List<$core.String> get childrenIds => $_getList(1);
}

class OutputUnitInfoPB extends $pb.GeneratedMessage {
  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
      const $core.bool.fromEnvironment('protobuf.omit_message_names')
          ? ''
          : 'OutputUnitInfoPB',
      package: const $pb.PackageName(
          const $core.bool.fromEnvironment('protobuf.omit_message_names')
              ? ''
              : 'dart2js_info.proto'),
      createEmptyInstance: create)
    ..pPS(
        1,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'imports')
    ..hasRequiredFields = false;

  OutputUnitInfoPB._() : super();
  factory OutputUnitInfoPB({
    $core.Iterable<$core.String>? imports,
  }) {
    final _result = create();
    if (imports != null) {
      _result.imports.addAll(imports);
    }
    return _result;
  }
  factory OutputUnitInfoPB.fromBuffer($core.List<$core.int> i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromBuffer(i, r);
  factory OutputUnitInfoPB.fromJson($core.String i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromJson(i, r);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
      'Will be removed in next major version')
  OutputUnitInfoPB clone() => OutputUnitInfoPB()..mergeFromMessage(this);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
      'Will be removed in next major version')
  OutputUnitInfoPB copyWith(void Function(OutputUnitInfoPB) updates) =>
      super.copyWith((message) => updates(message as OutputUnitInfoPB))
          as OutputUnitInfoPB; // ignore: deprecated_member_use
  $pb.BuilderInfo get info_ => _i;
  @$core.pragma('dart2js:noInline')
  static OutputUnitInfoPB create() => OutputUnitInfoPB._();
  OutputUnitInfoPB createEmptyInstance() => create();
  static $pb.PbList<OutputUnitInfoPB> createRepeated() =>
      $pb.PbList<OutputUnitInfoPB>();
  @$core.pragma('dart2js:noInline')
  static OutputUnitInfoPB getDefault() => _defaultInstance ??=
      $pb.GeneratedMessage.$_defaultFor<OutputUnitInfoPB>(create);
  static OutputUnitInfoPB? _defaultInstance;

  @$pb.TagNumber(1)
  $core.List<$core.String> get imports => $_getList(0);
}

class ClassInfoPB extends $pb.GeneratedMessage {
  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
      const $core.bool.fromEnvironment('protobuf.omit_message_names')
          ? ''
          : 'ClassInfoPB',
      package: const $pb.PackageName(
          const $core.bool.fromEnvironment('protobuf.omit_message_names')
              ? ''
              : 'dart2js_info.proto'),
      createEmptyInstance: create)
    ..aOB(
        1,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'isAbstract')
    ..pPS(
        2,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'childrenIds')
    ..hasRequiredFields = false;

  ClassInfoPB._() : super();
  factory ClassInfoPB({
    $core.bool? isAbstract,
    $core.Iterable<$core.String>? childrenIds,
  }) {
    final _result = create();
    if (isAbstract != null) {
      _result.isAbstract = isAbstract;
    }
    if (childrenIds != null) {
      _result.childrenIds.addAll(childrenIds);
    }
    return _result;
  }
  factory ClassInfoPB.fromBuffer($core.List<$core.int> i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromBuffer(i, r);
  factory ClassInfoPB.fromJson($core.String i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromJson(i, r);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
      'Will be removed in next major version')
  ClassInfoPB clone() => ClassInfoPB()..mergeFromMessage(this);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
      'Will be removed in next major version')
  ClassInfoPB copyWith(void Function(ClassInfoPB) updates) =>
      super.copyWith((message) => updates(message as ClassInfoPB))
          as ClassInfoPB; // ignore: deprecated_member_use
  $pb.BuilderInfo get info_ => _i;
  @$core.pragma('dart2js:noInline')
  static ClassInfoPB create() => ClassInfoPB._();
  ClassInfoPB createEmptyInstance() => create();
  static $pb.PbList<ClassInfoPB> createRepeated() => $pb.PbList<ClassInfoPB>();
  @$core.pragma('dart2js:noInline')
  static ClassInfoPB getDefault() => _defaultInstance ??=
      $pb.GeneratedMessage.$_defaultFor<ClassInfoPB>(create);
  static ClassInfoPB? _defaultInstance;

  @$pb.TagNumber(1)
  $core.bool get isAbstract => $_getBF(0);
  @$pb.TagNumber(1)
  set isAbstract($core.bool v) {
    $_setBool(0, v);
  }

  @$pb.TagNumber(1)
  $core.bool hasIsAbstract() => $_has(0);
  @$pb.TagNumber(1)
  void clearIsAbstract() => clearField(1);

  @$pb.TagNumber(2)
  $core.List<$core.String> get childrenIds => $_getList(1);
}

class ClassTypeInfoPB extends $pb.GeneratedMessage {
  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
      const $core.bool.fromEnvironment('protobuf.omit_message_names')
          ? ''
          : 'ClassTypeInfoPB',
      package: const $pb.PackageName(
          const $core.bool.fromEnvironment('protobuf.omit_message_names')
              ? ''
              : 'dart2js_info.proto'),
      createEmptyInstance: create)
    ..hasRequiredFields = false;

  ClassTypeInfoPB._() : super();
  factory ClassTypeInfoPB() => create();
  factory ClassTypeInfoPB.fromBuffer($core.List<$core.int> i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromBuffer(i, r);
  factory ClassTypeInfoPB.fromJson($core.String i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromJson(i, r);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
      'Will be removed in next major version')
  ClassTypeInfoPB clone() => ClassTypeInfoPB()..mergeFromMessage(this);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
      'Will be removed in next major version')
  ClassTypeInfoPB copyWith(void Function(ClassTypeInfoPB) updates) =>
      super.copyWith((message) => updates(message as ClassTypeInfoPB))
          as ClassTypeInfoPB; // ignore: deprecated_member_use
  $pb.BuilderInfo get info_ => _i;
  @$core.pragma('dart2js:noInline')
  static ClassTypeInfoPB create() => ClassTypeInfoPB._();
  ClassTypeInfoPB createEmptyInstance() => create();
  static $pb.PbList<ClassTypeInfoPB> createRepeated() =>
      $pb.PbList<ClassTypeInfoPB>();
  @$core.pragma('dart2js:noInline')
  static ClassTypeInfoPB getDefault() => _defaultInstance ??=
      $pb.GeneratedMessage.$_defaultFor<ClassTypeInfoPB>(create);
  static ClassTypeInfoPB? _defaultInstance;
}

class ConstantInfoPB extends $pb.GeneratedMessage {
  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
      const $core.bool.fromEnvironment('protobuf.omit_message_names')
          ? ''
          : 'ConstantInfoPB',
      package: const $pb.PackageName(
          const $core.bool.fromEnvironment('protobuf.omit_message_names')
              ? ''
              : 'dart2js_info.proto'),
      createEmptyInstance: create)
    ..aOS(
        1,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'code')
    ..hasRequiredFields = false;

  ConstantInfoPB._() : super();
  factory ConstantInfoPB({
    $core.String? code,
  }) {
    final _result = create();
    if (code != null) {
      _result.code = code;
    }
    return _result;
  }
  factory ConstantInfoPB.fromBuffer($core.List<$core.int> i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromBuffer(i, r);
  factory ConstantInfoPB.fromJson($core.String i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromJson(i, r);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
      'Will be removed in next major version')
  ConstantInfoPB clone() => ConstantInfoPB()..mergeFromMessage(this);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
      'Will be removed in next major version')
  ConstantInfoPB copyWith(void Function(ConstantInfoPB) updates) =>
      super.copyWith((message) => updates(message as ConstantInfoPB))
          as ConstantInfoPB; // ignore: deprecated_member_use
  $pb.BuilderInfo get info_ => _i;
  @$core.pragma('dart2js:noInline')
  static ConstantInfoPB create() => ConstantInfoPB._();
  ConstantInfoPB createEmptyInstance() => create();
  static $pb.PbList<ConstantInfoPB> createRepeated() =>
      $pb.PbList<ConstantInfoPB>();
  @$core.pragma('dart2js:noInline')
  static ConstantInfoPB getDefault() => _defaultInstance ??=
      $pb.GeneratedMessage.$_defaultFor<ConstantInfoPB>(create);
  static ConstantInfoPB? _defaultInstance;

  @$pb.TagNumber(1)
  $core.String get code => $_getSZ(0);
  @$pb.TagNumber(1)
  set code($core.String v) {
    $_setString(0, v);
  }

  @$pb.TagNumber(1)
  $core.bool hasCode() => $_has(0);
  @$pb.TagNumber(1)
  void clearCode() => clearField(1);
}

class FieldInfoPB extends $pb.GeneratedMessage {
  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
      const $core.bool.fromEnvironment('protobuf.omit_message_names')
          ? ''
          : 'FieldInfoPB',
      package: const $pb.PackageName(
          const $core.bool.fromEnvironment('protobuf.omit_message_names')
              ? ''
              : 'dart2js_info.proto'),
      createEmptyInstance: create)
    ..aOS(
        1,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'type')
    ..aOS(
        2,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'inferredType')
    ..pPS(
        3,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'childrenIds')
    ..aOS(
        4,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'code')
    ..aOB(
        5,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'isConst')
    ..aOS(
        6,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'initializerId')
    ..hasRequiredFields = false;

  FieldInfoPB._() : super();
  factory FieldInfoPB({
    $core.String? type,
    $core.String? inferredType,
    $core.Iterable<$core.String>? childrenIds,
    $core.String? code,
    $core.bool? isConst,
    $core.String? initializerId,
  }) {
    final _result = create();
    if (type != null) {
      _result.type = type;
    }
    if (inferredType != null) {
      _result.inferredType = inferredType;
    }
    if (childrenIds != null) {
      _result.childrenIds.addAll(childrenIds);
    }
    if (code != null) {
      _result.code = code;
    }
    if (isConst != null) {
      _result.isConst = isConst;
    }
    if (initializerId != null) {
      _result.initializerId = initializerId;
    }
    return _result;
  }
  factory FieldInfoPB.fromBuffer($core.List<$core.int> i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromBuffer(i, r);
  factory FieldInfoPB.fromJson($core.String i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromJson(i, r);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
      'Will be removed in next major version')
  FieldInfoPB clone() => FieldInfoPB()..mergeFromMessage(this);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
      'Will be removed in next major version')
  FieldInfoPB copyWith(void Function(FieldInfoPB) updates) =>
      super.copyWith((message) => updates(message as FieldInfoPB))
          as FieldInfoPB; // ignore: deprecated_member_use
  $pb.BuilderInfo get info_ => _i;
  @$core.pragma('dart2js:noInline')
  static FieldInfoPB create() => FieldInfoPB._();
  FieldInfoPB createEmptyInstance() => create();
  static $pb.PbList<FieldInfoPB> createRepeated() => $pb.PbList<FieldInfoPB>();
  @$core.pragma('dart2js:noInline')
  static FieldInfoPB getDefault() => _defaultInstance ??=
      $pb.GeneratedMessage.$_defaultFor<FieldInfoPB>(create);
  static FieldInfoPB? _defaultInstance;

  @$pb.TagNumber(1)
  $core.String get type => $_getSZ(0);
  @$pb.TagNumber(1)
  set type($core.String v) {
    $_setString(0, v);
  }

  @$pb.TagNumber(1)
  $core.bool hasType() => $_has(0);
  @$pb.TagNumber(1)
  void clearType() => clearField(1);

  @$pb.TagNumber(2)
  $core.String get inferredType => $_getSZ(1);
  @$pb.TagNumber(2)
  set inferredType($core.String v) {
    $_setString(1, v);
  }

  @$pb.TagNumber(2)
  $core.bool hasInferredType() => $_has(1);
  @$pb.TagNumber(2)
  void clearInferredType() => clearField(2);

  @$pb.TagNumber(3)
  $core.List<$core.String> get childrenIds => $_getList(2);

  @$pb.TagNumber(4)
  $core.String get code => $_getSZ(3);
  @$pb.TagNumber(4)
  set code($core.String v) {
    $_setString(3, v);
  }

  @$pb.TagNumber(4)
  $core.bool hasCode() => $_has(3);
  @$pb.TagNumber(4)
  void clearCode() => clearField(4);

  @$pb.TagNumber(5)
  $core.bool get isConst => $_getBF(4);
  @$pb.TagNumber(5)
  set isConst($core.bool v) {
    $_setBool(4, v);
  }

  @$pb.TagNumber(5)
  $core.bool hasIsConst() => $_has(4);
  @$pb.TagNumber(5)
  void clearIsConst() => clearField(5);

  @$pb.TagNumber(6)
  $core.String get initializerId => $_getSZ(5);
  @$pb.TagNumber(6)
  set initializerId($core.String v) {
    $_setString(5, v);
  }

  @$pb.TagNumber(6)
  $core.bool hasInitializerId() => $_has(5);
  @$pb.TagNumber(6)
  void clearInitializerId() => clearField(6);
}

class TypedefInfoPB extends $pb.GeneratedMessage {
  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
      const $core.bool.fromEnvironment('protobuf.omit_message_names')
          ? ''
          : 'TypedefInfoPB',
      package: const $pb.PackageName(
          const $core.bool.fromEnvironment('protobuf.omit_message_names')
              ? ''
              : 'dart2js_info.proto'),
      createEmptyInstance: create)
    ..aOS(
        1,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'type')
    ..hasRequiredFields = false;

  TypedefInfoPB._() : super();
  factory TypedefInfoPB({
    $core.String? type,
  }) {
    final _result = create();
    if (type != null) {
      _result.type = type;
    }
    return _result;
  }
  factory TypedefInfoPB.fromBuffer($core.List<$core.int> i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromBuffer(i, r);
  factory TypedefInfoPB.fromJson($core.String i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromJson(i, r);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
      'Will be removed in next major version')
  TypedefInfoPB clone() => TypedefInfoPB()..mergeFromMessage(this);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
      'Will be removed in next major version')
  TypedefInfoPB copyWith(void Function(TypedefInfoPB) updates) =>
      super.copyWith((message) => updates(message as TypedefInfoPB))
          as TypedefInfoPB; // ignore: deprecated_member_use
  $pb.BuilderInfo get info_ => _i;
  @$core.pragma('dart2js:noInline')
  static TypedefInfoPB create() => TypedefInfoPB._();
  TypedefInfoPB createEmptyInstance() => create();
  static $pb.PbList<TypedefInfoPB> createRepeated() =>
      $pb.PbList<TypedefInfoPB>();
  @$core.pragma('dart2js:noInline')
  static TypedefInfoPB getDefault() => _defaultInstance ??=
      $pb.GeneratedMessage.$_defaultFor<TypedefInfoPB>(create);
  static TypedefInfoPB? _defaultInstance;

  @$pb.TagNumber(1)
  $core.String get type => $_getSZ(0);
  @$pb.TagNumber(1)
  set type($core.String v) {
    $_setString(0, v);
  }

  @$pb.TagNumber(1)
  $core.bool hasType() => $_has(0);
  @$pb.TagNumber(1)
  void clearType() => clearField(1);
}

class FunctionModifiersPB extends $pb.GeneratedMessage {
  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
      const $core.bool.fromEnvironment('protobuf.omit_message_names')
          ? ''
          : 'FunctionModifiersPB',
      package: const $pb.PackageName(
          const $core.bool.fromEnvironment('protobuf.omit_message_names')
              ? ''
              : 'dart2js_info.proto'),
      createEmptyInstance: create)
    ..aOB(
        1,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'isStatic')
    ..aOB(
        2,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'isConst')
    ..aOB(
        3,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'isFactory')
    ..aOB(
        4,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'isExternal')
    ..hasRequiredFields = false;

  FunctionModifiersPB._() : super();
  factory FunctionModifiersPB({
    $core.bool? isStatic,
    $core.bool? isConst,
    $core.bool? isFactory,
    $core.bool? isExternal,
  }) {
    final _result = create();
    if (isStatic != null) {
      _result.isStatic = isStatic;
    }
    if (isConst != null) {
      _result.isConst = isConst;
    }
    if (isFactory != null) {
      _result.isFactory = isFactory;
    }
    if (isExternal != null) {
      _result.isExternal = isExternal;
    }
    return _result;
  }
  factory FunctionModifiersPB.fromBuffer($core.List<$core.int> i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromBuffer(i, r);
  factory FunctionModifiersPB.fromJson($core.String i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromJson(i, r);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
      'Will be removed in next major version')
  FunctionModifiersPB clone() => FunctionModifiersPB()..mergeFromMessage(this);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
      'Will be removed in next major version')
  FunctionModifiersPB copyWith(void Function(FunctionModifiersPB) updates) =>
      super.copyWith((message) => updates(message as FunctionModifiersPB))
          as FunctionModifiersPB; // ignore: deprecated_member_use
  $pb.BuilderInfo get info_ => _i;
  @$core.pragma('dart2js:noInline')
  static FunctionModifiersPB create() => FunctionModifiersPB._();
  FunctionModifiersPB createEmptyInstance() => create();
  static $pb.PbList<FunctionModifiersPB> createRepeated() =>
      $pb.PbList<FunctionModifiersPB>();
  @$core.pragma('dart2js:noInline')
  static FunctionModifiersPB getDefault() => _defaultInstance ??=
      $pb.GeneratedMessage.$_defaultFor<FunctionModifiersPB>(create);
  static FunctionModifiersPB? _defaultInstance;

  @$pb.TagNumber(1)
  $core.bool get isStatic => $_getBF(0);
  @$pb.TagNumber(1)
  set isStatic($core.bool v) {
    $_setBool(0, v);
  }

  @$pb.TagNumber(1)
  $core.bool hasIsStatic() => $_has(0);
  @$pb.TagNumber(1)
  void clearIsStatic() => clearField(1);

  @$pb.TagNumber(2)
  $core.bool get isConst => $_getBF(1);
  @$pb.TagNumber(2)
  set isConst($core.bool v) {
    $_setBool(1, v);
  }

  @$pb.TagNumber(2)
  $core.bool hasIsConst() => $_has(1);
  @$pb.TagNumber(2)
  void clearIsConst() => clearField(2);

  @$pb.TagNumber(3)
  $core.bool get isFactory => $_getBF(2);
  @$pb.TagNumber(3)
  set isFactory($core.bool v) {
    $_setBool(2, v);
  }

  @$pb.TagNumber(3)
  $core.bool hasIsFactory() => $_has(2);
  @$pb.TagNumber(3)
  void clearIsFactory() => clearField(3);

  @$pb.TagNumber(4)
  $core.bool get isExternal => $_getBF(3);
  @$pb.TagNumber(4)
  set isExternal($core.bool v) {
    $_setBool(3, v);
  }

  @$pb.TagNumber(4)
  $core.bool hasIsExternal() => $_has(3);
  @$pb.TagNumber(4)
  void clearIsExternal() => clearField(4);
}

class ParameterInfoPB extends $pb.GeneratedMessage {
  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
      const $core.bool.fromEnvironment('protobuf.omit_message_names')
          ? ''
          : 'ParameterInfoPB',
      package: const $pb.PackageName(
          const $core.bool.fromEnvironment('protobuf.omit_message_names')
              ? ''
              : 'dart2js_info.proto'),
      createEmptyInstance: create)
    ..aOS(
        1,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'name')
    ..aOS(
        2,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'type')
    ..aOS(
        3,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'declaredType')
    ..hasRequiredFields = false;

  ParameterInfoPB._() : super();
  factory ParameterInfoPB({
    $core.String? name,
    $core.String? type,
    $core.String? declaredType,
  }) {
    final _result = create();
    if (name != null) {
      _result.name = name;
    }
    if (type != null) {
      _result.type = type;
    }
    if (declaredType != null) {
      _result.declaredType = declaredType;
    }
    return _result;
  }
  factory ParameterInfoPB.fromBuffer($core.List<$core.int> i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromBuffer(i, r);
  factory ParameterInfoPB.fromJson($core.String i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromJson(i, r);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
      'Will be removed in next major version')
  ParameterInfoPB clone() => ParameterInfoPB()..mergeFromMessage(this);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
      'Will be removed in next major version')
  ParameterInfoPB copyWith(void Function(ParameterInfoPB) updates) =>
      super.copyWith((message) => updates(message as ParameterInfoPB))
          as ParameterInfoPB; // ignore: deprecated_member_use
  $pb.BuilderInfo get info_ => _i;
  @$core.pragma('dart2js:noInline')
  static ParameterInfoPB create() => ParameterInfoPB._();
  ParameterInfoPB createEmptyInstance() => create();
  static $pb.PbList<ParameterInfoPB> createRepeated() =>
      $pb.PbList<ParameterInfoPB>();
  @$core.pragma('dart2js:noInline')
  static ParameterInfoPB getDefault() => _defaultInstance ??=
      $pb.GeneratedMessage.$_defaultFor<ParameterInfoPB>(create);
  static ParameterInfoPB? _defaultInstance;

  @$pb.TagNumber(1)
  $core.String get name => $_getSZ(0);
  @$pb.TagNumber(1)
  set name($core.String v) {
    $_setString(0, v);
  }

  @$pb.TagNumber(1)
  $core.bool hasName() => $_has(0);
  @$pb.TagNumber(1)
  void clearName() => clearField(1);

  @$pb.TagNumber(2)
  $core.String get type => $_getSZ(1);
  @$pb.TagNumber(2)
  set type($core.String v) {
    $_setString(1, v);
  }

  @$pb.TagNumber(2)
  $core.bool hasType() => $_has(1);
  @$pb.TagNumber(2)
  void clearType() => clearField(2);

  @$pb.TagNumber(3)
  $core.String get declaredType => $_getSZ(2);
  @$pb.TagNumber(3)
  set declaredType($core.String v) {
    $_setString(2, v);
  }

  @$pb.TagNumber(3)
  $core.bool hasDeclaredType() => $_has(2);
  @$pb.TagNumber(3)
  void clearDeclaredType() => clearField(3);
}

class FunctionInfoPB extends $pb.GeneratedMessage {
  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
      const $core.bool.fromEnvironment('protobuf.omit_message_names')
          ? ''
          : 'FunctionInfoPB',
      package: const $pb.PackageName(
          const $core.bool.fromEnvironment('protobuf.omit_message_names')
              ? ''
              : 'dart2js_info.proto'),
      createEmptyInstance: create)
    ..aOM<FunctionModifiersPB>(
        1,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'functionModifiers',
        subBuilder: FunctionModifiersPB.create)
    ..pPS(
        2,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'childrenIds')
    ..aOS(
        3,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'returnType')
    ..aOS(
        4,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'inferredReturnType')
    ..pc<ParameterInfoPB>(
        5,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'parameters',
        $pb.PbFieldType.PM,
        subBuilder: ParameterInfoPB.create)
    ..aOS(
        6,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'sideEffects')
    ..a<$core.int>(
        7,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'inlinedCount',
        $pb.PbFieldType.O3)
    ..aOS(
        8,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'code')
    ..hasRequiredFields = false;

  FunctionInfoPB._() : super();
  factory FunctionInfoPB({
    FunctionModifiersPB? functionModifiers,
    $core.Iterable<$core.String>? childrenIds,
    $core.String? returnType,
    $core.String? inferredReturnType,
    $core.Iterable<ParameterInfoPB>? parameters,
    $core.String? sideEffects,
    $core.int? inlinedCount,
    $core.String? code,
  }) {
    final _result = create();
    if (functionModifiers != null) {
      _result.functionModifiers = functionModifiers;
    }
    if (childrenIds != null) {
      _result.childrenIds.addAll(childrenIds);
    }
    if (returnType != null) {
      _result.returnType = returnType;
    }
    if (inferredReturnType != null) {
      _result.inferredReturnType = inferredReturnType;
    }
    if (parameters != null) {
      _result.parameters.addAll(parameters);
    }
    if (sideEffects != null) {
      _result.sideEffects = sideEffects;
    }
    if (inlinedCount != null) {
      _result.inlinedCount = inlinedCount;
    }
    if (code != null) {
      _result.code = code;
    }
    return _result;
  }
  factory FunctionInfoPB.fromBuffer($core.List<$core.int> i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromBuffer(i, r);
  factory FunctionInfoPB.fromJson($core.String i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromJson(i, r);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
      'Will be removed in next major version')
  FunctionInfoPB clone() => FunctionInfoPB()..mergeFromMessage(this);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
      'Will be removed in next major version')
  FunctionInfoPB copyWith(void Function(FunctionInfoPB) updates) =>
      super.copyWith((message) => updates(message as FunctionInfoPB))
          as FunctionInfoPB; // ignore: deprecated_member_use
  $pb.BuilderInfo get info_ => _i;
  @$core.pragma('dart2js:noInline')
  static FunctionInfoPB create() => FunctionInfoPB._();
  FunctionInfoPB createEmptyInstance() => create();
  static $pb.PbList<FunctionInfoPB> createRepeated() =>
      $pb.PbList<FunctionInfoPB>();
  @$core.pragma('dart2js:noInline')
  static FunctionInfoPB getDefault() => _defaultInstance ??=
      $pb.GeneratedMessage.$_defaultFor<FunctionInfoPB>(create);
  static FunctionInfoPB? _defaultInstance;

  @$pb.TagNumber(1)
  FunctionModifiersPB get functionModifiers => $_getN(0);
  @$pb.TagNumber(1)
  set functionModifiers(FunctionModifiersPB v) {
    setField(1, v);
  }

  @$pb.TagNumber(1)
  $core.bool hasFunctionModifiers() => $_has(0);
  @$pb.TagNumber(1)
  void clearFunctionModifiers() => clearField(1);
  @$pb.TagNumber(1)
  FunctionModifiersPB ensureFunctionModifiers() => $_ensure(0);

  @$pb.TagNumber(2)
  $core.List<$core.String> get childrenIds => $_getList(1);

  @$pb.TagNumber(3)
  $core.String get returnType => $_getSZ(2);
  @$pb.TagNumber(3)
  set returnType($core.String v) {
    $_setString(2, v);
  }

  @$pb.TagNumber(3)
  $core.bool hasReturnType() => $_has(2);
  @$pb.TagNumber(3)
  void clearReturnType() => clearField(3);

  @$pb.TagNumber(4)
  $core.String get inferredReturnType => $_getSZ(3);
  @$pb.TagNumber(4)
  set inferredReturnType($core.String v) {
    $_setString(3, v);
  }

  @$pb.TagNumber(4)
  $core.bool hasInferredReturnType() => $_has(3);
  @$pb.TagNumber(4)
  void clearInferredReturnType() => clearField(4);

  @$pb.TagNumber(5)
  $core.List<ParameterInfoPB> get parameters => $_getList(4);

  @$pb.TagNumber(6)
  $core.String get sideEffects => $_getSZ(5);
  @$pb.TagNumber(6)
  set sideEffects($core.String v) {
    $_setString(5, v);
  }

  @$pb.TagNumber(6)
  $core.bool hasSideEffects() => $_has(5);
  @$pb.TagNumber(6)
  void clearSideEffects() => clearField(6);

  @$pb.TagNumber(7)
  $core.int get inlinedCount => $_getIZ(6);
  @$pb.TagNumber(7)
  set inlinedCount($core.int v) {
    $_setSignedInt32(6, v);
  }

  @$pb.TagNumber(7)
  $core.bool hasInlinedCount() => $_has(6);
  @$pb.TagNumber(7)
  void clearInlinedCount() => clearField(7);

  @$pb.TagNumber(8)
  $core.String get code => $_getSZ(7);
  @$pb.TagNumber(8)
  set code($core.String v) {
    $_setString(7, v);
  }

  @$pb.TagNumber(8)
  $core.bool hasCode() => $_has(7);
  @$pb.TagNumber(8)
  void clearCode() => clearField(8);
}

class ClosureInfoPB extends $pb.GeneratedMessage {
  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
      const $core.bool.fromEnvironment('protobuf.omit_message_names')
          ? ''
          : 'ClosureInfoPB',
      package: const $pb.PackageName(
          const $core.bool.fromEnvironment('protobuf.omit_message_names')
              ? ''
              : 'dart2js_info.proto'),
      createEmptyInstance: create)
    ..aOS(
        1,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'functionId')
    ..hasRequiredFields = false;

  ClosureInfoPB._() : super();
  factory ClosureInfoPB({
    $core.String? functionId,
  }) {
    final _result = create();
    if (functionId != null) {
      _result.functionId = functionId;
    }
    return _result;
  }
  factory ClosureInfoPB.fromBuffer($core.List<$core.int> i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromBuffer(i, r);
  factory ClosureInfoPB.fromJson($core.String i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromJson(i, r);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
      'Will be removed in next major version')
  ClosureInfoPB clone() => ClosureInfoPB()..mergeFromMessage(this);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
      'Will be removed in next major version')
  ClosureInfoPB copyWith(void Function(ClosureInfoPB) updates) =>
      super.copyWith((message) => updates(message as ClosureInfoPB))
          as ClosureInfoPB; // ignore: deprecated_member_use
  $pb.BuilderInfo get info_ => _i;
  @$core.pragma('dart2js:noInline')
  static ClosureInfoPB create() => ClosureInfoPB._();
  ClosureInfoPB createEmptyInstance() => create();
  static $pb.PbList<ClosureInfoPB> createRepeated() =>
      $pb.PbList<ClosureInfoPB>();
  @$core.pragma('dart2js:noInline')
  static ClosureInfoPB getDefault() => _defaultInstance ??=
      $pb.GeneratedMessage.$_defaultFor<ClosureInfoPB>(create);
  static ClosureInfoPB? _defaultInstance;

  @$pb.TagNumber(1)
  $core.String get functionId => $_getSZ(0);
  @$pb.TagNumber(1)
  set functionId($core.String v) {
    $_setString(0, v);
  }

  @$pb.TagNumber(1)
  $core.bool hasFunctionId() => $_has(0);
  @$pb.TagNumber(1)
  void clearFunctionId() => clearField(1);
}

class DeferredImportPB extends $pb.GeneratedMessage {
  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
      const $core.bool.fromEnvironment('protobuf.omit_message_names')
          ? ''
          : 'DeferredImportPB',
      package: const $pb.PackageName(
          const $core.bool.fromEnvironment('protobuf.omit_message_names')
              ? ''
              : 'dart2js_info.proto'),
      createEmptyInstance: create)
    ..aOS(
        1,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'prefix')
    ..pPS(
        2,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'files')
    ..hasRequiredFields = false;

  DeferredImportPB._() : super();
  factory DeferredImportPB({
    $core.String? prefix,
    $core.Iterable<$core.String>? files,
  }) {
    final _result = create();
    if (prefix != null) {
      _result.prefix = prefix;
    }
    if (files != null) {
      _result.files.addAll(files);
    }
    return _result;
  }
  factory DeferredImportPB.fromBuffer($core.List<$core.int> i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromBuffer(i, r);
  factory DeferredImportPB.fromJson($core.String i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromJson(i, r);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
      'Will be removed in next major version')
  DeferredImportPB clone() => DeferredImportPB()..mergeFromMessage(this);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
      'Will be removed in next major version')
  DeferredImportPB copyWith(void Function(DeferredImportPB) updates) =>
      super.copyWith((message) => updates(message as DeferredImportPB))
          as DeferredImportPB; // ignore: deprecated_member_use
  $pb.BuilderInfo get info_ => _i;
  @$core.pragma('dart2js:noInline')
  static DeferredImportPB create() => DeferredImportPB._();
  DeferredImportPB createEmptyInstance() => create();
  static $pb.PbList<DeferredImportPB> createRepeated() =>
      $pb.PbList<DeferredImportPB>();
  @$core.pragma('dart2js:noInline')
  static DeferredImportPB getDefault() => _defaultInstance ??=
      $pb.GeneratedMessage.$_defaultFor<DeferredImportPB>(create);
  static DeferredImportPB? _defaultInstance;

  @$pb.TagNumber(1)
  $core.String get prefix => $_getSZ(0);
  @$pb.TagNumber(1)
  set prefix($core.String v) {
    $_setString(0, v);
  }

  @$pb.TagNumber(1)
  $core.bool hasPrefix() => $_has(0);
  @$pb.TagNumber(1)
  void clearPrefix() => clearField(1);

  @$pb.TagNumber(2)
  $core.List<$core.String> get files => $_getList(1);
}

class LibraryDeferredImportsPB extends $pb.GeneratedMessage {
  static final $pb.BuilderInfo _i = $pb.BuilderInfo(
      const $core.bool.fromEnvironment('protobuf.omit_message_names')
          ? ''
          : 'LibraryDeferredImportsPB',
      package: const $pb.PackageName(
          const $core.bool.fromEnvironment('protobuf.omit_message_names')
              ? ''
              : 'dart2js_info.proto'),
      createEmptyInstance: create)
    ..aOS(
        1,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'libraryUri')
    ..aOS(
        2,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'libraryName')
    ..pc<DeferredImportPB>(
        3,
        const $core.bool.fromEnvironment('protobuf.omit_field_names')
            ? ''
            : 'imports',
        $pb.PbFieldType.PM,
        subBuilder: DeferredImportPB.create)
    ..hasRequiredFields = false;

  LibraryDeferredImportsPB._() : super();
  factory LibraryDeferredImportsPB({
    $core.String? libraryUri,
    $core.String? libraryName,
    $core.Iterable<DeferredImportPB>? imports,
  }) {
    final _result = create();
    if (libraryUri != null) {
      _result.libraryUri = libraryUri;
    }
    if (libraryName != null) {
      _result.libraryName = libraryName;
    }
    if (imports != null) {
      _result.imports.addAll(imports);
    }
    return _result;
  }
  factory LibraryDeferredImportsPB.fromBuffer($core.List<$core.int> i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromBuffer(i, r);
  factory LibraryDeferredImportsPB.fromJson($core.String i,
          [$pb.ExtensionRegistry r = $pb.ExtensionRegistry.EMPTY]) =>
      create()..mergeFromJson(i, r);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.deepCopy] instead. '
      'Will be removed in next major version')
  LibraryDeferredImportsPB clone() =>
      LibraryDeferredImportsPB()..mergeFromMessage(this);
  @$core.Deprecated('Using this can add significant overhead to your binary. '
      'Use [GeneratedMessageGenericExtensions.rebuild] instead. '
      'Will be removed in next major version')
  LibraryDeferredImportsPB copyWith(
          void Function(LibraryDeferredImportsPB) updates) =>
      super.copyWith((message) => updates(message as LibraryDeferredImportsPB))
          as LibraryDeferredImportsPB; // ignore: deprecated_member_use
  $pb.BuilderInfo get info_ => _i;
  @$core.pragma('dart2js:noInline')
  static LibraryDeferredImportsPB create() => LibraryDeferredImportsPB._();
  LibraryDeferredImportsPB createEmptyInstance() => create();
  static $pb.PbList<LibraryDeferredImportsPB> createRepeated() =>
      $pb.PbList<LibraryDeferredImportsPB>();
  @$core.pragma('dart2js:noInline')
  static LibraryDeferredImportsPB getDefault() => _defaultInstance ??=
      $pb.GeneratedMessage.$_defaultFor<LibraryDeferredImportsPB>(create);
  static LibraryDeferredImportsPB? _defaultInstance;

  @$pb.TagNumber(1)
  $core.String get libraryUri => $_getSZ(0);
  @$pb.TagNumber(1)
  set libraryUri($core.String v) {
    $_setString(0, v);
  }

  @$pb.TagNumber(1)
  $core.bool hasLibraryUri() => $_has(0);
  @$pb.TagNumber(1)
  void clearLibraryUri() => clearField(1);

  @$pb.TagNumber(2)
  $core.String get libraryName => $_getSZ(1);
  @$pb.TagNumber(2)
  set libraryName($core.String v) {
    $_setString(1, v);
  }

  @$pb.TagNumber(2)
  $core.bool hasLibraryName() => $_has(1);
  @$pb.TagNumber(2)
  void clearLibraryName() => clearField(2);

  @$pb.TagNumber(3)
  $core.List<DeferredImportPB> get imports => $_getList(2);
}
