// 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.

// @dart=2.11

part of '../protoc.dart';

class ProtobufField {
  static final RegExp _hexLiteralRegex =
      RegExp(r'^0x[0-9a-f]+$', multiLine: false, caseSensitive: false);
  static final RegExp _integerLiteralRegex = RegExp(r'^[+-]?[0-9]+$');
  static final RegExp _decimalLiteralRegexA = RegExp(
      r'^[+-]?([0-9]*)\.[0-9]+(e[+-]?[0-9]+)?$',
      multiLine: false,
      caseSensitive: false);
  static final RegExp _decimalLiteralRegexB = RegExp(
      r'^[+-]?[0-9]+e[+-]?[0-9]+$',
      multiLine: false,
      caseSensitive: false);

  final FieldDescriptorProto descriptor;

  /// Dart names within a GeneratedMessage or `null` for an extension.
  final FieldNames memberNames;

  final String fullName;
  final BaseType baseType;

  ProtobufField.message(
      FieldNames names, ProtobufContainer parent, GenerationContext ctx)
      : this._(names.descriptor, names, parent, ctx);

  ProtobufField.extension(FieldDescriptorProto descriptor,
      ProtobufContainer parent, GenerationContext ctx)
      : this._(descriptor, null, parent, ctx);

  ProtobufField._(this.descriptor, FieldNames dartNames,
      ProtobufContainer parent, GenerationContext ctx)
      : memberNames = dartNames,
        fullName = '${parent.fullName}.${descriptor.name}',
        baseType = BaseType(descriptor, ctx);

  /// The index of this field in MessageGenerator.fieldList.
  ///
  /// `null` for an extension.
  int get index => memberNames?.index;

  String get quotedProtoName =>
      (_unCamelCase(descriptor.jsonName) == descriptor.name)
          ? null
          : "'${descriptor.name}'";

  /// The position of this field as it appeared in the original DescriptorProto.
  int get sourcePosition => memberNames.sourcePosition;

  /// True if the field is to be encoded with [deprecated = true] encoding.
  bool get isDeprecated => descriptor.options?.deprecated;

  bool get isRequired =>
      descriptor.label == FieldDescriptorProto_Label.LABEL_REQUIRED;

  bool get isRepeated =>
      descriptor.label == FieldDescriptorProto_Label.LABEL_REPEATED;

  /// True if the field is to be encoded with [packed=true] encoding.
  bool get isPacked =>
      isRepeated && descriptor.options != null && descriptor.options.packed;

  /// Whether the field has the `overrideGetter` annotation set to true.
  bool get overridesGetter => _hasBooleanOption(Dart_options.overrideGetter);

  /// Whether the field has the `overrideSetter` annotation set to true.
  bool get overridesSetter => _hasBooleanOption(Dart_options.overrideSetter);

  /// Whether the field has the `overrideHasMethod` annotation set to true.
  bool get overridesHasMethod =>
      _hasBooleanOption(Dart_options.overrideHasMethod);

  /// Whether the field has the `overrideClearMethod` annotation set to true.
  bool get overridesClearMethod =>
      _hasBooleanOption(Dart_options.overrideClearMethod);

  /// True if this field uses the Int64 from the fixnum package.
  bool get needsFixnumImport =>
      baseType.unprefixed == '$_fixnumImportPrefix.Int64';

  /// True if this field is a map field definition:
  /// `map<key_type, value_type> map_field = N`.
  bool get isMapField {
    if (!isRepeated || !baseType.isMessage) return false;
    final generator = baseType.generator as MessageGenerator;
    return generator._descriptor.options.hasMapEntry();
  }

  // `true` if this field should have a `hazzer` generated.
  bool get hasPresence {
    if (isRepeated) return false;
    return true;
    // TODO(sigurdm): to provide the correct semantics for non-optional proto3
    // fields would need something like the following:
    // return baseType.isMessage ||
    //   descriptor.proto3Optional ||
    //   parent.fileGen.descriptor.syntax == "proto2";
    //
    // This change would break any accidental uses of the proto3 hazzers, and
    // would require some clean-up.
    //
    // We could consider keeping hazzers for proto3-oneof fields. There they
    // seem useful and not breaking proto3 semantics, and dart protobuf uses it
    // for example in package:protobuf/src/protobuf/mixins/well_known.dart.
  }

  /// Returns the expression to use for the Dart type.
  ///
  /// This will be a List for repeated types.
  /// [fileGen] represents the .proto file where we are generating code.
  String getDartType(FileGenerator fileGen) {
    if (isMapField) {
      final d = baseType.generator as MessageGenerator;
      var keyType = d._fieldList[0].baseType.getDartType(fileGen);
      var valueType = d._fieldList[1].baseType.getDartType(fileGen);
      return '$coreImportPrefix.Map<$keyType, $valueType>';
    }
    if (isRepeated) return baseType.getRepeatedDartType(fileGen);
    return baseType.getDartType(fileGen);
  }

  /// Returns the tag number of the underlying proto field.
  int get number => descriptor.number;

  /// Returns the constant in PbFieldType corresponding to this type.
  String get typeConstant {
    var prefix = 'O';
    if (isRequired) {
      prefix = 'Q';
    } else if (isPacked) {
      prefix = 'K';
    } else if (isRepeated) {
      prefix = 'P';
    }
    return '$protobufImportPrefix.PbFieldType.' +
        prefix +
        baseType.typeConstantSuffix;
  }

  static String _formatArguments(
      List<String> positionals, Map<String, String> named) {
    final args = positionals.toList();
    while (args.last == null) {
      args.removeLast();
    }
    for (var i = 0; i < args.length; i++) {
      if (args[i] == null) {
        args[i] = 'null';
      }
    }
    named.forEach((key, value) {
      if (value != null) {
        args.add('$key: $value');
      }
    });
    return args.join(', ');
  }

  /// Returns Dart code adding this field to a BuilderInfo object.
  /// The call will start with ".." and a method name.
  /// [fileGen] represents the .proto file where the code will be evaluated.
  String generateBuilderInfoCall(FileGenerator fileGen, String package) {
    assert(descriptor.hasJsonName());
    var quotedName = configurationDependent(
      'protobuf.omit_field_names',
      quoted(descriptor.jsonName),
    );

    var type = baseType.getDartType(fileGen);

    String invocation;

    var args = <String>[];
    var named = <String, String>{'protoName': quotedProtoName};
    args.add('$number');
    args.add(quotedName);

    if (isMapField) {
      final generator = baseType.generator as MessageGenerator;
      var key = generator._fieldList[0];
      var value = generator._fieldList[1];
      var keyType = key.baseType.getDartType(fileGen);
      var valueType = value.baseType.getDartType(fileGen);

      invocation = 'm<$keyType, $valueType>';

      named['entryClassName'] = "'${generator.messageName}'";
      named['keyFieldType'] = key.typeConstant;
      named['valueFieldType'] = value.typeConstant;
      if (value.baseType.isMessage || value.baseType.isGroup) {
        named['valueCreator'] = '$valueType.create';
      }
      if (value.baseType.isEnum) {
        named['valueOf'] = '$valueType.valueOf';
        named['enumValues'] = '$valueType.values';
        named['defaultEnumValue'] = value.generateDefaultFunction(fileGen);
      }
      if (package != '') {
        named['packageName'] =
            'const $protobufImportPrefix.PackageName(\'$package\')';
      }
    } else if (isRepeated) {
      if (typeConstant == '$protobufImportPrefix.PbFieldType.PS') {
        invocation = 'pPS';
      } else {
        args.add(typeConstant);
        if (baseType.isMessage || baseType.isGroup || baseType.isEnum) {
          invocation = 'pc<$type>';
        } else {
          invocation = 'p<$type>';
        }

        if (baseType.isMessage || baseType.isGroup) {
          named['subBuilder'] = '$type.create';
        } else if (baseType.isEnum) {
          named['valueOf'] = '$type.valueOf';
          named['enumValues'] = '$type.values';
          named['defaultEnumValue'] = generateDefaultFunction(fileGen);
        }
      }
    } else {
      // Singular field.
      var makeDefault = generateDefaultFunction(fileGen);

      if (baseType.isEnum) {
        args.add(typeConstant);
        named['defaultOrMaker'] = makeDefault;
        named['valueOf'] = '$type.valueOf';
        named['enumValues'] = '$type.values';
        invocation = 'e<$type>';
      } else if (makeDefault == null) {
        switch (type) {
          case '$coreImportPrefix.String':
            if (typeConstant == '$protobufImportPrefix.PbFieldType.OS') {
              invocation = 'aOS';
            } else if (typeConstant == '$protobufImportPrefix.PbFieldType.QS') {
              invocation = 'aQS';
            } else {
              invocation = 'a<$type>';
              args.add(typeConstant);
            }
            break;
          case '$coreImportPrefix.bool':
            if (typeConstant == '$protobufImportPrefix.PbFieldType.OB') {
              invocation = 'aOB';
            } else {
              invocation = 'a<$type>';
              args.add(typeConstant);
            }
            break;
          default:
            invocation = 'a<$type>';
            args.add(typeConstant);
            break;
        }
      } else {
        if (makeDefault == '$_fixnumImportPrefix.Int64.ZERO' &&
            type == '$_fixnumImportPrefix.Int64' &&
            typeConstant == '$protobufImportPrefix.PbFieldType.O6') {
          invocation = 'aInt64';
        } else {
          if (baseType.isMessage || baseType.isGroup) {
            named['subBuilder'] = '$type.create';
          }
          if (baseType.isMessage) {
            invocation = isRequired ? 'aQM<$type>' : 'aOM<$type>';
          } else {
            invocation = 'a<$type>';
            named['defaultOrMaker'] = makeDefault;
            args.add(typeConstant);
          }
        }
      }
    }
    assert(invocation != null);
    return '..$invocation(${_formatArguments(args, named)})';
  }

  /// Returns a Dart expression that evaluates to this field's default value.
  ///
  /// Returns "null" if unavailable, in which case FieldSet._getDefault()
  /// should be called instead.
  String getDefaultExpr() {
    if (isRepeated) return 'null';
    switch (descriptor.type) {
      case FieldDescriptorProto_Type.TYPE_BOOL:
        return _getDefaultAsBoolExpr('false');
      case FieldDescriptorProto_Type.TYPE_INT32:
      case FieldDescriptorProto_Type.TYPE_UINT32:
      case FieldDescriptorProto_Type.TYPE_SINT32:
      case FieldDescriptorProto_Type.TYPE_FIXED32:
      case FieldDescriptorProto_Type.TYPE_SFIXED32:
        return _getDefaultAsInt32Expr('0');
      case FieldDescriptorProto_Type.TYPE_STRING:
        return _getDefaultAsStringExpr("''");
      default:
        return 'null';
    }
  }

  /// Returns a function expression that returns the field's default value.
  ///
  /// [fileGen] represents the .proto file where the expression will be
  /// evaluated.
  String generateDefaultFunction(FileGenerator fileGen) {
    assert(!isRepeated);
    switch (descriptor.type) {
      case FieldDescriptorProto_Type.TYPE_BOOL:
        return _getDefaultAsBoolExpr(null);
      case FieldDescriptorProto_Type.TYPE_FLOAT:
      case FieldDescriptorProto_Type.TYPE_DOUBLE:
        if (!descriptor.hasDefaultValue()) {
          return null;
        } else if ('0.0' == descriptor.defaultValue ||
            '0' == descriptor.defaultValue) {
          return null;
        } else if (descriptor.defaultValue == 'inf') {
          return '$coreImportPrefix.double.infinity';
        } else if (descriptor.defaultValue == '-inf') {
          return '$coreImportPrefix.double.negativeInfinity';
        } else if (descriptor.defaultValue == 'nan') {
          return '$coreImportPrefix.double.nan';
        } else if (_hexLiteralRegex.hasMatch(descriptor.defaultValue)) {
          return '(${descriptor.defaultValue}).toDouble()';
        } else if (_integerLiteralRegex.hasMatch(descriptor.defaultValue)) {
          return '${descriptor.defaultValue}.0';
        } else if (_decimalLiteralRegexA.hasMatch(descriptor.defaultValue) ||
            _decimalLiteralRegexB.hasMatch(descriptor.defaultValue)) {
          return descriptor.defaultValue;
        }
        throw _invalidDefaultValue;
      case FieldDescriptorProto_Type.TYPE_INT32:
      case FieldDescriptorProto_Type.TYPE_UINT32:
      case FieldDescriptorProto_Type.TYPE_SINT32:
      case FieldDescriptorProto_Type.TYPE_FIXED32:
      case FieldDescriptorProto_Type.TYPE_SFIXED32:
        return _getDefaultAsInt32Expr(null);
      case FieldDescriptorProto_Type.TYPE_INT64:
      case FieldDescriptorProto_Type.TYPE_UINT64:
      case FieldDescriptorProto_Type.TYPE_SINT64:
      case FieldDescriptorProto_Type.TYPE_FIXED64:
      case FieldDescriptorProto_Type.TYPE_SFIXED64:
        var value = '0';
        if (descriptor.hasDefaultValue()) value = descriptor.defaultValue;
        if (value == '0') return '$_fixnumImportPrefix.Int64.ZERO';
        return "$protobufImportPrefix.parseLongInt('$value')";
      case FieldDescriptorProto_Type.TYPE_STRING:
        return _getDefaultAsStringExpr(null);
      case FieldDescriptorProto_Type.TYPE_BYTES:
        if (!descriptor.hasDefaultValue() || descriptor.defaultValue.isEmpty) {
          return null;
        }
        var byteList = descriptor.defaultValue.codeUnits
            .map((b) => '0x${b.toRadixString(16)}')
            .join(',');
        return '() => <$coreImportPrefix.int>[$byteList]';
      case FieldDescriptorProto_Type.TYPE_GROUP:
      case FieldDescriptorProto_Type.TYPE_MESSAGE:
        return '${baseType.getDartType(fileGen)}.getDefault';
      case FieldDescriptorProto_Type.TYPE_ENUM:
        var className = baseType.getDartType(fileGen);
        final gen = baseType.generator as EnumGenerator;
        if (descriptor.hasDefaultValue() &&
            descriptor.defaultValue.isNotEmpty) {
          return '$className.${descriptor.defaultValue}';
        } else if (gen._canonicalValues.isNotEmpty) {
          return '$className.${gen.dartNames[gen._canonicalValues[0].name]}';
        }
        return null;
      default:
        throw _typeNotImplemented('generatedDefaultFunction');
    }
  }

  String _getDefaultAsBoolExpr(String noDefault) {
    if (descriptor.hasDefaultValue() && 'false' != descriptor.defaultValue) {
      return descriptor.defaultValue;
    }
    return noDefault;
  }

  String _getDefaultAsStringExpr(String noDefault) {
    if (!descriptor.hasDefaultValue() || descriptor.defaultValue.isEmpty) {
      return noDefault;
    }

    return quoted(descriptor.defaultValue);
  }

  String _getDefaultAsInt32Expr(String noDefault) {
    if (descriptor.hasDefaultValue() && '0' != descriptor.defaultValue) {
      return descriptor.defaultValue;
    }
    return noDefault;
  }

  bool _hasBooleanOption(Extension extension) =>
      descriptor?.options?.getExtension(extension) as bool ?? false;

  String get _invalidDefaultValue => 'dart-protoc-plugin:'
      ' invalid default value (${descriptor.defaultValue})'
      ' found in field $fullName';

  String _typeNotImplemented(String methodName) => 'dart-protoc-plugin:'
      ' $methodName not implemented for type (${descriptor.type})'
      ' found in field $fullName';

  static final RegExp _upperCase = RegExp('[A-Z]');

  static String _unCamelCase(String name) {
    return name.replaceAllMapped(
        _upperCase, (match) => '_${match.group(0).toLowerCase()}');
  }
}
