// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: google/protobuf/struct.proto
#pragma warning disable 1591, 0612, 3021
#region Designer generated code

using pb = global::Google.Protobuf;
using pbc = global::Google.Protobuf.Collections;
using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace Google.Protobuf.WellKnownTypes {

  namespace Proto {

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public static partial class Struct {

      #region Descriptor
      public static pbr::FileDescriptor Descriptor {
        get { return descriptor; }
      }
      private static pbr::FileDescriptor descriptor;

      static Struct() {
        byte[] descriptorData = global::System.Convert.FromBase64String(
            string.Concat(
              "Chxnb29nbGUvcHJvdG9idWYvc3RydWN0LnByb3RvEg9nb29nbGUucHJvdG9i", 
              "dWYihAEKBlN0cnVjdBIzCgZmaWVsZHMYASADKAsyIy5nb29nbGUucHJvdG9i", 
              "dWYuU3RydWN0LkZpZWxkc0VudHJ5GkUKC0ZpZWxkc0VudHJ5EgsKA2tleRgB", 
              "IAEoCRIlCgV2YWx1ZRgCIAEoCzIWLmdvb2dsZS5wcm90b2J1Zi5WYWx1ZToC", 
              "OAEi6gEKBVZhbHVlEjAKCm51bGxfdmFsdWUYASABKA4yGi5nb29nbGUucHJv", 
              "dG9idWYuTnVsbFZhbHVlSAASFgoMbnVtYmVyX3ZhbHVlGAIgASgBSAASFgoM", 
              "c3RyaW5nX3ZhbHVlGAMgASgJSAASFAoKYm9vbF92YWx1ZRgEIAEoCEgAEi8K", 
              "DHN0cnVjdF92YWx1ZRgFIAEoCzIXLmdvb2dsZS5wcm90b2J1Zi5TdHJ1Y3RI", 
              "ABIwCgpsaXN0X3ZhbHVlGAYgASgLMhouZ29vZ2xlLnByb3RvYnVmLkxpc3RW", 
              "YWx1ZUgAQgYKBGtpbmQiMwoJTGlzdFZhbHVlEiYKBnZhbHVlcxgBIAMoCzIW", 
              "Lmdvb2dsZS5wcm90b2J1Zi5WYWx1ZSobCglOdWxsVmFsdWUSDgoKTlVMTF9W", 
              "QUxVRRAAQk4KE2NvbS5nb29nbGUucHJvdG9idWZCC1N0cnVjdFByb3RvUAGg", 
              "AQGiAgNHUEKqAh5Hb29nbGUuUHJvdG9idWYuV2VsbEtub3duVHlwZXNiBnBy", 
              "b3RvMw=="));
        descriptor = pbr::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
            new pbr::FileDescriptor[] { },
            new pbr::GeneratedCodeInfo(new[] {typeof(global::Google.Protobuf.WellKnownTypes.NullValue), }, new pbr::GeneratedCodeInfo[] {
              new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Struct), new[]{ "Fields" }, null, null, new pbr::GeneratedCodeInfo[] { null, }),
              new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.Value), new[]{ "NullValue", "NumberValue", "StringValue", "BoolValue", "StructValue", "ListValue" }, new[]{ "Kind" }, null, null),
              new pbr::GeneratedCodeInfo(typeof(global::Google.Protobuf.WellKnownTypes.ListValue), new[]{ "Values" }, null, null, null)
            }));
      }
      #endregion

    }
  }
  #region Enums
  public enum NullValue {
    NULL_VALUE = 0,
  }

  #endregion

  #region Messages
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class Struct : pb::IMessage<Struct> {
    private static readonly pb::MessageParser<Struct> _parser = new pb::MessageParser<Struct>(() => new Struct());
    public static pb::MessageParser<Struct> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.WellKnownTypes.Proto.Struct.Descriptor.MessageTypes[0]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public Struct() {
      OnConstruction();
    }

    partial void OnConstruction();

    public Struct(Struct other) : this() {
      fields_ = other.fields_.Clone();
    }

    public Struct Clone() {
      return new Struct(this);
    }

    public const int FieldsFieldNumber = 1;
    private static readonly pbc::MapField<string, global::Google.Protobuf.WellKnownTypes.Value>.Codec _map_fields_codec
        = new pbc::MapField<string, global::Google.Protobuf.WellKnownTypes.Value>.Codec(pb::FieldCodec.ForString(10), pb::FieldCodec.ForMessage(18, global::Google.Protobuf.WellKnownTypes.Value.Parser), 10);
    private readonly pbc::MapField<string, global::Google.Protobuf.WellKnownTypes.Value> fields_ = new pbc::MapField<string, global::Google.Protobuf.WellKnownTypes.Value>();
    public pbc::MapField<string, global::Google.Protobuf.WellKnownTypes.Value> Fields {
      get { return fields_; }
    }

    public override bool Equals(object other) {
      return Equals(other as Struct);
    }

    public bool Equals(Struct other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (!Fields.Equals(other.Fields)) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      hash ^= Fields.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      fields_.WriteTo(output, _map_fields_codec);
    }

    public int CalculateSize() {
      int size = 0;
      size += fields_.CalculateSize(_map_fields_codec);
      return size;
    }

    public void MergeFrom(Struct other) {
      if (other == null) {
        return;
      }
      fields_.Add(other.fields_);
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 10: {
            fields_.AddEntriesFrom(input, _map_fields_codec);
            break;
          }
        }
      }
    }

  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class Value : pb::IMessage<Value> {
    private static readonly pb::MessageParser<Value> _parser = new pb::MessageParser<Value>(() => new Value());
    public static pb::MessageParser<Value> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.WellKnownTypes.Proto.Struct.Descriptor.MessageTypes[1]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public Value() {
      OnConstruction();
    }

    partial void OnConstruction();

    public Value(Value other) : this() {
      switch (other.KindCase) {
        case KindOneofCase.NullValue:
          NullValue = other.NullValue;
          break;
        case KindOneofCase.NumberValue:
          NumberValue = other.NumberValue;
          break;
        case KindOneofCase.StringValue:
          StringValue = other.StringValue;
          break;
        case KindOneofCase.BoolValue:
          BoolValue = other.BoolValue;
          break;
        case KindOneofCase.StructValue:
          StructValue = other.StructValue.Clone();
          break;
        case KindOneofCase.ListValue:
          ListValue = other.ListValue.Clone();
          break;
      }

    }

    public Value Clone() {
      return new Value(this);
    }

    public const int NullValueFieldNumber = 1;
    public global::Google.Protobuf.WellKnownTypes.NullValue NullValue {
      get { return kindCase_ == KindOneofCase.NullValue ? (global::Google.Protobuf.WellKnownTypes.NullValue) kind_ : global::Google.Protobuf.WellKnownTypes.NullValue.NULL_VALUE; }
      set {
        kind_ = value;
        kindCase_ = KindOneofCase.NullValue;
      }
    }

    public const int NumberValueFieldNumber = 2;
    public double NumberValue {
      get { return kindCase_ == KindOneofCase.NumberValue ? (double) kind_ : 0D; }
      set {
        kind_ = value;
        kindCase_ = KindOneofCase.NumberValue;
      }
    }

    public const int StringValueFieldNumber = 3;
    public string StringValue {
      get { return kindCase_ == KindOneofCase.StringValue ? (string) kind_ : ""; }
      set {
        kind_ = pb::Preconditions.CheckNotNull(value, "value");
        kindCase_ = KindOneofCase.StringValue;
      }
    }

    public const int BoolValueFieldNumber = 4;
    public bool BoolValue {
      get { return kindCase_ == KindOneofCase.BoolValue ? (bool) kind_ : false; }
      set {
        kind_ = value;
        kindCase_ = KindOneofCase.BoolValue;
      }
    }

    public const int StructValueFieldNumber = 5;
    public global::Google.Protobuf.WellKnownTypes.Struct StructValue {
      get { return kindCase_ == KindOneofCase.StructValue ? (global::Google.Protobuf.WellKnownTypes.Struct) kind_ : null; }
      set {
        kind_ = value;
        kindCase_ = value == null ? KindOneofCase.None : KindOneofCase.StructValue;
      }
    }

    public const int ListValueFieldNumber = 6;
    public global::Google.Protobuf.WellKnownTypes.ListValue ListValue {
      get { return kindCase_ == KindOneofCase.ListValue ? (global::Google.Protobuf.WellKnownTypes.ListValue) kind_ : null; }
      set {
        kind_ = value;
        kindCase_ = value == null ? KindOneofCase.None : KindOneofCase.ListValue;
      }
    }

    private object kind_;
    public enum KindOneofCase {
      None = 0,
      NullValue = 1,
      NumberValue = 2,
      StringValue = 3,
      BoolValue = 4,
      StructValue = 5,
      ListValue = 6,
    }
    private KindOneofCase kindCase_ = KindOneofCase.None;
    public KindOneofCase KindCase {
      get { return kindCase_; }
    }

    public void ClearKind() {
      kindCase_ = KindOneofCase.None;
      kind_ = null;
    }

    public override bool Equals(object other) {
      return Equals(other as Value);
    }

    public bool Equals(Value other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (NullValue != other.NullValue) return false;
      if (NumberValue != other.NumberValue) return false;
      if (StringValue != other.StringValue) return false;
      if (BoolValue != other.BoolValue) return false;
      if (!object.Equals(StructValue, other.StructValue)) return false;
      if (!object.Equals(ListValue, other.ListValue)) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      if (kindCase_ == KindOneofCase.NullValue) hash ^= NullValue.GetHashCode();
      if (kindCase_ == KindOneofCase.NumberValue) hash ^= NumberValue.GetHashCode();
      if (kindCase_ == KindOneofCase.StringValue) hash ^= StringValue.GetHashCode();
      if (kindCase_ == KindOneofCase.BoolValue) hash ^= BoolValue.GetHashCode();
      if (kindCase_ == KindOneofCase.StructValue) hash ^= StructValue.GetHashCode();
      if (kindCase_ == KindOneofCase.ListValue) hash ^= ListValue.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      if (kindCase_ == KindOneofCase.NullValue) {
        output.WriteRawTag(8);
        output.WriteEnum((int) NullValue);
      }
      if (kindCase_ == KindOneofCase.NumberValue) {
        output.WriteRawTag(17);
        output.WriteDouble(NumberValue);
      }
      if (kindCase_ == KindOneofCase.StringValue) {
        output.WriteRawTag(26);
        output.WriteString(StringValue);
      }
      if (kindCase_ == KindOneofCase.BoolValue) {
        output.WriteRawTag(32);
        output.WriteBool(BoolValue);
      }
      if (kindCase_ == KindOneofCase.StructValue) {
        output.WriteRawTag(42);
        output.WriteMessage(StructValue);
      }
      if (kindCase_ == KindOneofCase.ListValue) {
        output.WriteRawTag(50);
        output.WriteMessage(ListValue);
      }
    }

    public int CalculateSize() {
      int size = 0;
      if (kindCase_ == KindOneofCase.NullValue) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) NullValue);
      }
      if (kindCase_ == KindOneofCase.NumberValue) {
        size += 1 + 8;
      }
      if (kindCase_ == KindOneofCase.StringValue) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(StringValue);
      }
      if (kindCase_ == KindOneofCase.BoolValue) {
        size += 1 + 1;
      }
      if (kindCase_ == KindOneofCase.StructValue) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(StructValue);
      }
      if (kindCase_ == KindOneofCase.ListValue) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(ListValue);
      }
      return size;
    }

    public void MergeFrom(Value other) {
      if (other == null) {
        return;
      }
      switch (other.KindCase) {
        case KindOneofCase.NullValue:
          NullValue = other.NullValue;
          break;
        case KindOneofCase.NumberValue:
          NumberValue = other.NumberValue;
          break;
        case KindOneofCase.StringValue:
          StringValue = other.StringValue;
          break;
        case KindOneofCase.BoolValue:
          BoolValue = other.BoolValue;
          break;
        case KindOneofCase.StructValue:
          StructValue = other.StructValue;
          break;
        case KindOneofCase.ListValue:
          ListValue = other.ListValue;
          break;
      }

    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 8: {
            kind_ = input.ReadEnum();
            kindCase_ = KindOneofCase.NullValue;
            break;
          }
          case 17: {
            NumberValue = input.ReadDouble();
            break;
          }
          case 26: {
            StringValue = input.ReadString();
            break;
          }
          case 32: {
            BoolValue = input.ReadBool();
            break;
          }
          case 42: {
            global::Google.Protobuf.WellKnownTypes.Struct subBuilder = new global::Google.Protobuf.WellKnownTypes.Struct();
            if (kindCase_ == KindOneofCase.StructValue) {
              subBuilder.MergeFrom(StructValue);
            }
            input.ReadMessage(subBuilder);
            StructValue = subBuilder;
            break;
          }
          case 50: {
            global::Google.Protobuf.WellKnownTypes.ListValue subBuilder = new global::Google.Protobuf.WellKnownTypes.ListValue();
            if (kindCase_ == KindOneofCase.ListValue) {
              subBuilder.MergeFrom(ListValue);
            }
            input.ReadMessage(subBuilder);
            ListValue = subBuilder;
            break;
          }
        }
      }
    }

  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class ListValue : pb::IMessage<ListValue> {
    private static readonly pb::MessageParser<ListValue> _parser = new pb::MessageParser<ListValue>(() => new ListValue());
    public static pb::MessageParser<ListValue> Parser { get { return _parser; } }

    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.WellKnownTypes.Proto.Struct.Descriptor.MessageTypes[2]; }
    }

    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    public ListValue() {
      OnConstruction();
    }

    partial void OnConstruction();

    public ListValue(ListValue other) : this() {
      values_ = other.values_.Clone();
    }

    public ListValue Clone() {
      return new ListValue(this);
    }

    public const int ValuesFieldNumber = 1;
    private static readonly pb::FieldCodec<global::Google.Protobuf.WellKnownTypes.Value> _repeated_values_codec
        = pb::FieldCodec.ForMessage(10, global::Google.Protobuf.WellKnownTypes.Value.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Value> values_ = new pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Value>();
    public pbc::RepeatedField<global::Google.Protobuf.WellKnownTypes.Value> Values {
      get { return values_; }
    }

    public override bool Equals(object other) {
      return Equals(other as ListValue);
    }

    public bool Equals(ListValue other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if(!values_.Equals(other.values_)) return false;
      return true;
    }

    public override int GetHashCode() {
      int hash = 1;
      hash ^= values_.GetHashCode();
      return hash;
    }

    public override string ToString() {
      return pb::JsonFormatter.Default.Format(this);
    }

    public void WriteTo(pb::CodedOutputStream output) {
      values_.WriteTo(output, _repeated_values_codec);
    }

    public int CalculateSize() {
      int size = 0;
      size += values_.CalculateSize(_repeated_values_codec);
      return size;
    }

    public void MergeFrom(ListValue other) {
      if (other == null) {
        return;
      }
      values_.Add(other.values_);
    }

    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 10: {
            values_.AddEntriesFrom(input, _repeated_values_codec);
            break;
          }
        }
      }
    }

  }

  #endregion

}

#endregion Designer generated code
