// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: unittest_issues.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 UnitTest.Issues.TestProtos {

  /// <summary>Holder for reflection information generated from unittest_issues.proto</summary>
  public static partial class UnittestIssuesReflection {

    #region Descriptor
    /// <summary>File descriptor for unittest_issues.proto</summary>
    public static pbr::FileDescriptor Descriptor {
      get { return descriptor; }
    }
    private static pbr::FileDescriptor descriptor;

    static UnittestIssuesReflection() {
      byte[] descriptorData = global::System.Convert.FromBase64String(
          string.Concat(
            "ChV1bml0dGVzdF9pc3N1ZXMucHJvdG8SD3VuaXR0ZXN0X2lzc3VlcyInCghJ",
            "c3N1ZTMwNxobCgpOZXN0ZWRPbmNlGg0KC05lc3RlZFR3aWNlIrABChNOZWdh",
            "dGl2ZUVudW1NZXNzYWdlEiwKBXZhbHVlGAEgASgOMh0udW5pdHRlc3RfaXNz",
            "dWVzLk5lZ2F0aXZlRW51bRIxCgZ2YWx1ZXMYAiADKA4yHS51bml0dGVzdF9p",
            "c3N1ZXMuTmVnYXRpdmVFbnVtQgIQABI4Cg1wYWNrZWRfdmFsdWVzGAMgAygO",
            "Mh0udW5pdHRlc3RfaXNzdWVzLk5lZ2F0aXZlRW51bUICEAEiEQoPRGVwcmVj",
            "YXRlZENoaWxkIrkCChdEZXByZWNhdGVkRmllbGRzTWVzc2FnZRIaCg5Qcmlt",
            "aXRpdmVWYWx1ZRgBIAEoBUICGAESGgoOUHJpbWl0aXZlQXJyYXkYAiADKAVC",
            "AhgBEjoKDE1lc3NhZ2VWYWx1ZRgDIAEoCzIgLnVuaXR0ZXN0X2lzc3Vlcy5E",
            "ZXByZWNhdGVkQ2hpbGRCAhgBEjoKDE1lc3NhZ2VBcnJheRgEIAMoCzIgLnVu",
            "aXR0ZXN0X2lzc3Vlcy5EZXByZWNhdGVkQ2hpbGRCAhgBEjYKCUVudW1WYWx1",
            "ZRgFIAEoDjIfLnVuaXR0ZXN0X2lzc3Vlcy5EZXByZWNhdGVkRW51bUICGAES",
            "NgoJRW51bUFycmF5GAYgAygOMh8udW5pdHRlc3RfaXNzdWVzLkRlcHJlY2F0",
            "ZWRFbnVtQgIYASIZCglJdGVtRmllbGQSDAoEaXRlbRgBIAEoBSJECg1SZXNl",
            "cnZlZE5hbWVzEg0KBXR5cGVzGAEgASgFEhIKCmRlc2NyaXB0b3IYAiABKAUa",
            "EAoOU29tZU5lc3RlZFR5cGUioAEKFVRlc3RKc29uRmllbGRPcmRlcmluZxIT",
            "CgtwbGFpbl9pbnQzMhgEIAEoBRITCglvMV9zdHJpbmcYAiABKAlIABISCghv",
            "MV9pbnQzMhgFIAEoBUgAEhQKDHBsYWluX3N0cmluZxgBIAEoCRISCghvMl9p",
            "bnQzMhgGIAEoBUgBEhMKCW8yX3N0cmluZxgDIAEoCUgBQgQKAm8xQgQKAm8y",
            "IksKDFRlc3RKc29uTmFtZRIMCgRuYW1lGAEgASgJEhkKC2Rlc2NyaXB0aW9u",
            "GAIgASgJUgRkZXNjEhIKBGd1aWQYAyABKAlSBGV4aWQqVQoMTmVnYXRpdmVF",
            "bnVtEhYKEk5FR0FUSVZFX0VOVU1fWkVSTxAAEhYKCUZpdmVCZWxvdxD7////",
            "//////8BEhUKCE1pbnVzT25lEP///////////wEqLgoORGVwcmVjYXRlZEVu",
            "dW0SEwoPREVQUkVDQVRFRF9aRVJPEAASBwoDb25lEAFCH0gBqgIaVW5pdFRl",
            "c3QuSXNzdWVzLlRlc3RQcm90b3NiBnByb3RvMw=="));
      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
          new pbr::FileDescriptor[] { },
          new pbr::GeneratedClrTypeInfo(new[] {typeof(global::UnitTest.Issues.TestProtos.NegativeEnum), typeof(global::UnitTest.Issues.TestProtos.DeprecatedEnum), }, new pbr::GeneratedClrTypeInfo[] {
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307), global::UnitTest.Issues.TestProtos.Issue307.Parser, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce), global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Parser, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Types.NestedTwice), global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Types.NestedTwice.Parser, null, null, null, null)})}),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.NegativeEnumMessage), global::UnitTest.Issues.TestProtos.NegativeEnumMessage.Parser, new[]{ "Value", "Values", "PackedValues" }, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.DeprecatedChild), global::UnitTest.Issues.TestProtos.DeprecatedChild.Parser, null, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage), global::UnitTest.Issues.TestProtos.DeprecatedFieldsMessage.Parser, new[]{ "PrimitiveValue", "PrimitiveArray", "MessageValue", "MessageArray", "EnumValue", "EnumArray" }, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ItemField), global::UnitTest.Issues.TestProtos.ItemField.Parser, new[]{ "Item" }, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ReservedNames), global::UnitTest.Issues.TestProtos.ReservedNames.Parser, new[]{ "Types_", "Descriptor_" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ReservedNames.Types.SomeNestedType), global::UnitTest.Issues.TestProtos.ReservedNames.Types.SomeNestedType.Parser, null, null, null, null)}),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering), global::UnitTest.Issues.TestProtos.TestJsonFieldOrdering.Parser, new[]{ "PlainInt32", "O1String", "O1Int32", "PlainString", "O2Int32", "O2String" }, new[]{ "O1", "O2" }, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.TestJsonName), global::UnitTest.Issues.TestProtos.TestJsonName.Parser, new[]{ "Name", "Description", "Guid" }, null, null, null)
          }));
    }
    #endregion

  }
  #region Enums
  public enum NegativeEnum {
    [pbr::OriginalName("NEGATIVE_ENUM_ZERO")] Zero = 0,
    [pbr::OriginalName("FiveBelow")] FiveBelow = -5,
    [pbr::OriginalName("MinusOne")] MinusOne = -1,
  }

  public enum DeprecatedEnum {
    [pbr::OriginalName("DEPRECATED_ZERO")] DeprecatedZero = 0,
    [pbr::OriginalName("one")] One = 1,
  }

  #endregion

  #region Messages
  /// <summary>
  /// Issue 307: when generating doubly-nested types, any references
  /// should be of the form A.Types.B.Types.C.
  /// </summary>
  public sealed partial class Issue307 : pb::IMessage<Issue307> {
    private static readonly pb::MessageParser<Issue307> _parser = new pb::MessageParser<Issue307>(() => new Issue307());
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<Issue307> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[0]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public Issue307() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public Issue307(Issue307 other) : this() {
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public Issue307 Clone() {
      return new Issue307(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as Issue307);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(Issue307 other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      return true;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(Issue307 other) {
      if (other == null) {
        return;
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
        }
      }
    }

    #region Nested types
    /// <summary>Container for nested types declared in the Issue307 message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static partial class Types {
      public sealed partial class NestedOnce : pb::IMessage<NestedOnce> {
        private static readonly pb::MessageParser<NestedOnce> _parser = new pb::MessageParser<NestedOnce>(() => new NestedOnce());
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public static pb::MessageParser<NestedOnce> Parser { get { return _parser; } }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public static pbr::MessageDescriptor Descriptor {
          get { return global::UnitTest.Issues.TestProtos.Issue307.Descriptor.NestedTypes[0]; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        pbr::MessageDescriptor pb::IMessage.Descriptor {
          get { return Descriptor; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public NestedOnce() {
          OnConstruction();
        }

        partial void OnConstruction();

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public NestedOnce(NestedOnce other) : this() {
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public NestedOnce Clone() {
          return new NestedOnce(this);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override bool Equals(object other) {
          return Equals(other as NestedOnce);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool Equals(NestedOnce other) {
          if (ReferenceEquals(other, null)) {
            return false;
          }
          if (ReferenceEquals(other, this)) {
            return true;
          }
          return true;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override int GetHashCode() {
          int hash = 1;
          return hash;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override string ToString() {
          return pb::JsonFormatter.ToDiagnosticString(this);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void WriteTo(pb::CodedOutputStream output) {
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int CalculateSize() {
          int size = 0;
          return size;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void MergeFrom(NestedOnce other) {
          if (other == null) {
            return;
          }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void MergeFrom(pb::CodedInputStream input) {
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
            switch(tag) {
              default:
                input.SkipLastField();
                break;
            }
          }
        }

        #region Nested types
        /// <summary>Container for nested types declared in the NestedOnce message type.</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public static partial class Types {
          public sealed partial class NestedTwice : pb::IMessage<NestedTwice> {
            private static readonly pb::MessageParser<NestedTwice> _parser = new pb::MessageParser<NestedTwice>(() => new NestedTwice());
            [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
            public static pb::MessageParser<NestedTwice> Parser { get { return _parser; } }

            [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
            public static pbr::MessageDescriptor Descriptor {
              get { return global::UnitTest.Issues.TestProtos.Issue307.Types.NestedOnce.Descriptor.NestedTypes[0]; }
            }

            [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
            pbr::MessageDescriptor pb::IMessage.Descriptor {
              get { return Descriptor; }
            }

            [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
            public NestedTwice() {
              OnConstruction();
            }

            partial void OnConstruction();

            [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
            public NestedTwice(NestedTwice other) : this() {
            }

            [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
            public NestedTwice Clone() {
              return new NestedTwice(this);
            }

            [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
            public override bool Equals(object other) {
              return Equals(other as NestedTwice);
            }

            [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
            public bool Equals(NestedTwice other) {
              if (ReferenceEquals(other, null)) {
                return false;
              }
              if (ReferenceEquals(other, this)) {
                return true;
              }
              return true;
            }

            [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
            public override int GetHashCode() {
              int hash = 1;
              return hash;
            }

            [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
            public override string ToString() {
              return pb::JsonFormatter.ToDiagnosticString(this);
            }

            [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
            public void WriteTo(pb::CodedOutputStream output) {
            }

            [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
            public int CalculateSize() {
              int size = 0;
              return size;
            }

            [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
            public void MergeFrom(NestedTwice other) {
              if (other == null) {
                return;
              }
            }

            [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
            public void MergeFrom(pb::CodedInputStream input) {
              uint tag;
              while ((tag = input.ReadTag()) != 0) {
                switch(tag) {
                  default:
                    input.SkipLastField();
                    break;
                }
              }
            }

          }

        }
        #endregion

      }

    }
    #endregion

  }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[1]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public NegativeEnumMessage() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public NegativeEnumMessage(NegativeEnumMessage other) : this() {
      value_ = other.value_;
      values_ = other.values_.Clone();
      packedValues_ = other.packedValues_.Clone();
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public NegativeEnumMessage Clone() {
      return new NegativeEnumMessage(this);
    }

    /// <summary>Field number for the "value" field.</summary>
    public const int ValueFieldNumber = 1;
    private global::UnitTest.Issues.TestProtos.NegativeEnum value_ = 0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::UnitTest.Issues.TestProtos.NegativeEnum Value {
      get { return value_; }
      set {
        value_ = value;
      }
    }

    /// <summary>Field number for the "values" field.</summary>
    public const int ValuesFieldNumber = 2;
    private static readonly pb::FieldCodec<global::UnitTest.Issues.TestProtos.NegativeEnum> _repeated_values_codec
        = pb::FieldCodec.ForEnum(16, x => (int) x, x => (global::UnitTest.Issues.TestProtos.NegativeEnum) x);
    private readonly pbc::RepeatedField<global::UnitTest.Issues.TestProtos.NegativeEnum> values_ = new pbc::RepeatedField<global::UnitTest.Issues.TestProtos.NegativeEnum>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::UnitTest.Issues.TestProtos.NegativeEnum> Values {
      get { return values_; }
    }

    /// <summary>Field number for the "packed_values" field.</summary>
    public const int PackedValuesFieldNumber = 3;
    private static readonly pb::FieldCodec<global::UnitTest.Issues.TestProtos.NegativeEnum> _repeated_packedValues_codec
        = pb::FieldCodec.ForEnum(26, x => (int) x, x => (global::UnitTest.Issues.TestProtos.NegativeEnum) x);
    private readonly pbc::RepeatedField<global::UnitTest.Issues.TestProtos.NegativeEnum> packedValues_ = new pbc::RepeatedField<global::UnitTest.Issues.TestProtos.NegativeEnum>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::UnitTest.Issues.TestProtos.NegativeEnum> PackedValues {
      get { return packedValues_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as NegativeEnumMessage);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(NegativeEnumMessage other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Value != other.Value) return false;
      if(!values_.Equals(other.values_)) return false;
      if(!packedValues_.Equals(other.packedValues_)) return false;
      return true;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (Value != 0) hash ^= Value.GetHashCode();
      hash ^= values_.GetHashCode();
      hash ^= packedValues_.GetHashCode();
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      if (Value != 0) {
        output.WriteRawTag(8);
        output.WriteEnum((int) Value);
      }
      values_.WriteTo(output, _repeated_values_codec);
      packedValues_.WriteTo(output, _repeated_packedValues_codec);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (Value != 0) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Value);
      }
      size += values_.CalculateSize(_repeated_values_codec);
      size += packedValues_.CalculateSize(_repeated_packedValues_codec);
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(NegativeEnumMessage other) {
      if (other == null) {
        return;
      }
      if (other.Value != 0) {
        Value = other.Value;
      }
      values_.Add(other.values_);
      packedValues_.Add(other.packedValues_);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 8: {
            value_ = (global::UnitTest.Issues.TestProtos.NegativeEnum) input.ReadEnum();
            break;
          }
          case 18:
          case 16: {
            values_.AddEntriesFrom(input, _repeated_values_codec);
            break;
          }
          case 26:
          case 24: {
            packedValues_.AddEntriesFrom(input, _repeated_packedValues_codec);
            break;
          }
        }
      }
    }

  }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[2]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public DeprecatedChild() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public DeprecatedChild(DeprecatedChild other) : this() {
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public DeprecatedChild Clone() {
      return new DeprecatedChild(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as DeprecatedChild);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(DeprecatedChild other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      return true;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(DeprecatedChild other) {
      if (other == null) {
        return;
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
        }
      }
    }

  }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[3]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public DeprecatedFieldsMessage() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public DeprecatedFieldsMessage(DeprecatedFieldsMessage other) : this() {
      primitiveValue_ = other.primitiveValue_;
      primitiveArray_ = other.primitiveArray_.Clone();
      MessageValue = other.messageValue_ != null ? other.MessageValue.Clone() : null;
      messageArray_ = other.messageArray_.Clone();
      enumValue_ = other.enumValue_;
      enumArray_ = other.enumArray_.Clone();
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public DeprecatedFieldsMessage Clone() {
      return new DeprecatedFieldsMessage(this);
    }

    /// <summary>Field number for the "PrimitiveValue" field.</summary>
    public const int PrimitiveValueFieldNumber = 1;
    private int primitiveValue_;
    [global::System.ObsoleteAttribute]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int PrimitiveValue {
      get { return primitiveValue_; }
      set {
        primitiveValue_ = value;
      }
    }

    /// <summary>Field number for the "PrimitiveArray" field.</summary>
    public const int PrimitiveArrayFieldNumber = 2;
    private static readonly pb::FieldCodec<int> _repeated_primitiveArray_codec
        = pb::FieldCodec.ForInt32(18);
    private readonly pbc::RepeatedField<int> primitiveArray_ = new pbc::RepeatedField<int>();
    [global::System.ObsoleteAttribute]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<int> PrimitiveArray {
      get { return primitiveArray_; }
    }

    /// <summary>Field number for the "MessageValue" field.</summary>
    public const int MessageValueFieldNumber = 3;
    private global::UnitTest.Issues.TestProtos.DeprecatedChild messageValue_;
    [global::System.ObsoleteAttribute]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::UnitTest.Issues.TestProtos.DeprecatedChild MessageValue {
      get { return messageValue_; }
      set {
        messageValue_ = value;
      }
    }

    /// <summary>Field number for the "MessageArray" field.</summary>
    public const int MessageArrayFieldNumber = 4;
    private static readonly pb::FieldCodec<global::UnitTest.Issues.TestProtos.DeprecatedChild> _repeated_messageArray_codec
        = pb::FieldCodec.ForMessage(34, global::UnitTest.Issues.TestProtos.DeprecatedChild.Parser);
    private readonly pbc::RepeatedField<global::UnitTest.Issues.TestProtos.DeprecatedChild> messageArray_ = new pbc::RepeatedField<global::UnitTest.Issues.TestProtos.DeprecatedChild>();
    [global::System.ObsoleteAttribute]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::UnitTest.Issues.TestProtos.DeprecatedChild> MessageArray {
      get { return messageArray_; }
    }

    /// <summary>Field number for the "EnumValue" field.</summary>
    public const int EnumValueFieldNumber = 5;
    private global::UnitTest.Issues.TestProtos.DeprecatedEnum enumValue_ = 0;
    [global::System.ObsoleteAttribute]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::UnitTest.Issues.TestProtos.DeprecatedEnum EnumValue {
      get { return enumValue_; }
      set {
        enumValue_ = value;
      }
    }

    /// <summary>Field number for the "EnumArray" field.</summary>
    public const int EnumArrayFieldNumber = 6;
    private static readonly pb::FieldCodec<global::UnitTest.Issues.TestProtos.DeprecatedEnum> _repeated_enumArray_codec
        = pb::FieldCodec.ForEnum(50, x => (int) x, x => (global::UnitTest.Issues.TestProtos.DeprecatedEnum) x);
    private readonly pbc::RepeatedField<global::UnitTest.Issues.TestProtos.DeprecatedEnum> enumArray_ = new pbc::RepeatedField<global::UnitTest.Issues.TestProtos.DeprecatedEnum>();
    [global::System.ObsoleteAttribute]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::UnitTest.Issues.TestProtos.DeprecatedEnum> EnumArray {
      get { return enumArray_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as DeprecatedFieldsMessage);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(DeprecatedFieldsMessage other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (PrimitiveValue != other.PrimitiveValue) return false;
      if(!primitiveArray_.Equals(other.primitiveArray_)) return false;
      if (!object.Equals(MessageValue, other.MessageValue)) return false;
      if(!messageArray_.Equals(other.messageArray_)) return false;
      if (EnumValue != other.EnumValue) return false;
      if(!enumArray_.Equals(other.enumArray_)) return false;
      return true;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (PrimitiveValue != 0) hash ^= PrimitiveValue.GetHashCode();
      hash ^= primitiveArray_.GetHashCode();
      if (messageValue_ != null) hash ^= MessageValue.GetHashCode();
      hash ^= messageArray_.GetHashCode();
      if (EnumValue != 0) hash ^= EnumValue.GetHashCode();
      hash ^= enumArray_.GetHashCode();
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      if (PrimitiveValue != 0) {
        output.WriteRawTag(8);
        output.WriteInt32(PrimitiveValue);
      }
      primitiveArray_.WriteTo(output, _repeated_primitiveArray_codec);
      if (messageValue_ != null) {
        output.WriteRawTag(26);
        output.WriteMessage(MessageValue);
      }
      messageArray_.WriteTo(output, _repeated_messageArray_codec);
      if (EnumValue != 0) {
        output.WriteRawTag(40);
        output.WriteEnum((int) EnumValue);
      }
      enumArray_.WriteTo(output, _repeated_enumArray_codec);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (PrimitiveValue != 0) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(PrimitiveValue);
      }
      size += primitiveArray_.CalculateSize(_repeated_primitiveArray_codec);
      if (messageValue_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(MessageValue);
      }
      size += messageArray_.CalculateSize(_repeated_messageArray_codec);
      if (EnumValue != 0) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) EnumValue);
      }
      size += enumArray_.CalculateSize(_repeated_enumArray_codec);
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(DeprecatedFieldsMessage other) {
      if (other == null) {
        return;
      }
      if (other.PrimitiveValue != 0) {
        PrimitiveValue = other.PrimitiveValue;
      }
      primitiveArray_.Add(other.primitiveArray_);
      if (other.messageValue_ != null) {
        if (messageValue_ == null) {
          messageValue_ = new global::UnitTest.Issues.TestProtos.DeprecatedChild();
        }
        MessageValue.MergeFrom(other.MessageValue);
      }
      messageArray_.Add(other.messageArray_);
      if (other.EnumValue != 0) {
        EnumValue = other.EnumValue;
      }
      enumArray_.Add(other.enumArray_);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 8: {
            PrimitiveValue = input.ReadInt32();
            break;
          }
          case 18:
          case 16: {
            primitiveArray_.AddEntriesFrom(input, _repeated_primitiveArray_codec);
            break;
          }
          case 26: {
            if (messageValue_ == null) {
              messageValue_ = new global::UnitTest.Issues.TestProtos.DeprecatedChild();
            }
            input.ReadMessage(messageValue_);
            break;
          }
          case 34: {
            messageArray_.AddEntriesFrom(input, _repeated_messageArray_codec);
            break;
          }
          case 40: {
            enumValue_ = (global::UnitTest.Issues.TestProtos.DeprecatedEnum) input.ReadEnum();
            break;
          }
          case 50:
          case 48: {
            enumArray_.AddEntriesFrom(input, _repeated_enumArray_codec);
            break;
          }
        }
      }
    }

  }

  /// <summary>
  /// Issue 45: http://code.google.com/p/protobuf-csharp-port/issues/detail?id=45
  /// </summary>
  public sealed partial class ItemField : pb::IMessage<ItemField> {
    private static readonly pb::MessageParser<ItemField> _parser = new pb::MessageParser<ItemField>(() => new ItemField());
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<ItemField> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[4]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public ItemField() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public ItemField(ItemField other) : this() {
      item_ = other.item_;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public ItemField Clone() {
      return new ItemField(this);
    }

    /// <summary>Field number for the "item" field.</summary>
    public const int ItemFieldNumber = 1;
    private int item_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int Item {
      get { return item_; }
      set {
        item_ = value;
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as ItemField);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(ItemField other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Item != other.Item) return false;
      return true;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (Item != 0) hash ^= Item.GetHashCode();
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      if (Item != 0) {
        output.WriteRawTag(8);
        output.WriteInt32(Item);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (Item != 0) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Item);
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(ItemField other) {
      if (other == null) {
        return;
      }
      if (other.Item != 0) {
        Item = other.Item;
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 8: {
            Item = input.ReadInt32();
            break;
          }
        }
      }
    }

  }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[5]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public ReservedNames() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public ReservedNames(ReservedNames other) : this() {
      types_ = other.types_;
      descriptor_ = other.descriptor_;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public ReservedNames Clone() {
      return new ReservedNames(this);
    }

    /// <summary>Field number for the "types" field.</summary>
    public const int Types_FieldNumber = 1;
    private int types_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int Types_ {
      get { return types_; }
      set {
        types_ = value;
      }
    }

    /// <summary>Field number for the "descriptor" field.</summary>
    public const int Descriptor_FieldNumber = 2;
    private int descriptor_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int Descriptor_ {
      get { return descriptor_; }
      set {
        descriptor_ = value;
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as ReservedNames);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(ReservedNames other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Types_ != other.Types_) return false;
      if (Descriptor_ != other.Descriptor_) return false;
      return true;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (Types_ != 0) hash ^= Types_.GetHashCode();
      if (Descriptor_ != 0) hash ^= Descriptor_.GetHashCode();
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      if (Types_ != 0) {
        output.WriteRawTag(8);
        output.WriteInt32(Types_);
      }
      if (Descriptor_ != 0) {
        output.WriteRawTag(16);
        output.WriteInt32(Descriptor_);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (Types_ != 0) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Types_);
      }
      if (Descriptor_ != 0) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Descriptor_);
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(ReservedNames other) {
      if (other == null) {
        return;
      }
      if (other.Types_ != 0) {
        Types_ = other.Types_;
      }
      if (other.Descriptor_ != 0) {
        Descriptor_ = other.Descriptor_;
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 8: {
            Types_ = input.ReadInt32();
            break;
          }
          case 16: {
            Descriptor_ = input.ReadInt32();
            break;
          }
        }
      }
    }

    #region Nested types
    /// <summary>Container for nested types declared in the ReservedNames message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static partial class Types {
      /// <summary>
      /// Force a nested type called Types
      /// </summary>
      public sealed partial class SomeNestedType : pb::IMessage<SomeNestedType> {
        private static readonly pb::MessageParser<SomeNestedType> _parser = new pb::MessageParser<SomeNestedType>(() => new SomeNestedType());
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public static pb::MessageParser<SomeNestedType> Parser { get { return _parser; } }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public static pbr::MessageDescriptor Descriptor {
          get { return global::UnitTest.Issues.TestProtos.ReservedNames.Descriptor.NestedTypes[0]; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        pbr::MessageDescriptor pb::IMessage.Descriptor {
          get { return Descriptor; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public SomeNestedType() {
          OnConstruction();
        }

        partial void OnConstruction();

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public SomeNestedType(SomeNestedType other) : this() {
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public SomeNestedType Clone() {
          return new SomeNestedType(this);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override bool Equals(object other) {
          return Equals(other as SomeNestedType);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool Equals(SomeNestedType other) {
          if (ReferenceEquals(other, null)) {
            return false;
          }
          if (ReferenceEquals(other, this)) {
            return true;
          }
          return true;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override int GetHashCode() {
          int hash = 1;
          return hash;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override string ToString() {
          return pb::JsonFormatter.ToDiagnosticString(this);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void WriteTo(pb::CodedOutputStream output) {
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int CalculateSize() {
          int size = 0;
          return size;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void MergeFrom(SomeNestedType other) {
          if (other == null) {
            return;
          }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void MergeFrom(pb::CodedInputStream input) {
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
            switch(tag) {
              default:
                input.SkipLastField();
                break;
            }
          }
        }

      }

    }
    #endregion

  }

  /// <summary>
  /// These fields are deliberately not declared in numeric
  /// order, and the oneof fields aren't contiguous either.
  /// This allows for reasonably robust tests of JSON output
  /// ordering.
  /// TestFieldOrderings in unittest_proto3.proto is similar,
  /// but doesn't include oneofs.
  /// TODO: Consider adding oneofs to TestFieldOrderings, although
  /// that will require fixing other tests in multiple platforms.
  /// Alternatively, consider just adding this to
  /// unittest_proto3.proto if multiple platforms want it.
  /// </summary>
  public sealed partial class TestJsonFieldOrdering : pb::IMessage<TestJsonFieldOrdering> {
    private static readonly pb::MessageParser<TestJsonFieldOrdering> _parser = new pb::MessageParser<TestJsonFieldOrdering>(() => new TestJsonFieldOrdering());
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<TestJsonFieldOrdering> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[6]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public TestJsonFieldOrdering() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public TestJsonFieldOrdering(TestJsonFieldOrdering other) : this() {
      plainInt32_ = other.plainInt32_;
      plainString_ = other.plainString_;
      switch (other.O1Case) {
        case O1OneofCase.O1String:
          O1String = other.O1String;
          break;
        case O1OneofCase.O1Int32:
          O1Int32 = other.O1Int32;
          break;
      }

      switch (other.O2Case) {
        case O2OneofCase.O2Int32:
          O2Int32 = other.O2Int32;
          break;
        case O2OneofCase.O2String:
          O2String = other.O2String;
          break;
      }

    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public TestJsonFieldOrdering Clone() {
      return new TestJsonFieldOrdering(this);
    }

    /// <summary>Field number for the "plain_int32" field.</summary>
    public const int PlainInt32FieldNumber = 4;
    private int plainInt32_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int PlainInt32 {
      get { return plainInt32_; }
      set {
        plainInt32_ = value;
      }
    }

    /// <summary>Field number for the "o1_string" field.</summary>
    public const int O1StringFieldNumber = 2;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string O1String {
      get { return o1Case_ == O1OneofCase.O1String ? (string) o1_ : ""; }
      set {
        o1_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
        o1Case_ = O1OneofCase.O1String;
      }
    }

    /// <summary>Field number for the "o1_int32" field.</summary>
    public const int O1Int32FieldNumber = 5;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int O1Int32 {
      get { return o1Case_ == O1OneofCase.O1Int32 ? (int) o1_ : 0; }
      set {
        o1_ = value;
        o1Case_ = O1OneofCase.O1Int32;
      }
    }

    /// <summary>Field number for the "plain_string" field.</summary>
    public const int PlainStringFieldNumber = 1;
    private string plainString_ = "";
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string PlainString {
      get { return plainString_; }
      set {
        plainString_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "o2_int32" field.</summary>
    public const int O2Int32FieldNumber = 6;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int O2Int32 {
      get { return o2Case_ == O2OneofCase.O2Int32 ? (int) o2_ : 0; }
      set {
        o2_ = value;
        o2Case_ = O2OneofCase.O2Int32;
      }
    }

    /// <summary>Field number for the "o2_string" field.</summary>
    public const int O2StringFieldNumber = 3;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string O2String {
      get { return o2Case_ == O2OneofCase.O2String ? (string) o2_ : ""; }
      set {
        o2_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
        o2Case_ = O2OneofCase.O2String;
      }
    }

    private object o1_;
    /// <summary>Enum of possible cases for the "o1" oneof.</summary>
    public enum O1OneofCase {
      None = 0,
      O1String = 2,
      O1Int32 = 5,
    }
    private O1OneofCase o1Case_ = O1OneofCase.None;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public O1OneofCase O1Case {
      get { return o1Case_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearO1() {
      o1Case_ = O1OneofCase.None;
      o1_ = null;
    }

    private object o2_;
    /// <summary>Enum of possible cases for the "o2" oneof.</summary>
    public enum O2OneofCase {
      None = 0,
      O2Int32 = 6,
      O2String = 3,
    }
    private O2OneofCase o2Case_ = O2OneofCase.None;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public O2OneofCase O2Case {
      get { return o2Case_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearO2() {
      o2Case_ = O2OneofCase.None;
      o2_ = null;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as TestJsonFieldOrdering);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(TestJsonFieldOrdering other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (PlainInt32 != other.PlainInt32) return false;
      if (O1String != other.O1String) return false;
      if (O1Int32 != other.O1Int32) return false;
      if (PlainString != other.PlainString) return false;
      if (O2Int32 != other.O2Int32) return false;
      if (O2String != other.O2String) return false;
      if (O1Case != other.O1Case) return false;
      if (O2Case != other.O2Case) return false;
      return true;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (PlainInt32 != 0) hash ^= PlainInt32.GetHashCode();
      if (o1Case_ == O1OneofCase.O1String) hash ^= O1String.GetHashCode();
      if (o1Case_ == O1OneofCase.O1Int32) hash ^= O1Int32.GetHashCode();
      if (PlainString.Length != 0) hash ^= PlainString.GetHashCode();
      if (o2Case_ == O2OneofCase.O2Int32) hash ^= O2Int32.GetHashCode();
      if (o2Case_ == O2OneofCase.O2String) hash ^= O2String.GetHashCode();
      hash ^= (int) o1Case_;
      hash ^= (int) o2Case_;
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      if (PlainString.Length != 0) {
        output.WriteRawTag(10);
        output.WriteString(PlainString);
      }
      if (o1Case_ == O1OneofCase.O1String) {
        output.WriteRawTag(18);
        output.WriteString(O1String);
      }
      if (o2Case_ == O2OneofCase.O2String) {
        output.WriteRawTag(26);
        output.WriteString(O2String);
      }
      if (PlainInt32 != 0) {
        output.WriteRawTag(32);
        output.WriteInt32(PlainInt32);
      }
      if (o1Case_ == O1OneofCase.O1Int32) {
        output.WriteRawTag(40);
        output.WriteInt32(O1Int32);
      }
      if (o2Case_ == O2OneofCase.O2Int32) {
        output.WriteRawTag(48);
        output.WriteInt32(O2Int32);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (PlainInt32 != 0) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(PlainInt32);
      }
      if (o1Case_ == O1OneofCase.O1String) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(O1String);
      }
      if (o1Case_ == O1OneofCase.O1Int32) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(O1Int32);
      }
      if (PlainString.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(PlainString);
      }
      if (o2Case_ == O2OneofCase.O2Int32) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(O2Int32);
      }
      if (o2Case_ == O2OneofCase.O2String) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(O2String);
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(TestJsonFieldOrdering other) {
      if (other == null) {
        return;
      }
      if (other.PlainInt32 != 0) {
        PlainInt32 = other.PlainInt32;
      }
      if (other.PlainString.Length != 0) {
        PlainString = other.PlainString;
      }
      switch (other.O1Case) {
        case O1OneofCase.O1String:
          O1String = other.O1String;
          break;
        case O1OneofCase.O1Int32:
          O1Int32 = other.O1Int32;
          break;
      }

      switch (other.O2Case) {
        case O2OneofCase.O2Int32:
          O2Int32 = other.O2Int32;
          break;
        case O2OneofCase.O2String:
          O2String = other.O2String;
          break;
      }

    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 10: {
            PlainString = input.ReadString();
            break;
          }
          case 18: {
            O1String = input.ReadString();
            break;
          }
          case 26: {
            O2String = input.ReadString();
            break;
          }
          case 32: {
            PlainInt32 = input.ReadInt32();
            break;
          }
          case 40: {
            O1Int32 = input.ReadInt32();
            break;
          }
          case 48: {
            O2Int32 = input.ReadInt32();
            break;
          }
        }
      }
    }

  }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::UnitTest.Issues.TestProtos.UnittestIssuesReflection.Descriptor.MessageTypes[7]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public TestJsonName() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public TestJsonName(TestJsonName other) : this() {
      name_ = other.name_;
      description_ = other.description_;
      guid_ = other.guid_;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public TestJsonName Clone() {
      return new TestJsonName(this);
    }

    /// <summary>Field number for the "name" field.</summary>
    public const int NameFieldNumber = 1;
    private string name_ = "";
    /// <summary>
    /// Message for testing the effects for of the json_name option
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Name {
      get { return name_; }
      set {
        name_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "description" field.</summary>
    public const int DescriptionFieldNumber = 2;
    private string description_ = "";
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Description {
      get { return description_; }
      set {
        description_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    /// <summary>Field number for the "guid" field.</summary>
    public const int GuidFieldNumber = 3;
    private string guid_ = "";
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string Guid {
      get { return guid_; }
      set {
        guid_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override bool Equals(object other) {
      return Equals(other as TestJsonName);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(TestJsonName other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Name != other.Name) return false;
      if (Description != other.Description) return false;
      if (Guid != other.Guid) return false;
      return true;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (Name.Length != 0) hash ^= Name.GetHashCode();
      if (Description.Length != 0) hash ^= Description.GetHashCode();
      if (Guid.Length != 0) hash ^= Guid.GetHashCode();
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void WriteTo(pb::CodedOutputStream output) {
      if (Name.Length != 0) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      if (Description.Length != 0) {
        output.WriteRawTag(18);
        output.WriteString(Description);
      }
      if (Guid.Length != 0) {
        output.WriteRawTag(26);
        output.WriteString(Guid);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (Name.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
      }
      if (Description.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Description);
      }
      if (Guid.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Guid);
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(TestJsonName other) {
      if (other == null) {
        return;
      }
      if (other.Name.Length != 0) {
        Name = other.Name;
      }
      if (other.Description.Length != 0) {
        Description = other.Description;
      }
      if (other.Guid.Length != 0) {
        Guid = other.Guid;
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            input.SkipLastField();
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 18: {
            Description = input.ReadString();
            break;
          }
          case 26: {
            Guid = input.ReadString();
            break;
          }
        }
      }
    }

  }

  #endregion

}

#endregion Designer generated code
