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

typedef CreateBuilderFunc = GeneratedMessage Function();
typedef MakeDefaultFunc = Function();
typedef ValueOfFunc = ProtobufEnum Function(int value);

/// The base class for all protobuf message types.
///
/// The protoc plugin generates subclasses providing type-specific
/// properties and methods.
///
/// Public properties and methods added here should also be added to
/// GeneratedMessage_reservedNames and should be unlikely to be used in
/// a proto file.
abstract class GeneratedMessage {
  _FieldSet _fieldSet;

  GeneratedMessage() {
    _fieldSet = _FieldSet(this, info_, eventPlugin);
    if (eventPlugin != null) eventPlugin.attach(this);
  }

  GeneratedMessage.fromBuffer(
      List<int> input, ExtensionRegistry extensionRegistry) {
    _fieldSet = _FieldSet(this, info_, eventPlugin);
    if (eventPlugin != null) eventPlugin.attach(this);
    mergeFromBuffer(input, extensionRegistry);
  }

  GeneratedMessage.fromJson(String input, ExtensionRegistry extensionRegistry) {
    _fieldSet = _FieldSet(this, info_, eventPlugin);
    if (eventPlugin != null) eventPlugin.attach(this);
    mergeFromJson(input, extensionRegistry);
  }

  // Overridden by subclasses.
  BuilderInfo get info_;

  /// Subclasses can override this getter to be notified of changes
  /// to protobuf fields.
  EventPlugin get eventPlugin => null;

  /// Creates a deep copy of the fields in this message.
  /// (The generated code uses [mergeFromMessage].)
  GeneratedMessage clone();

  /// Creates an empty instance of the same message type as this.
  GeneratedMessage createEmptyInstance();

  UnknownFieldSet get unknownFields => _fieldSet._ensureUnknownFields();

  /// Make this message read-only.
  ///
  /// Marks this message, and any sub-messages, as read-only.
  GeneratedMessage freeze() {
    _fieldSet._markReadOnly();
    return this;
  }

  /// Returns `true` if this message is marked read-only. Otherwise `false`.
  ///
  /// Even when `false`, some sub-message could be read-only.
  ///
  /// If `true` all sub-messages are frozen.
  bool get isFrozen => _fieldSet._isReadOnly;

  /// Returns a writable, shallow copy of this message.
  ///
  /// Sub messages will be shared with [this] and will still be frozen if [this]
  /// is frozen.
  ///
  /// The lists representing repeated fields are copied. But their elements will
  /// be shared with the corresponding list in [this].
  ///
  /// Similarly for map fields, the maps will be copied, but share the elements.
  // TODO(nichite, sigurdm): Consider returning an actual builder object that
  // lazily creates builders.
  GeneratedMessage toBuilder() {
    final result = createEmptyInstance();
    result._fieldSet._shallowCopyValues(_fieldSet);
    return result;
  }

  /// Apply [updates] to a copy of this message.
  ///
  /// Makes a writable copy of this message, applies the [updates] to it, and
  /// marks the copy read-only before returning it.
  GeneratedMessage copyWith(void Function(GeneratedMessage) updates) {
    final builder = toBuilder();
    updates(builder);
    return builder.freeze();
  }

  bool hasRequiredFields() => info_.hasRequiredFields;

  /// Returns [:true:] if all required fields in the message and all embedded
  /// messages are set, false otherwise.
  bool isInitialized() => _fieldSet._hasRequiredValues();

  /// Clears all data that was set in this message.
  ///
  /// After calling [clear], [getField] will still return default values for
  /// unset fields.
  void clear() => _fieldSet._clear();

  // TODO(antonm): move to getters.
  int getTagNumber(String fieldName) => info_.tagNumber(fieldName);

  @override
  bool operator ==(other) {
    if (identical(this, other)) return true;
    return other is GeneratedMessage
        ? _fieldSet._equals(other._fieldSet)
        : false;
  }

  /// Calculates a hash code based on the contents of the protobuf.
  ///
  /// The hash may change when any field changes (recursively).
  /// Therefore, protobufs used as map keys shouldn't be changed.
  @override
  int get hashCode => _fieldSet._hashCode;

  /// Returns a String representation of this message.
  ///
  /// This representation is similar to, but not quite, the Protocol Buffer
  /// TextFormat. Each field is printed on its own line. Sub-messages are
  /// indented two spaces farther than their parent messages.
  ///
  /// Note that this format is absolutely subject to change, and should only
  /// ever be used for debugging.
  @override
  String toString() => toDebugString();

  /// Returns a String representation of this message.
  ///
  /// This generates the same output as [toString], but can be used by mixins
  /// to compose debug strings with additional information.
  String toDebugString() {
    var out = StringBuffer();
    _fieldSet.writeString(out, '');
    return out.toString();
  }

  void check() {
    if (!isInitialized()) {
      var invalidFields = <String>[];
      _fieldSet._appendInvalidFields(invalidFields, '');
      var missingFields = (invalidFields..sort()).join(', ');
      throw StateError('Message missing required fields: $missingFields');
    }
  }

  Uint8List writeToBuffer() {
    var out = CodedBufferWriter();
    writeToCodedBufferWriter(out);
    return out.toBuffer();
  }

  void writeToCodedBufferWriter(CodedBufferWriter output) =>
      _writeToCodedBufferWriter(_fieldSet, output);

  void mergeFromCodedBufferReader(CodedBufferReader input,
          [ExtensionRegistry extensionRegistry = ExtensionRegistry.EMPTY]) =>
      _mergeFromCodedBufferReader(_fieldSet, input, extensionRegistry);

  /// Merges serialized protocol buffer data into this message.
  ///
  /// For each field in [input] that is already present in this message:
  ///
  /// * If it's a repeated field, this appends to the end of our list.
  /// * Else, if it's a scalar, this overwrites our field.
  /// * Else, (it's a non-repeated sub-message), this recursively merges into
  ///   the existing sub-message.
  void mergeFromBuffer(List<int> input,
      [ExtensionRegistry extensionRegistry = ExtensionRegistry.EMPTY]) {
    var codedInput = CodedBufferReader(input);
    _mergeFromCodedBufferReader(_fieldSet, codedInput, extensionRegistry);
    codedInput.checkLastTagWas(0);
  }

  // JSON support.

  /// Returns the JSON encoding of this message as a Dart [Map].
  ///
  /// The encoding is described in [GeneratedMessage.writeToJson].
  Map<String, dynamic> writeToJsonMap() => _writeToJsonMap(_fieldSet);

  /// Returns a JSON string that encodes this message.
  ///
  /// Each message (top level or nested) is represented as an object delimited
  /// by curly braces. Within a message, elements are indexed by tag number
  /// (surrounded by quotes). Repeated elements are represented as arrays.
  ///
  /// Boolean values, strings, and floating-point values are represented as
  /// literals. Values with a 32-bit integer datatype are represented as integer
  /// literals; values with a 64-bit integer datatype (regardless of their
  /// actual runtime value) are represented as strings. Enumerated values are
  /// represented as their integer value.
  ///
  /// For the proto3 JSON format use: [toProto3JSON].
  String writeToJson() => jsonEncode(writeToJsonMap());

  /// Returns an Object representing Proto3 JSON serialization of [this].
  ///
  /// The key for each field is be the camel-cased name of the field.
  ///
  /// Well-known types and their special JSON encoding are supported.
  /// If a well-known type cannot be encoded (eg. a `google.protobuf.Timestamp`
  /// with negative `nanoseconds`) an error is thrown.
  ///
  /// Extensions and unknown fields are not encoded.
  ///
  /// The [typeRegistry] is be used for encoding `Any` messages. If an `Any`
  /// message encoding a type not in [typeRegistry] is encountered, an
  /// error is thrown.
  Object toProto3Json(
          {TypeRegistry typeRegistry = const TypeRegistry.empty()}) =>
      _writeToProto3Json(_fieldSet, typeRegistry);

  /// Merges field values from [json], a JSON object using proto3 encoding.
  ///
  /// Well-known types and their special JSON encoding are supported.
  ///
  /// If [ignoreUnknownFields] is `false` (the default) an
  /// [FormatException] is be thrown if an unknown field or enum name
  /// is encountered. Otherwise the unknown field or enum is ignored.
  ///
  /// If [supportNamesWithUnderscores] is `true` (the default) field names in
  /// the JSON can be represented as either camel-case JSON-names or names with
  /// underscores.
  /// If `false` only the JSON names are supported.
  ///
  /// If [permissiveEnums] is `true` (default `false`) enum values in the
  /// JSON will be matched without case insensitivity and ignoring `-`s and `_`.
  /// This allows JSON values like `camelCase` and `kebab-case` to match the
  /// enum values `CAMEL_CASE` and `KEBAB_CASE`.
  /// In case of ambiguities between the enum values, the first matching value
  /// will be found.
  ///
  /// The [typeRegistry] is be used for decoding `Any` messages. If an `Any`
  /// message encoding a type not in [typeRegistry] is encountered, a
  /// [FormatException] is thrown.
  ///
  /// If the JSON is otherwise not formatted correctly (a String where a
  /// number was expected etc.) a [FormatException] is thrown.
  void mergeFromProto3Json(Object json,
          {TypeRegistry typeRegistry = const TypeRegistry.empty(),
          bool ignoreUnknownFields = false,
          bool supportNamesWithUnderscores = true,
          bool permissiveEnums = false}) =>
      _mergeFromProto3Json(json, _fieldSet, typeRegistry, ignoreUnknownFields,
          supportNamesWithUnderscores, permissiveEnums);

  /// Merges field values from [data], a JSON object, encoded as described by
  /// [GeneratedMessage.writeToJson].
  ///
  /// For the proto3 JSON format use: [mergeFromProto3JSON].
  void mergeFromJson(String data,
      [ExtensionRegistry extensionRegistry = ExtensionRegistry.EMPTY]) {
    /// Disable lazy creation of Dart objects for a dart2js speedup.
    /// This is a slight regression on the Dart VM.
    /// TODO(skybrian) we could skip the reviver if we're running
    /// on the Dart VM for a slight speedup.
    final jsonMap =
        jsonDecode(data, reviver: _emptyReviver) as Map<String, dynamic>;
    _mergeFromJsonMap(_fieldSet, jsonMap, extensionRegistry);
  }

  static dynamic _emptyReviver(k, v) => v;

  /// Merges field values from a JSON object represented as a Dart map.
  ///
  /// The encoding is described in [GeneratedMessage.writeToJson].
  void mergeFromJsonMap(Map<String, dynamic> json,
      [ExtensionRegistry extensionRegistry = ExtensionRegistry.EMPTY]) {
    _mergeFromJsonMap(_fieldSet, json, extensionRegistry);
  }

  /// Adds an extension field value to a repeated field.
  ///
  /// The backing [List] will be created if necessary.
  /// If the list already exists, the old extension won't be overwritten.
  void addExtension(Extension extension, var value) {
    if (!extension.isRepeated) {
      throw ArgumentError(
          'Cannot add to a non-repeated field (use setExtension())');
    }
    _fieldSet._ensureExtensions().._ensureRepeatedField(extension).add(value);
  }

  /// Clears an extension field and also removes the extension.
  void clearExtension(Extension extension) {
    if (_fieldSet._hasExtensions) {
      _fieldSet._extensions._clearFieldAndInfo(extension);
    }
  }

  /// Clears the contents of a given field.
  ///
  /// If it's an extension field, the Extension will be kept.
  /// The tagNumber should be a valid tag or extension.
  void clearField(int tagNumber) => _fieldSet._clearField(tagNumber);

  int $_whichOneof(int oneofIndex) => _fieldSet._oneofCases[oneofIndex] ?? 0;

  bool extensionsAreInitialized() => _fieldSet._hasRequiredExtensionValues();

  /// Returns the value of [extension].
  ///
  /// If not set, returns the extension's default value.
  dynamic getExtension(Extension extension) {
    return _fieldSet._ensureExtensions()._getFieldOrDefault(extension);
  }

  /// Returns the value of the field associated with [tagNumber], or the
  /// default value if it is not set.
  dynamic getField(int tagNumber) => _fieldSet._getField(tagNumber);

  /// Creates List implementing a mutable repeated field.
  ///
  /// Mixins may override this method to change the List type. To ensure
  /// that the protobuf can be encoded correctly, the returned List must
  /// validate all items added to it. This can most easily be done
  /// using the FieldInfo.check function.
  List<T> createRepeatedField<T>(int tagNumber, FieldInfo<T> fi) {
    return PbList<T>(check: fi.check);
  }

  /// Creates a Map representing a map field.
  Map<K, V> createMapField<K, V>(int tagNumber, MapFieldInfo<K, V> fi) {
    return PbMap<K, V>(
        fi.keyFieldType, fi.valueFieldType, fi.mapEntryBuilderInfo);
  }

  /// Returns the value of a field, ignoring any defaults.
  ///
  /// For unset or cleared fields, returns null.
  /// Also returns null for unknown tag numbers.
  dynamic getFieldOrNull(int tagNumber) =>
      _fieldSet._getFieldOrNullByTag(tagNumber);

  /// Returns the default value for the given field.
  ///
  /// For repeated fields, returns an immutable empty list
  /// (unlike [getField]). For all other fields, returns
  /// the same thing that getField() would for a cleared field.
  dynamic getDefaultForField(int tagNumber) =>
      _fieldSet._ensureInfo(tagNumber).readonlyDefault;

  /// Returns [:true:] if a value of [extension] is present.
  bool hasExtension(Extension extension) =>
      _fieldSet._hasExtensions &&
      _fieldSet._extensions._getFieldOrNull(extension) != null;

  /// Returns [:true:] if this message has a field associated with [tagNumber].
  bool hasField(int tagNumber) => _fieldSet._hasField(tagNumber);

  /// Merges the contents of the [other] into this message.
  ///
  /// Singular fields that are set in [other] overwrite the corresponding fields
  /// in this message. Repeated fields are appended. Singular sub-messages are
  /// recursively merged.
  void mergeFromMessage(GeneratedMessage other) =>
      _fieldSet._mergeFromMessage(other._fieldSet);

  void mergeUnknownFields(UnknownFieldSet unknownFieldSet) => _fieldSet
      ._ensureUnknownFields()
      .mergeFromUnknownFieldSet(unknownFieldSet);

  /// Sets the value of a non-repeated extension field to [value].
  void setExtension(Extension extension, value) {
    if (value == null) throw ArgumentError('value is null');
    if (_isRepeated(extension.type)) {
      throw ArgumentError(_fieldSet._setFieldFailedMessage(
          extension, value, 'repeating field (use get + .add())'));
    }
    _fieldSet._ensureExtensions()._setFieldAndInfo(extension, value);
  }

  /// Sets the value of a field by its [tagNumber].
  ///
  /// Throws an [:ArgumentError:] if [value] does not match the type
  /// associated with [tagNumber].
  ///
  /// Throws an [:ArgumentError:] if [value] is [:null:]. To clear a field of
  /// it's current value, use [clearField] instead.
  void setField(int tagNumber, value) {
    _fieldSet._setField(tagNumber, value);
    return; // ignore: dead_code
    return; // ignore: dead_code
  }

  /// For generated code only.
  T $_get<T>(int index, T defaultValue) =>
      _fieldSet._$get<T>(index, defaultValue);

  /// For generated code only.
  T $_getN<T>(int index) {
    // The implicit downcast at the return is always correct by construction
    // from the protoc generator. dart2js will omit the implicit downcast when
    // compiling with `-O3` or higher. We should introduce some way to
    // communicate that the downcast cannot fail to the other compilers.
    //
    // TODO(sra): With NNDB we will need to add 'as T', and a dart2js annotation
    // (to be implemented) to omit the 'as' check.
    return _fieldSet._$getND(index);
  }

  /// For generated code only.
  T $_ensure<T>(int index) {
    return _fieldSet._$ensure<T>(index);
  }

  /// For generated code only.
  List<T> $_getList<T>(int index) => _fieldSet._$getList<T>(index);

  /// For generated code only.
  Map<K, V> $_getMap<K, V>(int index) => _fieldSet._$getMap<K, V>(index);

  /// For generated code only.
  bool $_getB(int index, bool defaultValue) =>
      _fieldSet._$getB(index, defaultValue);

  /// For generated code only.
  bool $_getBF(int index) => _fieldSet._$getBF(index);

  /// For generated code only.
  int $_getI(int index, int defaultValue) =>
      _fieldSet._$getI(index, defaultValue);

  /// For generated code only.
  int $_getIZ(int index) => _fieldSet._$getIZ(index);

  /// For generated code only.
  String $_getS(int index, String defaultValue) =>
      _fieldSet._$getS(index, defaultValue);

  /// For generated code only.
  String $_getSZ(int index) => _fieldSet._$getSZ(index);

  /// For generated code only.
  Int64 $_getI64(int index) => _fieldSet._$getI64(index);

  /// For generated code only.
  bool $_has(int index) => _fieldSet._$has(index);

  /// For generated code only.
  void $_setBool(int index, bool value) => _fieldSet._$set(index, value);

  /// For generated code only.
  void $_setBytes(int index, List<int> value) => _fieldSet._$set(index, value);

  /// For generated code only.
  void $_setString(int index, String value) => _fieldSet._$set(index, value);

  /// For generated code only.
  void $_setFloat(int index, double value) {
    if (value == null || !_isFloat32(value)) {
      _fieldSet._$check(index, value);
    }
    _fieldSet._$set(index, value);
  }

  /// For generated code only.
  void $_setDouble(int index, double value) => _fieldSet._$set(index, value);

  /// For generated code only.
  void $_setSignedInt32(int index, int value) {
    if (value == null || !_isSigned32(value)) {
      _fieldSet._$check(index, value);
    }
    _fieldSet._$set(index, value);
  }

  /// For generated code only.
  void $_setUnsignedInt32(int index, int value) {
    if (value == null || !_isUnsigned32(value)) {
      _fieldSet._$check(index, value);
    }
    _fieldSet._$set(index, value);
  }

  /// For generated code only.
  void $_setInt64(int index, Int64 value) => _fieldSet._$set(index, value);

  // Support for generating a read-only default singleton instance.

  static final Map<Function, Function> _defaultMakers = {};

  static T Function() _defaultMakerFor<T extends GeneratedMessage>(
      T Function() createFn) {
    return _defaultMakers[createFn] ??= _createDefaultMakerFor<T>(createFn);
  }

  static T Function() _createDefaultMakerFor<T extends GeneratedMessage>(
      T Function() createFn) {
    T defaultValue;
    T defaultMaker() {
      return defaultValue ??= createFn()..freeze();
    }

    return defaultMaker;
  }

  /// For generated code only.
  static T $_defaultFor<T extends GeneratedMessage>(T Function() createFn) =>
      _defaultMakerFor<T>(createFn)();
}

/// The package name of a protobuf message.
class PackageName {
  final String name;
  const PackageName(this.name);
  String get prefix => name == '' ? '' : '$name.';
}
