// Copyright (c) 2011, 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 protobuf;

/// Per-message type setup.
class BuilderInfo {
  /// The fully qualified name of this message.
  final String qualifiedMessageName;
  final List<FieldInfo> byIndex = <FieldInfo>[];
  final Map<int, FieldInfo> fieldInfo = <int, FieldInfo>{};
  final Map<String, FieldInfo> byTagAsString = <String, FieldInfo>{};
  final Map<String, FieldInfo> byName = <String, FieldInfo>{};
  // Maps a tag number to the corresponding oneof index (if any).
  final Map<int, int> oneofs = <int, int>{};
  bool hasExtensions = false;
  bool hasRequiredFields = true;
  List<FieldInfo> _sortedByTag;

  // For well-known types.
  final Object Function(GeneratedMessage message, TypeRegistry typeRegistry)
      toProto3Json;
  final Function(GeneratedMessage targetMessage, Object json,
      TypeRegistry typeRegistry, JsonParsingContext context) fromProto3Json;
  final CreateBuilderFunc createEmptyInstance;

  BuilderInfo(String messageName,
      {PackageName package = const PackageName(''),
      this.createEmptyInstance,
      this.toProto3Json,
      this.fromProto3Json})
      : qualifiedMessageName = '${package.prefix}$messageName';

  void add<T>(
      int tagNumber,
      String name,
      int fieldType,
      dynamic defaultOrMaker,
      CreateBuilderFunc subBuilder,
      ValueOfFunc valueOf,
      List<ProtobufEnum> enumValues,
      {String protoName}) {
    var index = byIndex.length;
    final fieldInfo = (tagNumber == 0)
        ? FieldInfo.dummy(index)
        : FieldInfo<T>(name, tagNumber, index, fieldType,
            defaultOrMaker: defaultOrMaker,
            subBuilder: subBuilder,
            valueOf: valueOf,
            enumValues: enumValues,
            protoName: protoName);
    _addField(fieldInfo);
  }

  void addMapField<K, V>(
      int tagNumber,
      String name,
      int keyFieldType,
      int valueFieldType,
      BuilderInfo mapEntryBuilderInfo,
      CreateBuilderFunc valueCreator,
      {String protoName}) {
    var index = byIndex.length;
    _addField(MapFieldInfo<K, V>(name, tagNumber, index, PbFieldType.M,
        keyFieldType, valueFieldType, mapEntryBuilderInfo, valueCreator,
        protoName: protoName));
  }

  void addRepeated<T>(
      int tagNumber,
      String name,
      int fieldType,
      CheckFunc<T> check,
      CreateBuilderFunc subBuilder,
      ValueOfFunc valueOf,
      List<ProtobufEnum> enumValues,
      {String protoName}) {
    var index = byIndex.length;
    _addField(FieldInfo<T>.repeated(
        name, tagNumber, index, fieldType, check, subBuilder,
        valueOf: valueOf, enumValues: enumValues, protoName: protoName));
  }

  void _addField(FieldInfo fi) {
    byIndex.add(fi);
    assert(byIndex[fi.index] == fi);
    // Fields with tag number 0 are considered dummy fields added to avoid
    // index calculations add up. They should not be reflected in the following
    // maps.
    if (!fi._isDummy) {
      fieldInfo[fi.tagNumber] = fi;
      byTagAsString['${fi.tagNumber}'] = fi;
      byName[fi.name] = fi;
    }
  }

  void a<T>(int tagNumber, String name, int fieldType,
      {dynamic defaultOrMaker,
      CreateBuilderFunc subBuilder,
      ValueOfFunc valueOf,
      List<ProtobufEnum> enumValues,
      String protoName}) {
    add<T>(tagNumber, name, fieldType, defaultOrMaker, subBuilder, valueOf,
        enumValues,
        protoName: protoName);
  }

  /// Adds PbFieldType.OS String with no default value to reduce generated
  /// code size.
  void aOS(int tagNumber, String name, {String protoName}) {
    add<String>(tagNumber, name, PbFieldType.OS, null, null, null, null,
        protoName: protoName);
  }

  /// Adds PbFieldType.PS String with no default value.
  void pPS(int tagNumber, String name, {String protoName}) {
    addRepeated<String>(tagNumber, name, PbFieldType.PS,
        getCheckFunction(PbFieldType.PS), null, null, null,
        protoName: protoName);
  }

  /// Adds PbFieldType.QS String with no default value.
  void aQS(int tagNumber, String name, {String protoName}) {
    add<String>(tagNumber, name, PbFieldType.QS, null, null, null, null,
        protoName: protoName);
  }

  /// Adds Int64 field with Int64.ZERO default.
  void aInt64(int tagNumber, String name, {String protoName}) {
    add<Int64>(tagNumber, name, PbFieldType.O6, Int64.ZERO, null, null, null,
        protoName: protoName);
  }

  /// Adds a boolean with no default value.
  void aOB(int tagNumber, String name, {String protoName}) {
    add<bool>(tagNumber, name, PbFieldType.OB, null, null, null, null,
        protoName: protoName);
  }

  // Enum.
  void e<T>(int tagNumber, String name, int fieldType,
      {dynamic defaultOrMaker,
      ValueOfFunc valueOf,
      List<ProtobufEnum> enumValues,
      String protoName}) {
    add<T>(
        tagNumber, name, fieldType, defaultOrMaker, null, valueOf, enumValues,
        protoName: protoName);
  }

  // Repeated, not a message, group, or enum.
  void p<T>(int tagNumber, String name, int fieldType, {String protoName}) {
    assert(!_isGroupOrMessage(fieldType) && !_isEnum(fieldType));
    addRepeated<T>(tagNumber, name, fieldType, getCheckFunction(fieldType),
        null, null, null,
        protoName: protoName);
  }

  // Repeated message, group, or enum.
  void pc<T>(int tagNumber, String name, int fieldType,
      {CreateBuilderFunc subBuilder,
      ValueOfFunc valueOf,
      List<ProtobufEnum> enumValues,
      String protoName}) {
    assert(_isGroupOrMessage(fieldType) || _isEnum(fieldType));
    addRepeated<T>(tagNumber, name, fieldType, _checkNotNull, subBuilder,
        valueOf, enumValues,
        protoName: protoName);
  }

  void aOM<T extends GeneratedMessage>(int tagNumber, String name,
      {T Function() subBuilder, String protoName}) {
    add<T>(
        tagNumber,
        name,
        PbFieldType.OM,
        GeneratedMessage._defaultMakerFor<T>(subBuilder),
        subBuilder,
        null,
        null,
        protoName: protoName);
  }

  void aQM<T extends GeneratedMessage>(int tagNumber, String name,
      {T Function() subBuilder, String protoName}) {
    add<T>(
        tagNumber,
        name,
        PbFieldType.QM,
        GeneratedMessage._defaultMakerFor<T>(subBuilder),
        subBuilder,
        null,
        null,
        protoName: protoName);
  }

  // oneof declarations.
  void oo(int oneofIndex, List<int> tags) {
    tags.forEach((int tag) => oneofs[tag] = oneofIndex);
  }

  // Map field.
  void m<K, V>(int tagNumber, String name,
      {String entryClassName,
      int keyFieldType,
      int valueFieldType,
      CreateBuilderFunc valueCreator,
      ValueOfFunc valueOf,
      List<ProtobufEnum> enumValues,
      PackageName packageName = const PackageName(''),
      String protoName}) {
    var mapEntryBuilderInfo = BuilderInfo(entryClassName, package: packageName)
      ..add(PbMap._keyFieldNumber, 'key', keyFieldType, null, null, null, null)
      ..add(PbMap._valueFieldNumber, 'value', valueFieldType, null,
          valueCreator, valueOf, enumValues);

    addMapField<K, V>(tagNumber, name, keyFieldType, valueFieldType,
        mapEntryBuilderInfo, valueCreator,
        protoName: protoName);
  }

  bool containsTagNumber(int tagNumber) => fieldInfo.containsKey(tagNumber);

  dynamic defaultValue(int tagNumber) {
    var func = makeDefault(tagNumber);
    return func == null ? null : func();
  }

  // Returns the field name for a given tag number, for debugging purposes.
  String fieldName(int tagNumber) {
    var i = fieldInfo[tagNumber];
    return i != null ? i.name : null;
  }

  int fieldType(int tagNumber) {
    var i = fieldInfo[tagNumber];
    return i != null ? i.type : null;
  }

  MakeDefaultFunc makeDefault(int tagNumber) {
    var i = fieldInfo[tagNumber];
    return i != null ? i.makeDefault : null;
  }

  CreateBuilderFunc subBuilder(int tagNumber) {
    var i = fieldInfo[tagNumber];
    return i != null ? i.subBuilder : null;
  }

  int tagNumber(String fieldName) {
    var i = byName[fieldName];
    return i != null ? i.tagNumber : null;
  }

  ValueOfFunc valueOfFunc(int tagNumber) {
    var i = fieldInfo[tagNumber];
    return i != null ? i.valueOf : null;
  }

  /// The FieldInfo for each field in tag number order.
  List<FieldInfo> get sortedByTag => _sortedByTag ??= _computeSortedByTag();

  /// The message name. Also see [qualifiedMessageName].
  String get messageName {
    final lastDot = qualifiedMessageName.lastIndexOf('.');
    return lastDot == -1
        ? qualifiedMessageName
        : qualifiedMessageName.substring(lastDot + 1);
  }

  List<FieldInfo> _computeSortedByTag() {
    // TODO(skybrian): perhaps the code generator should insert the FieldInfos
    // in tag number order, to avoid sorting them?
    return List<FieldInfo>.from(fieldInfo.values, growable: false)
      ..sort((FieldInfo a, FieldInfo b) => a.tagNumber.compareTo(b.tagNumber));
  }

  GeneratedMessage _makeEmptyMessage(
      int tagNumber, ExtensionRegistry extensionRegistry) {
    var subBuilderFunc = subBuilder(tagNumber);
    if (subBuilderFunc == null && extensionRegistry != null) {
      subBuilderFunc = extensionRegistry
          .getExtension(qualifiedMessageName, tagNumber)
          .subBuilder;
    }
    return subBuilderFunc();
  }

  ProtobufEnum _decodeEnum(
      int tagNumber, ExtensionRegistry registry, int rawValue) {
    var f = valueOfFunc(tagNumber);
    if (f == null && registry != null) {
      f = registry.getExtension(qualifiedMessageName, tagNumber).valueOf;
    }
    return f(rawValue);
  }
}

/// Annotation for marking accessors that belong together.
class TagNumber {
  final int tagNumber;

  /// Annotation for marking accessors that belong together.
  ///
  /// Allows tooling to associate related accessors.
  /// [tagNumber] is the protobuf tagnumber associated with the annotated
  /// accessor.
  const TagNumber(this.tagNumber);
}
