// <auto-generated>
//     Generated by the protocol buffer compiler.  DO NOT EDIT!
//     source: google/protobuf/unittest_proto3_optional.proto
// </auto-generated>
#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 ProtobufUnittest {

  /// <summary>Holder for reflection information generated from google/protobuf/unittest_proto3_optional.proto</summary>
  public static partial class UnittestProto3OptionalReflection {

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

    static UnittestProto3OptionalReflection() {
      byte[] descriptorData = global::System.Convert.FromBase64String(
          string.Concat(
            "Ci5nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zX29wdGlvbmFsLnBy",
            "b3RvEhFwcm90b2J1Zl91bml0dGVzdCKxCgoSVGVzdFByb3RvM09wdGlvbmFs",
            "EhsKDm9wdGlvbmFsX2ludDMyGAEgASgFSACIAQESGwoOb3B0aW9uYWxfaW50",
            "NjQYAiABKANIAYgBARIcCg9vcHRpb25hbF91aW50MzIYAyABKA1IAogBARIc",
            "Cg9vcHRpb25hbF91aW50NjQYBCABKARIA4gBARIcCg9vcHRpb25hbF9zaW50",
            "MzIYBSABKBFIBIgBARIcCg9vcHRpb25hbF9zaW50NjQYBiABKBJIBYgBARId",
            "ChBvcHRpb25hbF9maXhlZDMyGAcgASgHSAaIAQESHQoQb3B0aW9uYWxfZml4",
            "ZWQ2NBgIIAEoBkgHiAEBEh4KEW9wdGlvbmFsX3NmaXhlZDMyGAkgASgPSAiI",
            "AQESHgoRb3B0aW9uYWxfc2ZpeGVkNjQYCiABKBBICYgBARIbCg5vcHRpb25h",
            "bF9mbG9hdBgLIAEoAkgKiAEBEhwKD29wdGlvbmFsX2RvdWJsZRgMIAEoAUgL",
            "iAEBEhoKDW9wdGlvbmFsX2Jvb2wYDSABKAhIDIgBARIcCg9vcHRpb25hbF9z",
            "dHJpbmcYDiABKAlIDYgBARIbCg5vcHRpb25hbF9ieXRlcxgPIAEoDEgOiAEB",
            "Eh4KDW9wdGlvbmFsX2NvcmQYECABKAlCAggBSA+IAQESWQoXb3B0aW9uYWxf",
            "bmVzdGVkX21lc3NhZ2UYEiABKAsyMy5wcm90b2J1Zl91bml0dGVzdC5UZXN0",
            "UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZUgQiAEBElkKE2xhenlfbmVz",
            "dGVkX21lc3NhZ2UYEyABKAsyMy5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJv",
            "dG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZUICKAFIEYgBARJTChRvcHRpb25h",
            "bF9uZXN0ZWRfZW51bRgVIAEoDjIwLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQ",
            "cm90bzNPcHRpb25hbC5OZXN0ZWRFbnVtSBKIAQESFgoOc2luZ3VsYXJfaW50",
            "MzIYFiABKAUSFgoOc2luZ3VsYXJfaW50NjQYFyABKAMaJwoNTmVzdGVkTWVz",
            "c2FnZRIPCgJiYhgBIAEoBUgAiAEBQgUKA19iYiJKCgpOZXN0ZWRFbnVtEg8K",
            "C1VOU1BFQ0lGSUVEEAASBwoDRk9PEAESBwoDQkFSEAISBwoDQkFaEAMSEAoD",
            "TkVHEP///////////wFCEQoPX29wdGlvbmFsX2ludDMyQhEKD19vcHRpb25h",
            "bF9pbnQ2NEISChBfb3B0aW9uYWxfdWludDMyQhIKEF9vcHRpb25hbF91aW50",
            "NjRCEgoQX29wdGlvbmFsX3NpbnQzMkISChBfb3B0aW9uYWxfc2ludDY0QhMK",
            "EV9vcHRpb25hbF9maXhlZDMyQhMKEV9vcHRpb25hbF9maXhlZDY0QhQKEl9v",
            "cHRpb25hbF9zZml4ZWQzMkIUChJfb3B0aW9uYWxfc2ZpeGVkNjRCEQoPX29w",
            "dGlvbmFsX2Zsb2F0QhIKEF9vcHRpb25hbF9kb3VibGVCEAoOX29wdGlvbmFs",
            "X2Jvb2xCEgoQX29wdGlvbmFsX3N0cmluZ0IRCg9fb3B0aW9uYWxfYnl0ZXNC",
            "EAoOX29wdGlvbmFsX2NvcmRCGgoYX29wdGlvbmFsX25lc3RlZF9tZXNzYWdl",
            "QhYKFF9sYXp5X25lc3RlZF9tZXNzYWdlQhcKFV9vcHRpb25hbF9uZXN0ZWRf",
            "ZW51bUIlCiFjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG9QAWIG",
            "cHJvdG8z"));
      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
          new pbr::FileDescriptor[] { },
          new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
            new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3Optional), global::ProtobufUnittest.TestProto3Optional.Parser, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalCord", "OptionalNestedMessage", "LazyNestedMessage", "OptionalNestedEnum", "SingularInt32", "SingularInt64" }, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalCord", "OptionalNestedMessage", "LazyNestedMessage", "OptionalNestedEnum" }, new[]{ typeof(global::ProtobufUnittest.TestProto3Optional.Types.NestedEnum) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage), global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage.Parser, new[]{ "Bb" }, new[]{ "Bb" }, null, null, null)})
          }));
    }
    #endregion

  }
  #region Messages
  public sealed partial class TestProto3Optional : pb::IMessage<TestProto3Optional>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    private static readonly pb::MessageParser<TestProto3Optional> _parser = new pb::MessageParser<TestProto3Optional>(() => new TestProto3Optional());
    private pb::UnknownFieldSet _unknownFields;
    private int _hasBits0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<TestProto3Optional> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::ProtobufUnittest.UnittestProto3OptionalReflection.Descriptor.MessageTypes[0]; }
    }

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

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

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public TestProto3Optional(TestProto3Optional other) : this() {
      _hasBits0 = other._hasBits0;
      optionalInt32_ = other.optionalInt32_;
      optionalInt64_ = other.optionalInt64_;
      optionalUint32_ = other.optionalUint32_;
      optionalUint64_ = other.optionalUint64_;
      optionalSint32_ = other.optionalSint32_;
      optionalSint64_ = other.optionalSint64_;
      optionalFixed32_ = other.optionalFixed32_;
      optionalFixed64_ = other.optionalFixed64_;
      optionalSfixed32_ = other.optionalSfixed32_;
      optionalSfixed64_ = other.optionalSfixed64_;
      optionalFloat_ = other.optionalFloat_;
      optionalDouble_ = other.optionalDouble_;
      optionalBool_ = other.optionalBool_;
      optionalString_ = other.optionalString_;
      optionalBytes_ = other.optionalBytes_;
      optionalCord_ = other.optionalCord_;
      optionalNestedMessage_ = other.optionalNestedMessage_ != null ? other.optionalNestedMessage_.Clone() : null;
      lazyNestedMessage_ = other.lazyNestedMessage_ != null ? other.lazyNestedMessage_.Clone() : null;
      optionalNestedEnum_ = other.optionalNestedEnum_;
      singularInt32_ = other.singularInt32_;
      singularInt64_ = other.singularInt64_;
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

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

    /// <summary>Field number for the "optional_int32" field.</summary>
    public const int OptionalInt32FieldNumber = 1;
    private int optionalInt32_;
    /// <summary>
    /// Singular
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int OptionalInt32 {
      get { if ((_hasBits0 & 1) != 0) { return optionalInt32_; } else { return 0; } }
      set {
        _hasBits0 |= 1;
        optionalInt32_ = value;
      }
    }
    /// <summary>Gets whether the "optional_int32" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptionalInt32 {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "optional_int32" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptionalInt32() {
      _hasBits0 &= ~1;
    }

    /// <summary>Field number for the "optional_int64" field.</summary>
    public const int OptionalInt64FieldNumber = 2;
    private long optionalInt64_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public long OptionalInt64 {
      get { if ((_hasBits0 & 2) != 0) { return optionalInt64_; } else { return 0L; } }
      set {
        _hasBits0 |= 2;
        optionalInt64_ = value;
      }
    }
    /// <summary>Gets whether the "optional_int64" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptionalInt64 {
      get { return (_hasBits0 & 2) != 0; }
    }
    /// <summary>Clears the value of the "optional_int64" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptionalInt64() {
      _hasBits0 &= ~2;
    }

    /// <summary>Field number for the "optional_uint32" field.</summary>
    public const int OptionalUint32FieldNumber = 3;
    private uint optionalUint32_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public uint OptionalUint32 {
      get { if ((_hasBits0 & 4) != 0) { return optionalUint32_; } else { return 0; } }
      set {
        _hasBits0 |= 4;
        optionalUint32_ = value;
      }
    }
    /// <summary>Gets whether the "optional_uint32" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptionalUint32 {
      get { return (_hasBits0 & 4) != 0; }
    }
    /// <summary>Clears the value of the "optional_uint32" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptionalUint32() {
      _hasBits0 &= ~4;
    }

    /// <summary>Field number for the "optional_uint64" field.</summary>
    public const int OptionalUint64FieldNumber = 4;
    private ulong optionalUint64_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public ulong OptionalUint64 {
      get { if ((_hasBits0 & 8) != 0) { return optionalUint64_; } else { return 0UL; } }
      set {
        _hasBits0 |= 8;
        optionalUint64_ = value;
      }
    }
    /// <summary>Gets whether the "optional_uint64" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptionalUint64 {
      get { return (_hasBits0 & 8) != 0; }
    }
    /// <summary>Clears the value of the "optional_uint64" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptionalUint64() {
      _hasBits0 &= ~8;
    }

    /// <summary>Field number for the "optional_sint32" field.</summary>
    public const int OptionalSint32FieldNumber = 5;
    private int optionalSint32_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int OptionalSint32 {
      get { if ((_hasBits0 & 16) != 0) { return optionalSint32_; } else { return 0; } }
      set {
        _hasBits0 |= 16;
        optionalSint32_ = value;
      }
    }
    /// <summary>Gets whether the "optional_sint32" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptionalSint32 {
      get { return (_hasBits0 & 16) != 0; }
    }
    /// <summary>Clears the value of the "optional_sint32" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptionalSint32() {
      _hasBits0 &= ~16;
    }

    /// <summary>Field number for the "optional_sint64" field.</summary>
    public const int OptionalSint64FieldNumber = 6;
    private long optionalSint64_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public long OptionalSint64 {
      get { if ((_hasBits0 & 32) != 0) { return optionalSint64_; } else { return 0L; } }
      set {
        _hasBits0 |= 32;
        optionalSint64_ = value;
      }
    }
    /// <summary>Gets whether the "optional_sint64" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptionalSint64 {
      get { return (_hasBits0 & 32) != 0; }
    }
    /// <summary>Clears the value of the "optional_sint64" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptionalSint64() {
      _hasBits0 &= ~32;
    }

    /// <summary>Field number for the "optional_fixed32" field.</summary>
    public const int OptionalFixed32FieldNumber = 7;
    private uint optionalFixed32_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public uint OptionalFixed32 {
      get { if ((_hasBits0 & 64) != 0) { return optionalFixed32_; } else { return 0; } }
      set {
        _hasBits0 |= 64;
        optionalFixed32_ = value;
      }
    }
    /// <summary>Gets whether the "optional_fixed32" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptionalFixed32 {
      get { return (_hasBits0 & 64) != 0; }
    }
    /// <summary>Clears the value of the "optional_fixed32" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptionalFixed32() {
      _hasBits0 &= ~64;
    }

    /// <summary>Field number for the "optional_fixed64" field.</summary>
    public const int OptionalFixed64FieldNumber = 8;
    private ulong optionalFixed64_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public ulong OptionalFixed64 {
      get { if ((_hasBits0 & 128) != 0) { return optionalFixed64_; } else { return 0UL; } }
      set {
        _hasBits0 |= 128;
        optionalFixed64_ = value;
      }
    }
    /// <summary>Gets whether the "optional_fixed64" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptionalFixed64 {
      get { return (_hasBits0 & 128) != 0; }
    }
    /// <summary>Clears the value of the "optional_fixed64" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptionalFixed64() {
      _hasBits0 &= ~128;
    }

    /// <summary>Field number for the "optional_sfixed32" field.</summary>
    public const int OptionalSfixed32FieldNumber = 9;
    private int optionalSfixed32_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int OptionalSfixed32 {
      get { if ((_hasBits0 & 256) != 0) { return optionalSfixed32_; } else { return 0; } }
      set {
        _hasBits0 |= 256;
        optionalSfixed32_ = value;
      }
    }
    /// <summary>Gets whether the "optional_sfixed32" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptionalSfixed32 {
      get { return (_hasBits0 & 256) != 0; }
    }
    /// <summary>Clears the value of the "optional_sfixed32" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptionalSfixed32() {
      _hasBits0 &= ~256;
    }

    /// <summary>Field number for the "optional_sfixed64" field.</summary>
    public const int OptionalSfixed64FieldNumber = 10;
    private long optionalSfixed64_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public long OptionalSfixed64 {
      get { if ((_hasBits0 & 512) != 0) { return optionalSfixed64_; } else { return 0L; } }
      set {
        _hasBits0 |= 512;
        optionalSfixed64_ = value;
      }
    }
    /// <summary>Gets whether the "optional_sfixed64" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptionalSfixed64 {
      get { return (_hasBits0 & 512) != 0; }
    }
    /// <summary>Clears the value of the "optional_sfixed64" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptionalSfixed64() {
      _hasBits0 &= ~512;
    }

    /// <summary>Field number for the "optional_float" field.</summary>
    public const int OptionalFloatFieldNumber = 11;
    private float optionalFloat_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public float OptionalFloat {
      get { if ((_hasBits0 & 1024) != 0) { return optionalFloat_; } else { return 0F; } }
      set {
        _hasBits0 |= 1024;
        optionalFloat_ = value;
      }
    }
    /// <summary>Gets whether the "optional_float" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptionalFloat {
      get { return (_hasBits0 & 1024) != 0; }
    }
    /// <summary>Clears the value of the "optional_float" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptionalFloat() {
      _hasBits0 &= ~1024;
    }

    /// <summary>Field number for the "optional_double" field.</summary>
    public const int OptionalDoubleFieldNumber = 12;
    private double optionalDouble_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public double OptionalDouble {
      get { if ((_hasBits0 & 2048) != 0) { return optionalDouble_; } else { return 0D; } }
      set {
        _hasBits0 |= 2048;
        optionalDouble_ = value;
      }
    }
    /// <summary>Gets whether the "optional_double" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptionalDouble {
      get { return (_hasBits0 & 2048) != 0; }
    }
    /// <summary>Clears the value of the "optional_double" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptionalDouble() {
      _hasBits0 &= ~2048;
    }

    /// <summary>Field number for the "optional_bool" field.</summary>
    public const int OptionalBoolFieldNumber = 13;
    private bool optionalBool_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool OptionalBool {
      get { if ((_hasBits0 & 4096) != 0) { return optionalBool_; } else { return false; } }
      set {
        _hasBits0 |= 4096;
        optionalBool_ = value;
      }
    }
    /// <summary>Gets whether the "optional_bool" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptionalBool {
      get { return (_hasBits0 & 4096) != 0; }
    }
    /// <summary>Clears the value of the "optional_bool" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptionalBool() {
      _hasBits0 &= ~4096;
    }

    /// <summary>Field number for the "optional_string" field.</summary>
    public const int OptionalStringFieldNumber = 14;
    private string optionalString_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string OptionalString {
      get { return optionalString_ ?? ""; }
      set {
        optionalString_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "optional_string" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptionalString {
      get { return optionalString_ != null; }
    }
    /// <summary>Clears the value of the "optional_string" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptionalString() {
      optionalString_ = null;
    }

    /// <summary>Field number for the "optional_bytes" field.</summary>
    public const int OptionalBytesFieldNumber = 15;
    private pb::ByteString optionalBytes_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pb::ByteString OptionalBytes {
      get { return optionalBytes_ ?? pb::ByteString.Empty; }
      set {
        optionalBytes_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "optional_bytes" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptionalBytes {
      get { return optionalBytes_ != null; }
    }
    /// <summary>Clears the value of the "optional_bytes" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptionalBytes() {
      optionalBytes_ = null;
    }

    /// <summary>Field number for the "optional_cord" field.</summary>
    public const int OptionalCordFieldNumber = 16;
    private string optionalCord_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public string OptionalCord {
      get { return optionalCord_ ?? ""; }
      set {
        optionalCord_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
      }
    }
    /// <summary>Gets whether the "optional_cord" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptionalCord {
      get { return optionalCord_ != null; }
    }
    /// <summary>Clears the value of the "optional_cord" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptionalCord() {
      optionalCord_ = null;
    }

    /// <summary>Field number for the "optional_nested_message" field.</summary>
    public const int OptionalNestedMessageFieldNumber = 18;
    private global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage optionalNestedMessage_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage OptionalNestedMessage {
      get { return optionalNestedMessage_; }
      set {
        optionalNestedMessage_ = value;
      }
    }

    /// <summary>Field number for the "lazy_nested_message" field.</summary>
    public const int LazyNestedMessageFieldNumber = 19;
    private global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage lazyNestedMessage_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage LazyNestedMessage {
      get { return lazyNestedMessage_; }
      set {
        lazyNestedMessage_ = value;
      }
    }

    /// <summary>Field number for the "optional_nested_enum" field.</summary>
    public const int OptionalNestedEnumFieldNumber = 21;
    private global::ProtobufUnittest.TestProto3Optional.Types.NestedEnum optionalNestedEnum_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::ProtobufUnittest.TestProto3Optional.Types.NestedEnum OptionalNestedEnum {
      get { if ((_hasBits0 & 8192) != 0) { return optionalNestedEnum_; } else { return global::ProtobufUnittest.TestProto3Optional.Types.NestedEnum.Unspecified; } }
      set {
        _hasBits0 |= 8192;
        optionalNestedEnum_ = value;
      }
    }
    /// <summary>Gets whether the "optional_nested_enum" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool HasOptionalNestedEnum {
      get { return (_hasBits0 & 8192) != 0; }
    }
    /// <summary>Clears the value of the "optional_nested_enum" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearOptionalNestedEnum() {
      _hasBits0 &= ~8192;
    }

    /// <summary>Field number for the "singular_int32" field.</summary>
    public const int SingularInt32FieldNumber = 22;
    private int singularInt32_;
    /// <summary>
    /// Add some non-optional fields to verify we can mix them.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int SingularInt32 {
      get { return singularInt32_; }
      set {
        singularInt32_ = value;
      }
    }

    /// <summary>Field number for the "singular_int64" field.</summary>
    public const int SingularInt64FieldNumber = 23;
    private long singularInt64_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public long SingularInt64 {
      get { return singularInt64_; }
      set {
        singularInt64_ = value;
      }
    }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(TestProto3Optional other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (OptionalInt32 != other.OptionalInt32) return false;
      if (OptionalInt64 != other.OptionalInt64) return false;
      if (OptionalUint32 != other.OptionalUint32) return false;
      if (OptionalUint64 != other.OptionalUint64) return false;
      if (OptionalSint32 != other.OptionalSint32) return false;
      if (OptionalSint64 != other.OptionalSint64) return false;
      if (OptionalFixed32 != other.OptionalFixed32) return false;
      if (OptionalFixed64 != other.OptionalFixed64) return false;
      if (OptionalSfixed32 != other.OptionalSfixed32) return false;
      if (OptionalSfixed64 != other.OptionalSfixed64) return false;
      if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(OptionalFloat, other.OptionalFloat)) return false;
      if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(OptionalDouble, other.OptionalDouble)) return false;
      if (OptionalBool != other.OptionalBool) return false;
      if (OptionalString != other.OptionalString) return false;
      if (OptionalBytes != other.OptionalBytes) return false;
      if (OptionalCord != other.OptionalCord) return false;
      if (!object.Equals(OptionalNestedMessage, other.OptionalNestedMessage)) return false;
      if (!object.Equals(LazyNestedMessage, other.LazyNestedMessage)) return false;
      if (OptionalNestedEnum != other.OptionalNestedEnum) return false;
      if (SingularInt32 != other.SingularInt32) return false;
      if (SingularInt64 != other.SingularInt64) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (HasOptionalInt32) hash ^= OptionalInt32.GetHashCode();
      if (HasOptionalInt64) hash ^= OptionalInt64.GetHashCode();
      if (HasOptionalUint32) hash ^= OptionalUint32.GetHashCode();
      if (HasOptionalUint64) hash ^= OptionalUint64.GetHashCode();
      if (HasOptionalSint32) hash ^= OptionalSint32.GetHashCode();
      if (HasOptionalSint64) hash ^= OptionalSint64.GetHashCode();
      if (HasOptionalFixed32) hash ^= OptionalFixed32.GetHashCode();
      if (HasOptionalFixed64) hash ^= OptionalFixed64.GetHashCode();
      if (HasOptionalSfixed32) hash ^= OptionalSfixed32.GetHashCode();
      if (HasOptionalSfixed64) hash ^= OptionalSfixed64.GetHashCode();
      if (HasOptionalFloat) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(OptionalFloat);
      if (HasOptionalDouble) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(OptionalDouble);
      if (HasOptionalBool) hash ^= OptionalBool.GetHashCode();
      if (HasOptionalString) hash ^= OptionalString.GetHashCode();
      if (HasOptionalBytes) hash ^= OptionalBytes.GetHashCode();
      if (HasOptionalCord) hash ^= OptionalCord.GetHashCode();
      if (optionalNestedMessage_ != null) hash ^= OptionalNestedMessage.GetHashCode();
      if (lazyNestedMessage_ != null) hash ^= LazyNestedMessage.GetHashCode();
      if (HasOptionalNestedEnum) hash ^= OptionalNestedEnum.GetHashCode();
      if (SingularInt32 != 0) hash ^= SingularInt32.GetHashCode();
      if (SingularInt64 != 0L) hash ^= SingularInt64.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.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 (HasOptionalInt32) {
        output.WriteRawTag(8);
        output.WriteInt32(OptionalInt32);
      }
      if (HasOptionalInt64) {
        output.WriteRawTag(16);
        output.WriteInt64(OptionalInt64);
      }
      if (HasOptionalUint32) {
        output.WriteRawTag(24);
        output.WriteUInt32(OptionalUint32);
      }
      if (HasOptionalUint64) {
        output.WriteRawTag(32);
        output.WriteUInt64(OptionalUint64);
      }
      if (HasOptionalSint32) {
        output.WriteRawTag(40);
        output.WriteSInt32(OptionalSint32);
      }
      if (HasOptionalSint64) {
        output.WriteRawTag(48);
        output.WriteSInt64(OptionalSint64);
      }
      if (HasOptionalFixed32) {
        output.WriteRawTag(61);
        output.WriteFixed32(OptionalFixed32);
      }
      if (HasOptionalFixed64) {
        output.WriteRawTag(65);
        output.WriteFixed64(OptionalFixed64);
      }
      if (HasOptionalSfixed32) {
        output.WriteRawTag(77);
        output.WriteSFixed32(OptionalSfixed32);
      }
      if (HasOptionalSfixed64) {
        output.WriteRawTag(81);
        output.WriteSFixed64(OptionalSfixed64);
      }
      if (HasOptionalFloat) {
        output.WriteRawTag(93);
        output.WriteFloat(OptionalFloat);
      }
      if (HasOptionalDouble) {
        output.WriteRawTag(97);
        output.WriteDouble(OptionalDouble);
      }
      if (HasOptionalBool) {
        output.WriteRawTag(104);
        output.WriteBool(OptionalBool);
      }
      if (HasOptionalString) {
        output.WriteRawTag(114);
        output.WriteString(OptionalString);
      }
      if (HasOptionalBytes) {
        output.WriteRawTag(122);
        output.WriteBytes(OptionalBytes);
      }
      if (HasOptionalCord) {
        output.WriteRawTag(130, 1);
        output.WriteString(OptionalCord);
      }
      if (optionalNestedMessage_ != null) {
        output.WriteRawTag(146, 1);
        output.WriteMessage(OptionalNestedMessage);
      }
      if (lazyNestedMessage_ != null) {
        output.WriteRawTag(154, 1);
        output.WriteMessage(LazyNestedMessage);
      }
      if (HasOptionalNestedEnum) {
        output.WriteRawTag(168, 1);
        output.WriteEnum((int) OptionalNestedEnum);
      }
      if (SingularInt32 != 0) {
        output.WriteRawTag(176, 1);
        output.WriteInt32(SingularInt32);
      }
      if (SingularInt64 != 0L) {
        output.WriteRawTag(184, 1);
        output.WriteInt64(SingularInt64);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (HasOptionalInt32) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(OptionalInt32);
      }
      if (HasOptionalInt64) {
        size += 1 + pb::CodedOutputStream.ComputeInt64Size(OptionalInt64);
      }
      if (HasOptionalUint32) {
        size += 1 + pb::CodedOutputStream.ComputeUInt32Size(OptionalUint32);
      }
      if (HasOptionalUint64) {
        size += 1 + pb::CodedOutputStream.ComputeUInt64Size(OptionalUint64);
      }
      if (HasOptionalSint32) {
        size += 1 + pb::CodedOutputStream.ComputeSInt32Size(OptionalSint32);
      }
      if (HasOptionalSint64) {
        size += 1 + pb::CodedOutputStream.ComputeSInt64Size(OptionalSint64);
      }
      if (HasOptionalFixed32) {
        size += 1 + 4;
      }
      if (HasOptionalFixed64) {
        size += 1 + 8;
      }
      if (HasOptionalSfixed32) {
        size += 1 + 4;
      }
      if (HasOptionalSfixed64) {
        size += 1 + 8;
      }
      if (HasOptionalFloat) {
        size += 1 + 4;
      }
      if (HasOptionalDouble) {
        size += 1 + 8;
      }
      if (HasOptionalBool) {
        size += 1 + 1;
      }
      if (HasOptionalString) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(OptionalString);
      }
      if (HasOptionalBytes) {
        size += 1 + pb::CodedOutputStream.ComputeBytesSize(OptionalBytes);
      }
      if (HasOptionalCord) {
        size += 2 + pb::CodedOutputStream.ComputeStringSize(OptionalCord);
      }
      if (optionalNestedMessage_ != null) {
        size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalNestedMessage);
      }
      if (lazyNestedMessage_ != null) {
        size += 2 + pb::CodedOutputStream.ComputeMessageSize(LazyNestedMessage);
      }
      if (HasOptionalNestedEnum) {
        size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OptionalNestedEnum);
      }
      if (SingularInt32 != 0) {
        size += 2 + pb::CodedOutputStream.ComputeInt32Size(SingularInt32);
      }
      if (SingularInt64 != 0L) {
        size += 2 + pb::CodedOutputStream.ComputeInt64Size(SingularInt64);
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(TestProto3Optional other) {
      if (other == null) {
        return;
      }
      if (other.HasOptionalInt32) {
        OptionalInt32 = other.OptionalInt32;
      }
      if (other.HasOptionalInt64) {
        OptionalInt64 = other.OptionalInt64;
      }
      if (other.HasOptionalUint32) {
        OptionalUint32 = other.OptionalUint32;
      }
      if (other.HasOptionalUint64) {
        OptionalUint64 = other.OptionalUint64;
      }
      if (other.HasOptionalSint32) {
        OptionalSint32 = other.OptionalSint32;
      }
      if (other.HasOptionalSint64) {
        OptionalSint64 = other.OptionalSint64;
      }
      if (other.HasOptionalFixed32) {
        OptionalFixed32 = other.OptionalFixed32;
      }
      if (other.HasOptionalFixed64) {
        OptionalFixed64 = other.OptionalFixed64;
      }
      if (other.HasOptionalSfixed32) {
        OptionalSfixed32 = other.OptionalSfixed32;
      }
      if (other.HasOptionalSfixed64) {
        OptionalSfixed64 = other.OptionalSfixed64;
      }
      if (other.HasOptionalFloat) {
        OptionalFloat = other.OptionalFloat;
      }
      if (other.HasOptionalDouble) {
        OptionalDouble = other.OptionalDouble;
      }
      if (other.HasOptionalBool) {
        OptionalBool = other.OptionalBool;
      }
      if (other.HasOptionalString) {
        OptionalString = other.OptionalString;
      }
      if (other.HasOptionalBytes) {
        OptionalBytes = other.OptionalBytes;
      }
      if (other.HasOptionalCord) {
        OptionalCord = other.OptionalCord;
      }
      if (other.optionalNestedMessage_ != null) {
        if (optionalNestedMessage_ == null) {
          OptionalNestedMessage = new global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage();
        }
        OptionalNestedMessage.MergeFrom(other.OptionalNestedMessage);
      }
      if (other.lazyNestedMessage_ != null) {
        if (lazyNestedMessage_ == null) {
          LazyNestedMessage = new global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage();
        }
        LazyNestedMessage.MergeFrom(other.LazyNestedMessage);
      }
      if (other.HasOptionalNestedEnum) {
        OptionalNestedEnum = other.OptionalNestedEnum;
      }
      if (other.SingularInt32 != 0) {
        SingularInt32 = other.SingularInt32;
      }
      if (other.SingularInt64 != 0L) {
        SingularInt64 = other.SingularInt64;
      }
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 8: {
            OptionalInt32 = input.ReadInt32();
            break;
          }
          case 16: {
            OptionalInt64 = input.ReadInt64();
            break;
          }
          case 24: {
            OptionalUint32 = input.ReadUInt32();
            break;
          }
          case 32: {
            OptionalUint64 = input.ReadUInt64();
            break;
          }
          case 40: {
            OptionalSint32 = input.ReadSInt32();
            break;
          }
          case 48: {
            OptionalSint64 = input.ReadSInt64();
            break;
          }
          case 61: {
            OptionalFixed32 = input.ReadFixed32();
            break;
          }
          case 65: {
            OptionalFixed64 = input.ReadFixed64();
            break;
          }
          case 77: {
            OptionalSfixed32 = input.ReadSFixed32();
            break;
          }
          case 81: {
            OptionalSfixed64 = input.ReadSFixed64();
            break;
          }
          case 93: {
            OptionalFloat = input.ReadFloat();
            break;
          }
          case 97: {
            OptionalDouble = input.ReadDouble();
            break;
          }
          case 104: {
            OptionalBool = input.ReadBool();
            break;
          }
          case 114: {
            OptionalString = input.ReadString();
            break;
          }
          case 122: {
            OptionalBytes = input.ReadBytes();
            break;
          }
          case 130: {
            OptionalCord = input.ReadString();
            break;
          }
          case 146: {
            if (optionalNestedMessage_ == null) {
              OptionalNestedMessage = new global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage();
            }
            input.ReadMessage(OptionalNestedMessage);
            break;
          }
          case 154: {
            if (lazyNestedMessage_ == null) {
              LazyNestedMessage = new global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage();
            }
            input.ReadMessage(LazyNestedMessage);
            break;
          }
          case 168: {
            OptionalNestedEnum = (global::ProtobufUnittest.TestProto3Optional.Types.NestedEnum) input.ReadEnum();
            break;
          }
          case 176: {
            SingularInt32 = input.ReadInt32();
            break;
          }
          case 184: {
            SingularInt64 = input.ReadInt64();
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
        switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            break;
          case 8: {
            OptionalInt32 = input.ReadInt32();
            break;
          }
          case 16: {
            OptionalInt64 = input.ReadInt64();
            break;
          }
          case 24: {
            OptionalUint32 = input.ReadUInt32();
            break;
          }
          case 32: {
            OptionalUint64 = input.ReadUInt64();
            break;
          }
          case 40: {
            OptionalSint32 = input.ReadSInt32();
            break;
          }
          case 48: {
            OptionalSint64 = input.ReadSInt64();
            break;
          }
          case 61: {
            OptionalFixed32 = input.ReadFixed32();
            break;
          }
          case 65: {
            OptionalFixed64 = input.ReadFixed64();
            break;
          }
          case 77: {
            OptionalSfixed32 = input.ReadSFixed32();
            break;
          }
          case 81: {
            OptionalSfixed64 = input.ReadSFixed64();
            break;
          }
          case 93: {
            OptionalFloat = input.ReadFloat();
            break;
          }
          case 97: {
            OptionalDouble = input.ReadDouble();
            break;
          }
          case 104: {
            OptionalBool = input.ReadBool();
            break;
          }
          case 114: {
            OptionalString = input.ReadString();
            break;
          }
          case 122: {
            OptionalBytes = input.ReadBytes();
            break;
          }
          case 130: {
            OptionalCord = input.ReadString();
            break;
          }
          case 146: {
            if (optionalNestedMessage_ == null) {
              OptionalNestedMessage = new global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage();
            }
            input.ReadMessage(OptionalNestedMessage);
            break;
          }
          case 154: {
            if (lazyNestedMessage_ == null) {
              LazyNestedMessage = new global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage();
            }
            input.ReadMessage(LazyNestedMessage);
            break;
          }
          case 168: {
            OptionalNestedEnum = (global::ProtobufUnittest.TestProto3Optional.Types.NestedEnum) input.ReadEnum();
            break;
          }
          case 176: {
            SingularInt32 = input.ReadInt32();
            break;
          }
          case 184: {
            SingularInt64 = input.ReadInt64();
            break;
          }
        }
      }
    }
    #endif

    #region Nested types
    /// <summary>Container for nested types declared in the TestProto3Optional message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static partial class Types {
      public enum NestedEnum {
        [pbr::OriginalName("UNSPECIFIED")] Unspecified = 0,
        [pbr::OriginalName("FOO")] Foo = 1,
        [pbr::OriginalName("BAR")] Bar = 2,
        [pbr::OriginalName("BAZ")] Baz = 3,
        /// <summary>
        /// Intentionally negative.
        /// </summary>
        [pbr::OriginalName("NEG")] Neg = -1,
      }

      public sealed partial class NestedMessage : pb::IMessage<NestedMessage>
      #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          , pb::IBufferMessage
      #endif
      {
        private static readonly pb::MessageParser<NestedMessage> _parser = new pb::MessageParser<NestedMessage>(() => new NestedMessage());
        private pb::UnknownFieldSet _unknownFields;
        private int _hasBits0;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public static pb::MessageParser<NestedMessage> Parser { get { return _parser; } }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public static pbr::MessageDescriptor Descriptor {
          get { return global::ProtobufUnittest.TestProto3Optional.Descriptor.NestedTypes[0]; }
        }

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

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

        partial void OnConstruction();

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public NestedMessage(NestedMessage other) : this() {
          _hasBits0 = other._hasBits0;
          bb_ = other.bb_;
          _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
        }

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

        /// <summary>Field number for the "bb" field.</summary>
        public const int BbFieldNumber = 1;
        private int bb_;
        /// <summary>
        /// The field name "b" fails to compile in proto1 because it conflicts with
        /// a local variable named "b" in one of the generated methods.  Doh.
        /// This file needs to compile in proto1 to test backwards-compatibility.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int Bb {
          get { if ((_hasBits0 & 1) != 0) { return bb_; } else { return 0; } }
          set {
            _hasBits0 |= 1;
            bb_ = value;
          }
        }
        /// <summary>Gets whether the "bb" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public bool HasBb {
          get { return (_hasBits0 & 1) != 0; }
        }
        /// <summary>Clears the value of the "bb" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void ClearBb() {
          _hasBits0 &= ~1;
        }

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

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

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public override int GetHashCode() {
          int hash = 1;
          if (HasBb) hash ^= Bb.GetHashCode();
          if (_unknownFields != null) {
            hash ^= _unknownFields.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 (HasBb) {
            output.WriteRawTag(8);
            output.WriteInt32(Bb);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(output);
          }
        }

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

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void MergeFrom(NestedMessage other) {
          if (other == null) {
            return;
          }
          if (other.HasBb) {
            Bb = other.Bb;
          }
          _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public void MergeFrom(pb::CodedInputStream input) {
        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          input.ReadRawMessage(this);
        #else
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
            switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                break;
              case 8: {
                Bb = input.ReadInt32();
                break;
              }
            }
          }
        #endif
        }

        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
            switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
                break;
              case 8: {
                Bb = input.ReadInt32();
                break;
              }
            }
          }
        }
        #endif

      }

    }
    #endregion

  }

  #endregion

}

#endregion Designer generated code
