// Copyright (c) 2013, 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.

part of '../protoc.dart';

/// Generates the Dart enum corresponding to a oneof declaration.
///
/// The enum is used to represent the state of a oneof when using the
/// corresponding which-method.
class OneofEnumGenerator {
  static void generate(
    IndentingWriter out,
    String classname,
    List<ProtobufField> fields,
  ) {
    out.addBlock('enum $classname {', '}\n', () {
      for (final field in fields) {
        final name = oneofEnumMemberName(field.memberNames!.fieldName);
        out.println('$name, ');
      }
      out.println('notSet');
    });
  }
}

class MessageGenerator extends ProtobufContainer {
  /// The name of the Dart class to generate.
  @override
  final String classname;

  /// The fully-qualified name of the message (without any leading '.').
  @override
  final String fullName;

  /// The part of the fully qualified name that comes after the package prefix.
  ///
  /// For nested messages this will include the names of the parents.
  ///
  /// For example:
  /// ```
  /// package foo;
  ///
  /// message Container {
  ///   message Nested {
  ///     int32 int32_value = 1;
  ///   }
  /// }
  /// ```
  /// The nested message will have a `fullName` of 'foo.Container.Nested', and a
  /// `messageName` of 'Container.Nested'.
  String get messageName =>
      fullName.substring(package.isEmpty ? 0 : package.length + 1);

  PbMixin? mixin;

  @override
  final ProtobufContainer? parent;

  final DescriptorProto _descriptor;
  final List<EnumGenerator> _enumGenerators = <EnumGenerator>[];
  final List<MessageGenerator> _messageGenerators = <MessageGenerator>[];
  final List<ExtensionGenerator> _extensionGenerators = <ExtensionGenerator>[];

  /// Stores the list of fields belonging to each oneof declaration identified
  /// by the index in the containing types's oneof_decl list.
  /// Only contains the 'real' oneofs.
  final List<List<ProtobufField>> _oneofFields;
  late List<OneofNames> _oneofNames;

  final List<int> _fieldPathSegment;

  @override
  late final List<int> fieldPath = [...parent!.fieldPath, ..._fieldPathSegment];

  // populated by resolve()
  late List<ProtobufField> _fieldList;
  bool _resolved = false;

  Set<String> _usedTopLevelNames;

  MessageGenerator._(
    DescriptorProto descriptor,
    this.parent,
    Map<String, PbMixin> declaredMixins,
    PbMixin? defaultMixin,
    this._usedTopLevelNames,
    int repeatedFieldIndex,
    int fieldIdTag,
  ) : _descriptor = descriptor,
      _fieldPathSegment = [fieldIdTag, repeatedFieldIndex],
      classname = messageOrEnumClassName(
        descriptor.name,
        _usedTopLevelNames,
        parent: parent?.classname ?? '',
      ),
      assert(parent != null),
      fullName =
          parent!.fullName == ''
              ? descriptor.name
              : '${parent.fullName}.${descriptor.name}',
      _oneofFields = List.generate(
        countRealOneofs(descriptor),
        (int index) => [],
      ) {
    mixin = _getMixin(declaredMixins, defaultMixin);
    for (var i = 0; i < _descriptor.enumType.length; i++) {
      final e = _descriptor.enumType[i];
      _enumGenerators.add(EnumGenerator.nested(e, this, _usedTopLevelNames, i));
    }

    for (var i = 0; i < _descriptor.nestedType.length; i++) {
      final n = _descriptor.nestedType[i];
      _messageGenerators.add(
        MessageGenerator.nested(
          n,
          this,
          declaredMixins,
          defaultMixin,
          _usedTopLevelNames,
          i,
        ),
      );
    }

    // Extensions within messages won't create top-level classes and don't need
    // to check against / be added to top-level reserved names.
    final usedExtensionNames = {...forbiddenExtensionNames};
    for (var i = 0; i < _descriptor.extension.length; i++) {
      final x = _descriptor.extension[i];
      _extensionGenerators.add(
        ExtensionGenerator.nested(x, this, usedExtensionNames, i),
      );
    }
  }

  /// Tag of `FileDescriptorProto.message_type`.
  static const _topLevelMessageTag = 4;

  /// Tag of `DescriptorProto.nested_type`.
  static const _nestedMessageTag = 3;

  /// Tag of `DescriptorProto.field`.
  static const _messageFieldTag = 2;

  MessageGenerator.topLevel(
    DescriptorProto descriptor,
    ProtobufContainer parent,
    Map<String, PbMixin> declaredMixins,
    PbMixin? defaultMixin,
    Set<String> usedNames,
    int repeatedFieldIndex,
  ) : this._(
        descriptor,
        parent,
        declaredMixins,
        defaultMixin,
        usedNames,
        repeatedFieldIndex,
        _topLevelMessageTag,
      );

  MessageGenerator.nested(
    DescriptorProto descriptor,
    ProtobufContainer parent,
    Map<String, PbMixin> declaredMixins,
    PbMixin? defaultMixin,
    Set<String> usedNames,
    int repeatedFieldIndex,
  ) : this._(
        descriptor,
        parent,
        declaredMixins,
        defaultMixin,
        usedNames,
        repeatedFieldIndex,
        _nestedMessageTag,
      );

  @override
  String get package => parent!.package;

  /// The generator of the .pb.dart file that will declare this type.
  @override
  FileGenerator get fileGen => parent!.fileGen!;

  /// Throws an exception if [resolve] hasn't been called yet.
  void checkResolved() {
    if (!_resolved) {
      throw StateError('message not resolved: $fullName');
    }
  }

  /// Returns a const expression that evaluates to the JSON for this message.
  ///
  /// [context] represents the .pb.dart file where the expression will be used.
  String getJsonConstant(FileGenerator context) {
    final name = '$classname\$json';
    if (context.protoFileUri == fileGen.protoFileUri) {
      return name;
    }
    return '${importPrefix(context: context)}.$name';
  }

  /// Adds all mixins used in this message and any submessages.
  void addMixinsTo(Set<PbMixin> output) {
    if (mixin != null) {
      output.addAll(mixin!.findMixinsToApply());
    }
    for (final m in _messageGenerators) {
      m.addMixinsTo(output);
    }
  }

  // Registers message and enum types that can be used elsewhere.
  void register(GenerationContext ctx) {
    ctx.registerFieldType(this);
    for (final m in _messageGenerators) {
      m.register(ctx);
    }
    for (final e in _enumGenerators) {
      e.register(ctx);
    }
  }

  // Creates fields and resolves extension targets.
  void resolve(GenerationContext ctx) {
    if (_resolved) throw StateError('message already resolved');
    _resolved = true;

    final reserved = mixin?.findReservedNames() ?? const <String>[];
    final members = messageMemberNames(
      _descriptor,
      classname,
      _usedTopLevelNames,
      reserved: reserved,
    );

    _fieldList = <ProtobufField>[];
    for (final names in members.fieldNames) {
      final field = ProtobufField.message(names, this, ctx);
      if (field.descriptor.hasOneofIndex() &&
          !field.descriptor.proto3Optional) {
        _oneofFields[field.descriptor.oneofIndex].add(field);
      }
      _fieldList.add(field);
    }
    _oneofNames = members.oneofNames;

    for (final m in _messageGenerators) {
      m.resolve(ctx);
    }
    for (final x in _extensionGenerators) {
      x.resolve(ctx);
    }
  }

  bool get needsFixnumImport {
    checkResolved();
    for (final field in _fieldList) {
      if (field.needsFixnumImport) return true;
    }
    for (final m in _messageGenerators) {
      if (m.needsFixnumImport) return true;
    }
    for (final x in _extensionGenerators) {
      if (x.needsFixnumImport) return true;
    }
    return false;
  }

  /// Adds dependencies of [generate] to [imports].
  ///
  /// For each .pb.dart file that the generated code needs to import,
  /// add its generator.
  void addImportsTo(
    Set<FileGenerator> imports,
    Set<FileGenerator> enumImports,
  ) {
    checkResolved();
    for (final field in _fieldList) {
      final typeGen = field.baseType.generator;
      if (typeGen is EnumGenerator) {
        enumImports.add(typeGen.fileGen!);
      } else if (typeGen != null) {
        imports.add(typeGen.fileGen!);
      }
    }
    for (final m in _messageGenerators) {
      m.addImportsTo(imports, enumImports);
    }
    for (final x in _extensionGenerators) {
      x.addImportsTo(imports, enumImports);
    }
  }

  // Returns the number of enums in this message and all nested messages.
  int get enumCount {
    var count = _enumGenerators.length;
    for (final m in _messageGenerators) {
      count += m.enumCount;
    }
    return count;
  }

  /// Adds dependencies of [generateConstants] to [imports].
  ///
  /// For each .pbjson.dart file that the generated code needs to import,
  /// add its generator.
  void addConstantImportsTo(Set<FileGenerator> imports) {
    checkResolved();
    for (final m in _messageGenerators) {
      m.addConstantImportsTo(imports);
    }
    for (final x in _extensionGenerators) {
      x.addConstantImportsTo(imports);
    }
  }

  void generate(IndentingWriter out) {
    checkResolved();

    for (final m in _messageGenerators) {
      // Don't output the generated map entry type. Instead, the `PbMap` type
      // from the protobuf library is used to hold the keys and values.
      if (m._descriptor.options.hasMapEntry()) continue;
      m.generate(out);
    }

    for (final oneof in _oneofNames) {
      OneofEnumGenerator.generate(
        out,
        oneof.oneofEnumName,
        _oneofFields[oneof.index],
      );
    }

    var mixinClause = '';
    if (mixin != null) {
      final mixinNames = mixin!.findMixinsToApply().map(
        (m) => '$mixinImportPrefix.${m.name}',
      );
      mixinClause = ' with ${mixinNames.join(", ")}';
    }

    final omitMessageNames = ConditionalConstDefinition('omit_message_names');
    out.addSuffix(
      omitMessageNames.constFieldName,
      omitMessageNames.constDefinition,
    );

    final conditionalPackageName =
        'const $protobufImportPrefix.PackageName'
        '(${omitMessageNames.createTernary(package)})';

    final packageClause =
        package == '' ? '' : ', package: $conditionalPackageName';
    final proto3JsonClause =
        (mixin?.hasProto3JsonHelpers ?? false)
            ? ', toProto3Json: $mixinImportPrefix.${mixin!.name}.toProto3JsonHelper, '
                'fromProto3Json: $mixinImportPrefix.${mixin!.name}.fromProto3JsonHelper'
            : '';

    final String extendedClass;
    if (_descriptor.options.messageSetWireFormat) {
      extendedClass = '\$_MessageSet';
    } else {
      extendedClass = 'GeneratedMessage';
    }

    final commentBlock = fileGen.commentBlock(fieldPath);
    if (commentBlock != null) {
      out.println(commentBlock);
    }
    if (_descriptor.options.deprecated) {
      out.println(
        '@$coreImportPrefix.Deprecated(\'This message is deprecated\')',
      );
    }
    out.addAnnotatedBlock(
      'class $classname extends $protobufImportPrefix.$extendedClass$mixinClause {',
      '}',
      [
        NamedLocation(
          name: classname,
          fieldPathSegment: fieldPath,
          start: 'class '.length,
        ),
      ],
      () {
        _generateFactory(out);

        out.println();

        out.printlnAnnotated('$classname._();', [
          NamedLocation(name: classname, fieldPathSegment: fieldPath, start: 0),
        ]);

        out.println();

        out.println(
          'factory $classname.fromBuffer($coreImportPrefix.List<$coreImportPrefix.int> data,'
          ' [$protobufImportPrefix.ExtensionRegistry registry = $protobufImportPrefix.ExtensionRegistry.EMPTY])'
          ' => create()..mergeFromBuffer(data, registry);',
        );
        out.println(
          'factory $classname.fromJson($coreImportPrefix.String json,'
          ' [$protobufImportPrefix.ExtensionRegistry registry = $protobufImportPrefix.ExtensionRegistry.EMPTY])'
          ' => create()..mergeFromJson(json, registry);',
        );

        out.println();
        for (final oneof in _oneofNames) {
          out.addBlock(
            'static const $coreImportPrefix.Map<$coreImportPrefix.int, ${oneof.oneofEnumName}> ${oneof.byTagMapName} = {',
            '};',
            () {
              for (final field in _oneofFields[oneof.index]) {
                final oneofMemberName = oneofEnumMemberName(
                  field.memberNames!.fieldName,
                );
                out.println(
                  '${field.number} : ${oneof.oneofEnumName}.$oneofMemberName,',
                );
              }
              out.println('0 : ${oneof.oneofEnumName}.notSet');
            },
          );
        }

        final omitMessageNames = ConditionalConstDefinition(
          'omit_message_names',
        );
        out.addSuffix(
          omitMessageNames.constFieldName,
          omitMessageNames.constDefinition,
        );

        out.addBlock(
          'static final $protobufImportPrefix.BuilderInfo _i = '
              '$protobufImportPrefix.BuilderInfo(${omitMessageNames.createTernary(messageName)}'
              '$packageClause'
              ', createEmptyInstance: create'
              '$proto3JsonClause)',
          ';',
          () {
            for (var oneof = 0; oneof < _oneofFields.length; oneof++) {
              final tags =
                  _oneofFields[oneof]
                      .map((ProtobufField f) => f.number)
                      .toList();
              out.println('..oo($oneof, $tags)');
            }

            for (final field in _fieldList) {
              field.generateBuilderInfoCall(out, package);
            }

            if (_descriptor.extensionRange.isNotEmpty) {
              out.println('..hasExtensions = true');
            }
            if (!_hasRequiredFields(this, {})) {
              out.println('..hasRequiredFields = false');
            }
          },
        );

        for (final x in _extensionGenerators) {
          x.generate(out);
        }

        out.println();
        out.println(
          '@$coreImportPrefix.Deprecated('
          "'See https://github.com/google/protobuf.dart/issues/998.')",
        );
        out.println(
          '$classname clone() => $classname()..mergeFromMessage(this);',
        );
        out.println(
          '@$coreImportPrefix.Deprecated('
          "'See https://github.com/google/protobuf.dart/issues/998.')",
        );
        out.println(
          '$classname copyWith(void Function($classname) updates) =>'
          ' super.copyWith((message) => updates(message as $classname))'
          ' as $classname;',
        );

        out.println();
        out.println('@$coreImportPrefix.override');
        out.println('$protobufImportPrefix.BuilderInfo get info_ => _i;');

        // Factory functions which can be used as default value closures.
        out.println();
        out.println("@$coreImportPrefix.pragma('dart2js:noInline')");
        out.println('static $classname create() => $classname._();');
        out.println('@$coreImportPrefix.override');
        out.println('$classname createEmptyInstance() => create();');

        out.println(
          'static $protobufImportPrefix.PbList<$classname> createRepeated() =>'
          ' $protobufImportPrefix.PbList<$classname>();',
        );
        out.println("@$coreImportPrefix.pragma('dart2js:noInline')");
        out.println(
          'static $classname getDefault() =>'
          ' _defaultInstance ??='
          ' $protobufImportPrefix.GeneratedMessage.\$_defaultFor<$classname>'
          '(create);',
        );
        out.println('static $classname? _defaultInstance;');

        generateFieldsAccessorsMutators(out);
        mixin?.injectHelpers(out);
      },
    );
    out.println();
  }

  void _generateFactory(IndentingWriter out) {
    if (!fileGen.options.disableConstructorArgs && _fieldList.isNotEmpty) {
      out.println('factory $classname({');
      for (final field in _fieldList) {
        _emitDeprecatedIf(field.isDeprecated, out);
        if (field.isRepeated && !field.isMapField) {
          out.println(
            '  ${field.baseType.getRepeatedDartTypeIterable(fileGen)}? ${field.memberNames!.fieldName},',
          );
        } else if (field.isMapField) {
          final keyType = field.getDartMapKeyType();
          final valueType = field.getDartMapValueType();
          out.println(
            '  $coreImportPrefix.Iterable<$coreImportPrefix.MapEntry<$keyType, $valueType>>? '
            '${field.memberNames!.fieldName},',
          );
        } else {
          out.println(
            '  ${field.getDartType()}? ${field.memberNames!.fieldName},',
          );
        }
      }
      out.print('}) ');

      final names = _fieldList.map((f) => f.memberNames!.fieldName).toSet();
      var result = 'result';
      if (names.contains(result)) {
        result += r'$';
      }
      out.addBlock('{', '}', () {
        out.println('final $result = create();');
        for (final field in _fieldList) {
          out.print('if (${field.memberNames!.fieldName} != null) ');
          if (field.isRepeated && !field.isMapField) {
            out.println(
              '$result.${field.memberNames!.fieldName}.addAll(${field.memberNames!.fieldName});',
            );
          } else if (field.isMapField) {
            out.println(
              '$result.${field.memberNames!.fieldName}.addEntries(${field.memberNames!.fieldName});',
            );
          } else {
            out.println(
              '$result.${field.memberNames!.fieldName} = ${field.memberNames!.fieldName};',
            );
          }
        }
        out.println('return $result;');
      });
    } else {
      out.println('factory $classname() => create();');
    }
  }

  // Returns true if the message type has any required fields.  If it doesn't,
  // we can optimize out calls to its isInitialized()/_findInvalidFields()
  // methods.
  //
  // already_seen is used to avoid checking the same type multiple times
  // (and also to protect against unbounded recursion).
  bool _hasRequiredFields(MessageGenerator type, Set<String> alreadySeen) {
    checkResolved();

    if (alreadySeen.contains(type.fullName)) {
      // The type is already in cache.  This means that either:
      // a. The type has no required fields.
      // b. We are in the midst of checking if the type has required fields,
      //    somewhere up the stack.  In this case, we know that if the type
      //    has any required fields, they'll be found when we return to it,
      //    and the whole call to HasRequiredFields() will return true.
      //    Therefore, we don't have to check if this type has required fields
      //    here.
      return false;
    }
    alreadySeen.add(type.fullName);
    // If the type has extensions, an extension with message type could contain
    // required fields, so we have to be conservative and assume such an
    // extension exists.
    if (type._descriptor.extensionRange.isNotEmpty) {
      return true;
    }

    for (final field in type._fieldList) {
      if (field.isRequired) {
        return true;
      }
      if (field.baseType.isMessage) {
        final child = field.baseType.generator as MessageGenerator;
        if (_hasRequiredFields(child, alreadySeen)) {
          return true;
        }
      }
    }
    return false;
  }

  void generateFieldsAccessorsMutators(IndentingWriter out) {
    for (final oneof in _oneofNames) {
      generateOneofAccessors(out, oneof);
    }

    for (final field in _fieldList) {
      out.println();
      final memberFieldPath = List<int>.from(fieldPath)
        ..addAll([_messageFieldTag, field.sourcePosition!]);
      generateFieldAccessorsMutators(field, out, memberFieldPath);
    }
  }

  void generateOneofAccessors(IndentingWriter out, OneofNames oneof) {
    out.println();
    out.println(
      '${oneof.oneofEnumName} ${oneof.whichOneofMethodName}() '
      '=> ${oneof.byTagMapName}[\$_whichOneof(${oneof.index})]!;',
    );
    out.println(
      'void ${oneof.clearMethodName}() '
      '=> \$_clearField(\$_whichOneof(${oneof.index}));',
    );
  }

  void generateFieldAccessorsMutators(
    ProtobufField field,
    IndentingWriter out,
    List<int> memberFieldPath,
  ) {
    final fieldTypeString = field.getDartType();
    final defaultExpr = field.getDefaultExpr();
    final names = field.memberNames;

    final commentBlock = fileGen.commentBlock(memberFieldPath);
    if (commentBlock != null) {
      out.println(commentBlock);
    }

    _emitDeprecatedIf(field.isDeprecated, out);
    _emitOverrideIf(field.overridesGetter, out);
    _emitIndexAnnotation(field.number, out);
    final getterExpr = _getterExpression(
      fieldTypeString,
      field.index!,
      defaultExpr,
      field.isRepeated,
      field.isMapField,
    );

    out.printlnAnnotated(
      '$fieldTypeString get ${names!.fieldName} => $getterExpr;',
      [
        NamedLocation(
          name: names.fieldName,
          fieldPathSegment: memberFieldPath,
          start: '$fieldTypeString get '.length,
        ),
      ],
    );

    if (field.isRepeated) {
      if (field.overridesSetter) {
        throw 'Field ${field.fullName} cannot override a setter for '
            '${names.fieldName} because it is repeated.';
      }
      if (field.overridesHasMethod) {
        throw 'Field ${field.fullName} cannot override '
            '${names.hasMethodName}() because it is repeated.';
      }
      if (field.overridesClearMethod) {
        throw 'Field ${field.fullName} cannot override '
            '${names.clearMethodName}() because it is repeated.';
      }
    } else {
      final fastSetter = field.baseType.setter;
      _emitDeprecatedIf(field.isDeprecated, out);
      _emitOverrideIf(field.overridesSetter, out);
      _emitIndexAnnotation(field.number, out);
      if (fastSetter != null) {
        out.printlnAnnotated(
          'set ${names.fieldName}($fieldTypeString value) => '
          '$fastSetter(${field.index}, value);',
          [
            NamedLocation(
              name: names.fieldName,
              fieldPathSegment: memberFieldPath,
              start: 'set '.length,
            ),
          ],
        );
      } else {
        out.printlnAnnotated(
          'set ${names.fieldName}($fieldTypeString value) => '
          '\$_setField(${field.number}, value);',
          [
            NamedLocation(
              name: names.fieldName,
              fieldPathSegment: memberFieldPath,
              start: 'set '.length,
            ),
          ],
        );
      }
      if (field.hasPresence) {
        _emitDeprecatedIf(field.isDeprecated, out);
        _emitOverrideIf(field.overridesHasMethod, out);
        _emitIndexAnnotation(field.number, out);
        out.printlnAnnotated(
          '$coreImportPrefix.bool ${names.hasMethodName}() =>'
          ' \$_has(${field.index});',
          [
            NamedLocation(
              name: names.hasMethodName!,
              fieldPathSegment: memberFieldPath,
              start: '$coreImportPrefix.bool '.length,
            ),
          ],
        );
      }
      _emitDeprecatedIf(field.isDeprecated, out);
      _emitOverrideIf(field.overridesClearMethod, out);
      _emitIndexAnnotation(field.number, out);
      out.printlnAnnotated(
        'void ${names.clearMethodName}() =>'
        ' \$_clearField(${field.number});',
        [
          NamedLocation(
            name: names.clearMethodName!,
            fieldPathSegment: memberFieldPath,
            start: 'void '.length,
          ),
        ],
      );
      if (field.baseType.isMessage) {
        _emitDeprecatedIf(field.isDeprecated, out);
        _emitIndexAnnotation(field.number, out);
        out.printlnAnnotated(
          '$fieldTypeString ${names.ensureMethodName}() => '
          '\$_ensure(${field.index});',
          <NamedLocation>[
            NamedLocation(
              name: names.ensureMethodName!,
              fieldPathSegment: memberFieldPath,
              start: '$fieldTypeString '.length,
            ),
          ],
        );
      }
    }
  }

  String _getterExpression(
    String fieldType,
    int index,
    String defaultExpr,
    bool isRepeated,
    bool isMapField,
  ) {
    if (isMapField) {
      return '\$_getMap($index)';
    }
    if (fieldType == '$coreImportPrefix.String') {
      if (defaultExpr == '""' || defaultExpr == "''") {
        return '\$_getSZ($index)';
      }
      return '\$_getS($index, $defaultExpr)';
    }
    if (fieldType == '$coreImportPrefix.bool') {
      if (defaultExpr == 'false') {
        return '\$_getBF($index)';
      }
      return '\$_getB($index, $defaultExpr)';
    }
    if (fieldType == '$coreImportPrefix.int') {
      if (defaultExpr == '0') {
        return '\$_getIZ($index)';
      }
      return '\$_getI($index, $defaultExpr)';
    }
    if (fieldType == '$fixnumImportPrefix.Int64' && defaultExpr == 'null') {
      return '\$_getI64($index)';
    }
    if (defaultExpr == 'null') {
      return isRepeated ? '\$_getList($index)' : '\$_getN($index)';
    }
    return '\$_get($index, $defaultExpr)';
  }

  void _emitDeprecatedIf(bool condition, IndentingWriter out) {
    if (condition) {
      out.println(
        '@$coreImportPrefix.Deprecated(\'This field is deprecated.\')',
      );
    }
  }

  void _emitOverrideIf(bool condition, IndentingWriter out) {
    if (condition) {
      out.println('@$coreImportPrefix.override');
    }
  }

  void _emitIndexAnnotation(int index, IndentingWriter out) {
    out.println('@$protobufImportPrefix.TagNumber($index)');
  }

  void generateEnums(IndentingWriter out) {
    for (final e in _enumGenerators) {
      e.generate(out);
    }

    for (final m in _messageGenerators) {
      m.generateEnums(out);
    }
  }

  /// Writes a Dart constant containing the JSON for the ProtoDescriptor.
  /// Also writes a separate constant for each nested message,
  /// to avoid duplication.
  void generateConstants(IndentingWriter out) {
    const nestedTypeTag = 3;
    const enumTypeTag = 4;
    assert(_descriptor.info_.fieldInfo[nestedTypeTag]!.name == 'nestedType');
    assert(_descriptor.info_.fieldInfo[enumTypeTag]!.name == 'enumType');

    final name = getJsonConstant(fileGen);
    final json = _descriptor.writeToJsonMap();
    final nestedTypeNames =
        _messageGenerators.map((m) => m.getJsonConstant(fileGen)).toList();
    final nestedEnumNames =
        _enumGenerators.map((e) => e.getJsonConstant(fileGen)).toList();

    out.println(
      '@$coreImportPrefix.Deprecated'
      '(\'Use ${toplevelParent!.binaryDescriptorName} instead\')',
    );
    out.addBlock('const $name = {', '};', () {
      for (final key in json.keys) {
        out.print("'$key': ");
        if (key == '$nestedTypeTag') {
          // refer to message constants by name instead of repeating each value
          out.println("[${nestedTypeNames.join(", ")}],");
          continue;
        } else if (key == '$enumTypeTag') {
          // refer to enum constants by name
          out.println("[${nestedEnumNames.join(", ")}],");
          continue;
        }
        writeJsonConst(out, json[key]);
        out.println(',');
      }
    });
    out.println();

    for (final m in _messageGenerators) {
      m.generateConstants(out);
    }

    for (final e in _enumGenerators) {
      e.generateConstants(out);
    }
  }

  /// Returns the mixin for this message, or null if none.
  ///
  /// First searches [_wellKnownMixins], then [declaredMixins],
  /// then internal mixins declared by [findMixin].
  PbMixin? _getMixin(
    Map<String, PbMixin> declaredMixins,
    PbMixin? defaultMixin,
  ) {
    final wellKnownMixin = wellKnownMixinForFullName(fullName);
    if (wellKnownMixin != null) return wellKnownMixin;
    if (!_descriptor.hasOptions() ||
        !_descriptor.options.hasExtension(Dart_options.mixin)) {
      return defaultMixin;
    }

    final name = _descriptor.options.getExtension(Dart_options.mixin) as String;
    if (name.isEmpty) return null; // don't use any mixins (override default)
    final mixin = declaredMixins[name] ?? findMixin(name);
    if (mixin == null) {
      throw '${_descriptor.name} in ${parent!.fileGen!.descriptor.name}: mixin "$name" not found';
    }
    return mixin;
  }
}
