// 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 name
  /// is encountered. Otherwise the unknown field 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.';
}
