// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: unittest_custom_options_proto3.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_custom_options_proto3.proto</summary>
  public static partial class UnittestCustomOptionsProto3Reflection {

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

    static UnittestCustomOptionsProto3Reflection() {
      byte[] descriptorData = global::System.Convert.FromBase64String(
          string.Concat(
            "CiR1bml0dGVzdF9jdXN0b21fb3B0aW9uc19wcm90bzMucHJvdG8SEXByb3Rv",
            "YnVmX3VuaXR0ZXN0GiBnb29nbGUvcHJvdG9idWYvZGVzY3JpcHRvci5wcm90",
            "byLXAQocVGVzdE1lc3NhZ2VXaXRoQ3VzdG9tT3B0aW9ucxIeCgZmaWVsZDEY",
            "ASABKAlCDggBweDDHS3hdQoCAAAAEhUKC29uZW9mX2ZpZWxkGAIgASgFSAAi",
            "UwoGQW5FbnVtEhYKEkFORU5VTV9VTlNQRUNJRklFRBAAEg8KC0FORU5VTV9W",
            "QUwxEAESFgoLQU5FTlVNX1ZBTDIQAhoFsIb6BXsaCMX2yR3r/P//OhAIAODp",
            "wh3I//////////8BQhkKB0FuT25lb2YSDviswx2d//////////8BIhgKFkN1",
            "c3RvbU9wdGlvbkZvb1JlcXVlc3QiGQoXQ3VzdG9tT3B0aW9uRm9vUmVzcG9u",
            "c2UiHgocQ3VzdG9tT3B0aW9uRm9vQ2xpZW50TWVzc2FnZSIeChxDdXN0b21P",
            "cHRpb25Gb29TZXJ2ZXJNZXNzYWdlIo8BChpEdW1teU1lc3NhZ2VDb250YWlu",
            "aW5nRW51bSJxCgxUZXN0RW51bVR5cGUSIAocVEVTVF9PUFRJT05fRU5VTV9V",
            "TlNQRUNJRklFRBAAEhoKFlRFU1RfT1BUSU9OX0VOVU1fVFlQRTEQFhIjChZU",
            "RVNUX09QVElPTl9FTlVNX1RZUEUyEOn//////////wEiIQofRHVtbXlNZXNz",
            "YWdlSW52YWxpZEFzT3B0aW9uVHlwZSKKAQocQ3VzdG9tT3B0aW9uTWluSW50",
            "ZWdlclZhbHVlczpq0N6yHQDoxrIdgICAgPj/////AbC8sh2AgICAgICAgIAB",
            "gJOyHQD49bAdAIDEsB3/////D/iXsB3///////////8BnfWvHQAAAACR7q8d",
            "AAAAAAAAAACtja8dAAAAgJnWqB0AAAAAAAAAgCKRAQocQ3VzdG9tT3B0aW9u",
            "TWF4SW50ZWdlclZhbHVlczpx0N6yHQHoxrId/////wewvLId//////////9/",
            "gJOyHf////8P+PWwHf///////////wGAxLAd/v///w/4l7Ad/v//////////",
            "AZ31rx3/////ke6vHf//////////rY2vHf///3+Z1qgd/////////38ibgoX",
            "Q3VzdG9tT3B0aW9uT3RoZXJWYWx1ZXM6U+jGsh2c//////////8B9d+jHeeH",
            "RUHp3KId+1mMQsrA8z+q3KIdDkhlbGxvLCAiV29ybGQistmiHQtIZWxsbwBX",
            "b3JsZIjZoh3p//////////8BIjQKHFNldHRpbmdSZWFsc0Zyb21Qb3NpdGl2",
            "ZUludHM6FPXfox0AAEBB6dyiHQAAAAAAQGNAIjQKHFNldHRpbmdSZWFsc0Zy",
            "b21OZWdhdGl2ZUludHM6FPXfox0AAEDB6dyiHQAAAAAAQGPAIksKEkNvbXBs",
            "ZXhPcHRpb25UeXBlMRILCgNmb28YASABKAUSDAoEZm9vMhgCIAEoBRIMCgRm",
            "b28zGAMgASgFEgwKBGZvbzQYBCADKAUigQMKEkNvbXBsZXhPcHRpb25UeXBl",
            "MhIyCgNiYXIYASABKAsyJS5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0",
            "aW9uVHlwZTESCwoDYmF6GAIgASgFEkYKBGZyZWQYAyABKAsyOC5wcm90b2J1",
            "Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5",
            "cGU0EkgKBmJhcm5leRgEIAMoCzI4LnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBs",
            "ZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0aW9uVHlwZTQalwEKEkNvbXBsZXhP",
            "cHRpb25UeXBlNBINCgV3YWxkbxgBIAEoBTJyCgxjb21wbGV4X29wdDQSHy5n",
            "b29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYivXRAyABKAsyOC5wcm90",
            "b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTIuQ29tcGxleE9wdGlv",
            "blR5cGU0IiEKEkNvbXBsZXhPcHRpb25UeXBlMxILCgNxdXgYASABKAUibAoV",
            "VmFyaW91c0NvbXBsZXhPcHRpb25zOlOi4pUdAggqouKVHQIgY6LilR0CIFiq",
            "/ZAdAxDbB6r9kB0FCgMI5wXSqI8dAwizD6r9kB0FGgMIwQKq/ZAdBCICCGWq",
            "/ZAdBSIDCNQB+t6QHQIICSJMCglBZ2dyZWdhdGUSCQoBaRgBIAEoBRIJCgFz",
            "GAIgASgJEikKA3N1YhgDIAEoCzIcLnByb3RvYnVmX3VuaXR0ZXN0LkFnZ3Jl",
            "Z2F0ZSJZChBBZ2dyZWdhdGVNZXNzYWdlEikKCWZpZWxkbmFtZRgBIAEoBUIW",
            "8qGHOxESD0ZpZWxkQW5ub3RhdGlvbjoawtGGOxUIZRIRTWVzc2FnZUFubm90",
            "YXRpb24ilwEKEE5lc3RlZE9wdGlvblR5cGUaOwoNTmVzdGVkTWVzc2FnZRIi",
            "CgxuZXN0ZWRfZmllbGQYASABKAVCDMHgwx3qAwAAAAAAADoG4OnCHekHIkYK",
            "Ck5lc3RlZEVudW0SDwoLVU5TUEVDSUZJRUQQABIdChFORVNURURfRU5VTV9W",
            "QUxVRRABGgawhvoF7AcaCMX2yR3rAwAAKlIKCk1ldGhvZE9wdDESGgoWTUVU",
            "SE9ET1BUMV9VTlNQRUNJRklFRBAAEhMKD01FVEhPRE9QVDFfVkFMMRABEhMK",
            "D01FVEhPRE9QVDFfVkFMMhACKl4KDUFnZ3JlZ2F0ZUVudW0SDwoLVU5TUEVD",
            "SUZJRUQQABIlCgVWQUxVRRABGhrK/Ik7FRITRW51bVZhbHVlQW5ub3RhdGlv",
            "bhoVkpWIOxASDkVudW1Bbm5vdGF0aW9uMo4BChxUZXN0U2VydmljZVdpdGhD",
            "dXN0b21PcHRpb25zEmMKA0ZvbxIpLnByb3RvYnVmX3VuaXR0ZXN0LkN1c3Rv",
            "bU9wdGlvbkZvb1JlcXVlc3QaKi5wcm90b2J1Zl91bml0dGVzdC5DdXN0b21P",
            "cHRpb25Gb29SZXNwb25zZSIF4PqMHgIaCZCyix7T24DLSTKZAQoQQWdncmVn",
            "YXRlU2VydmljZRJrCgZNZXRob2QSIy5wcm90b2J1Zl91bml0dGVzdC5BZ2dy",
            "ZWdhdGVNZXNzYWdlGiMucHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlTWVz",
            "c2FnZSIXysiWOxISEE1ldGhvZEFubm90YXRpb24aGMr7jjsTEhFTZXJ2aWNl",
            "QW5ub3RhdGlvbjoyCglmaWxlX29wdDESHC5nb29nbGUucHJvdG9idWYuRmls",
            "ZU9wdGlvbnMYjp3YAyABKAQ6OAoMbWVzc2FnZV9vcHQxEh8uZ29vZ2xlLnBy",
            "b3RvYnVmLk1lc3NhZ2VPcHRpb25zGJyt2AMgASgFOjQKCmZpZWxkX29wdDES",
            "HS5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25zGIi82AMgASgGOjQKCm9u",
            "ZW9mX29wdDESHS5nb29nbGUucHJvdG9idWYuT25lb2ZPcHRpb25zGM+12AMg",
            "ASgFOjIKCWVudW1fb3B0MRIcLmdvb2dsZS5wcm90b2J1Zi5FbnVtT3B0aW9u",
            "cxjontkDIAEoDzo8Cg9lbnVtX3ZhbHVlX29wdDESIS5nb29nbGUucHJvdG9i",
            "dWYuRW51bVZhbHVlT3B0aW9ucxjmoF8gASgFOjgKDHNlcnZpY2Vfb3B0MRIf",
            "Lmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0aW9ucxiituEDIAEoEjpVCgtt",
            "ZXRob2Rfb3B0MRIeLmdvb2dsZS5wcm90b2J1Zi5NZXRob2RPcHRpb25zGKzP",
            "4QMgASgOMh0ucHJvdG9idWZfdW5pdHRlc3QuTWV0aG9kT3B0MTo0Cghib29s",
            "X29wdBIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxjqq9YDIAEo",
            "CDo1CglpbnQzMl9vcHQSHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlv",
            "bnMY7ajWAyABKAU6NQoJaW50NjRfb3B0Eh8uZ29vZ2xlLnByb3RvYnVmLk1l",
            "c3NhZ2VPcHRpb25zGMan1gMgASgDOjYKCnVpbnQzMl9vcHQSHy5nb29nbGUu",
            "cHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYsKLWAyABKA06NgoKdWludDY0X29w",
            "dBIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxjfjtYDIAEoBDo2",
            "CgpzaW50MzJfb3B0Eh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25z",
            "GMCI1gMgASgROjYKCnNpbnQ2NF9vcHQSHy5nb29nbGUucHJvdG9idWYuTWVz",
            "c2FnZU9wdGlvbnMY/4LWAyABKBI6NwoLZml4ZWQzMl9vcHQSHy5nb29nbGUu",
            "cHJvdG9idWYuTWVzc2FnZU9wdGlvbnMY0/7VAyABKAc6NwoLZml4ZWQ2NF9v",
            "cHQSHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMY4v3VAyABKAY6",
            "OAoMc2ZpeGVkMzJfb3B0Eh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRp",
            "b25zGNXx1QMgASgPOjgKDHNmaXhlZDY0X29wdBIfLmdvb2dsZS5wcm90b2J1",
            "Zi5NZXNzYWdlT3B0aW9ucxjjitUDIAEoEDo1CglmbG9hdF9vcHQSHy5nb29n",
            "bGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMY/rvUAyABKAI6NgoKZG91Ymxl",
            "X29wdBIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxjNq9QDIAEo",
            "ATo2CgpzdHJpbmdfb3B0Eh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRp",
            "b25zGMWr1AMgASgJOjUKCWJ5dGVzX29wdBIfLmdvb2dsZS5wcm90b2J1Zi5N",
            "ZXNzYWdlT3B0aW9ucxiWq9QDIAEoDDpwCghlbnVtX29wdBIfLmdvb2dsZS5w",
            "cm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiRq9QDIAEoDjI6LnByb3RvYnVmX3Vu",
            "aXR0ZXN0LkR1bW15TWVzc2FnZUNvbnRhaW5pbmdFbnVtLlRlc3RFbnVtVHlw",
            "ZTpwChBtZXNzYWdlX3R5cGVfb3B0Eh8uZ29vZ2xlLnByb3RvYnVmLk1lc3Nh",
            "Z2VPcHRpb25zGK/y0wMgASgLMjIucHJvdG9idWZfdW5pdHRlc3QuRHVtbXlN",
            "ZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZTpfCgxjb21wbGV4X29wdDESHy5n",
            "b29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYpNzSAyABKAsyJS5wcm90",
            "b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTE6XwoMY29tcGxleF9v",
            "cHQyEh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGNWP0gMgASgL",
            "MiUucHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUyOl8KDGNv",
            "bXBsZXhfb3B0MxIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxjv",
            "i9IDIAEoCzIlLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBl",
            "MzpOCgdmaWxlb3B0EhwuZ29vZ2xlLnByb3RvYnVmLkZpbGVPcHRpb25zGM/d",
            "sAcgASgLMhwucHJvdG9idWZfdW5pdHRlc3QuQWdncmVnYXRlOlAKBm1zZ29w",
            "dBIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiY6rAHIAEoCzIc",
            "LnByb3RvYnVmX3VuaXR0ZXN0LkFnZ3JlZ2F0ZTpQCghmaWVsZG9wdBIdLmdv",
            "b2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMYnvSwByABKAsyHC5wcm90b2J1",
            "Zl91bml0dGVzdC5BZ2dyZWdhdGU6TgoHZW51bW9wdBIcLmdvb2dsZS5wcm90",
            "b2J1Zi5FbnVtT3B0aW9ucxjSgrEHIAEoCzIcLnByb3RvYnVmX3VuaXR0ZXN0",
            "LkFnZ3JlZ2F0ZTpWCgplbnVtdmFsb3B0EiEuZ29vZ2xlLnByb3RvYnVmLkVu",
            "dW1WYWx1ZU9wdGlvbnMYyZ+xByABKAsyHC5wcm90b2J1Zl91bml0dGVzdC5B",
            "Z2dyZWdhdGU6VAoKc2VydmljZW9wdBIfLmdvb2dsZS5wcm90b2J1Zi5TZXJ2",
            "aWNlT3B0aW9ucxi577EHIAEoCzIcLnByb3RvYnVmX3VuaXR0ZXN0LkFnZ3Jl",
            "Z2F0ZTpSCgltZXRob2RvcHQSHi5nb29nbGUucHJvdG9idWYuTWV0aG9kT3B0",
            "aW9ucxiJ6bIHIAEoCzIcLnByb3RvYnVmX3VuaXR0ZXN0LkFnZ3JlZ2F0ZUJV",
            "qgIaVW5pdFRlc3QuSXNzdWVzLlRlc3RQcm90b3Pw6MEd6q3A5ST67IU7Kghk",
            "Eg5GaWxlQW5ub3RhdGlvbhoWEhROZXN0ZWRGaWxlQW5ub3RhdGlvbmIGcHJv",
            "dG8z"));
      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
          new pbr::FileDescriptor[] { pbr::FileDescriptor.DescriptorProtoFileDescriptor, },
          new pbr::GeneratedClrTypeInfo(new[] {typeof(global::UnitTest.Issues.TestProtos.MethodOpt1), typeof(global::UnitTest.Issues.TestProtos.AggregateEnum), }, new pbr::GeneratedClrTypeInfo[] {
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.TestMessageWithCustomOptions), global::UnitTest.Issues.TestProtos.TestMessageWithCustomOptions.Parser, new[]{ "Field1", "OneofField" }, new[]{ "AnOneof" }, new[]{ typeof(global::UnitTest.Issues.TestProtos.TestMessageWithCustomOptions.Types.AnEnum) }, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.CustomOptionFooRequest), global::UnitTest.Issues.TestProtos.CustomOptionFooRequest.Parser, null, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.CustomOptionFooResponse), global::UnitTest.Issues.TestProtos.CustomOptionFooResponse.Parser, null, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.CustomOptionFooClientMessage), global::UnitTest.Issues.TestProtos.CustomOptionFooClientMessage.Parser, null, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.CustomOptionFooServerMessage), global::UnitTest.Issues.TestProtos.CustomOptionFooServerMessage.Parser, null, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.DummyMessageContainingEnum), global::UnitTest.Issues.TestProtos.DummyMessageContainingEnum.Parser, null, null, new[]{ typeof(global::UnitTest.Issues.TestProtos.DummyMessageContainingEnum.Types.TestEnumType) }, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.DummyMessageInvalidAsOptionType), global::UnitTest.Issues.TestProtos.DummyMessageInvalidAsOptionType.Parser, null, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.CustomOptionMinIntegerValues), global::UnitTest.Issues.TestProtos.CustomOptionMinIntegerValues.Parser, null, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.CustomOptionMaxIntegerValues), global::UnitTest.Issues.TestProtos.CustomOptionMaxIntegerValues.Parser, null, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.CustomOptionOtherValues), global::UnitTest.Issues.TestProtos.CustomOptionOtherValues.Parser, null, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.SettingRealsFromPositiveInts), global::UnitTest.Issues.TestProtos.SettingRealsFromPositiveInts.Parser, null, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.SettingRealsFromNegativeInts), global::UnitTest.Issues.TestProtos.SettingRealsFromNegativeInts.Parser, null, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ComplexOptionType1), global::UnitTest.Issues.TestProtos.ComplexOptionType1.Parser, new[]{ "Foo", "Foo2", "Foo3", "Foo4" }, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ComplexOptionType2), global::UnitTest.Issues.TestProtos.ComplexOptionType2.Parser, new[]{ "Bar", "Baz", "Fred", "Barney" }, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ComplexOptionType2.Types.ComplexOptionType4), global::UnitTest.Issues.TestProtos.ComplexOptionType2.Types.ComplexOptionType4.Parser, new[]{ "Waldo" }, null, null, null)}),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.ComplexOptionType3), global::UnitTest.Issues.TestProtos.ComplexOptionType3.Parser, new[]{ "Qux" }, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.VariousComplexOptions), global::UnitTest.Issues.TestProtos.VariousComplexOptions.Parser, null, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.Aggregate), global::UnitTest.Issues.TestProtos.Aggregate.Parser, new[]{ "I", "S", "Sub" }, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.AggregateMessage), global::UnitTest.Issues.TestProtos.AggregateMessage.Parser, new[]{ "Fieldname" }, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.NestedOptionType), global::UnitTest.Issues.TestProtos.NestedOptionType.Parser, null, null, new[]{ typeof(global::UnitTest.Issues.TestProtos.NestedOptionType.Types.NestedEnum) }, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::UnitTest.Issues.TestProtos.NestedOptionType.Types.NestedMessage), global::UnitTest.Issues.TestProtos.NestedOptionType.Types.NestedMessage.Parser, new[]{ "NestedField" }, null, null, null)})
          }));
    }
    #endregion

  }
  #region Enums
  public enum MethodOpt1 {
    [pbr::OriginalName("METHODOPT1_UNSPECIFIED")] Unspecified = 0,
    [pbr::OriginalName("METHODOPT1_VAL1")] Val1 = 1,
    [pbr::OriginalName("METHODOPT1_VAL2")] Val2 = 2,
  }

  public enum AggregateEnum {
    [pbr::OriginalName("UNSPECIFIED")] Unspecified = 0,
    [pbr::OriginalName("VALUE")] Value = 1,
  }

  #endregion

  #region Messages
  /// <summary>
  /// A test message with custom options at all possible locations (and also some
  /// regular options, to make sure they interact nicely).
  /// </summary>
  public sealed partial class TestMessageWithCustomOptions : pb::IMessage<TestMessageWithCustomOptions> {
    private static readonly pb::MessageParser<TestMessageWithCustomOptions> _parser = new pb::MessageParser<TestMessageWithCustomOptions>(() => new TestMessageWithCustomOptions());
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<TestMessageWithCustomOptions> Parser { get { return _parser; } }

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

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

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

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public TestMessageWithCustomOptions(TestMessageWithCustomOptions other) : this() {
      field1_ = other.field1_;
      switch (other.AnOneofCase) {
        case AnOneofOneofCase.OneofField:
          OneofField = other.OneofField;
          break;
      }

    }

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

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

    /// <summary>Field number for the "oneof_field" field.</summary>
    public const int OneofFieldFieldNumber = 2;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int OneofField {
      get { return anOneofCase_ == AnOneofOneofCase.OneofField ? (int) anOneof_ : 0; }
      set {
        anOneof_ = value;
        anOneofCase_ = AnOneofOneofCase.OneofField;
      }
    }

    private object anOneof_;
    /// <summary>Enum of possible cases for the "AnOneof" oneof.</summary>
    public enum AnOneofOneofCase {
      None = 0,
      OneofField = 2,
    }
    private AnOneofOneofCase anOneofCase_ = AnOneofOneofCase.None;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public AnOneofOneofCase AnOneofCase {
      get { return anOneofCase_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void ClearAnOneof() {
      anOneofCase_ = AnOneofOneofCase.None;
      anOneof_ = null;
    }

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

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (Field1.Length != 0) hash ^= Field1.GetHashCode();
      if (anOneofCase_ == AnOneofOneofCase.OneofField) hash ^= OneofField.GetHashCode();
      hash ^= (int) anOneofCase_;
      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 (Field1.Length != 0) {
        output.WriteRawTag(10);
        output.WriteString(Field1);
      }
      if (anOneofCase_ == AnOneofOneofCase.OneofField) {
        output.WriteRawTag(16);
        output.WriteInt32(OneofField);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (Field1.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Field1);
      }
      if (anOneofCase_ == AnOneofOneofCase.OneofField) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(OneofField);
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(TestMessageWithCustomOptions other) {
      if (other == null) {
        return;
      }
      if (other.Field1.Length != 0) {
        Field1 = other.Field1;
      }
      switch (other.AnOneofCase) {
        case AnOneofOneofCase.OneofField:
          OneofField = other.OneofField;
          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: {
            Field1 = input.ReadString();
            break;
          }
          case 16: {
            OneofField = input.ReadInt32();
            break;
          }
        }
      }
    }

    #region Nested types
    /// <summary>Container for nested types declared in the TestMessageWithCustomOptions message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static partial class Types {
      public enum AnEnum {
        [pbr::OriginalName("ANENUM_UNSPECIFIED")] Unspecified = 0,
        [pbr::OriginalName("ANENUM_VAL1")] Val1 = 1,
        [pbr::OriginalName("ANENUM_VAL2")] Val2 = 2,
      }

    }
    #endregion

  }

  /// <summary>
  /// A test RPC service with custom options at all possible locations (and also
  /// some regular options, to make sure they interact nicely).
  /// </summary>
  public sealed partial class CustomOptionFooRequest : pb::IMessage<CustomOptionFooRequest> {
    private static readonly pb::MessageParser<CustomOptionFooRequest> _parser = new pb::MessageParser<CustomOptionFooRequest>(() => new CustomOptionFooRequest());
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<CustomOptionFooRequest> Parser { get { return _parser; } }

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

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

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

    partial void OnConstruction();

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

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

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(CustomOptionFooRequest 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(CustomOptionFooRequest 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 CustomOptionFooResponse : pb::IMessage<CustomOptionFooResponse> {
    private static readonly pb::MessageParser<CustomOptionFooResponse> _parser = new pb::MessageParser<CustomOptionFooResponse>(() => new CustomOptionFooResponse());
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<CustomOptionFooResponse> Parser { get { return _parser; } }

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

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

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

    partial void OnConstruction();

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

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

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(CustomOptionFooResponse 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(CustomOptionFooResponse 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 CustomOptionFooClientMessage : pb::IMessage<CustomOptionFooClientMessage> {
    private static readonly pb::MessageParser<CustomOptionFooClientMessage> _parser = new pb::MessageParser<CustomOptionFooClientMessage>(() => new CustomOptionFooClientMessage());
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<CustomOptionFooClientMessage> Parser { get { return _parser; } }

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

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

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

    partial void OnConstruction();

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

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

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(CustomOptionFooClientMessage 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(CustomOptionFooClientMessage 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 CustomOptionFooServerMessage : pb::IMessage<CustomOptionFooServerMessage> {
    private static readonly pb::MessageParser<CustomOptionFooServerMessage> _parser = new pb::MessageParser<CustomOptionFooServerMessage>(() => new CustomOptionFooServerMessage());
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<CustomOptionFooServerMessage> Parser { get { return _parser; } }

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

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

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

    partial void OnConstruction();

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

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

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(CustomOptionFooServerMessage 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(CustomOptionFooServerMessage 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 DummyMessageContainingEnum : pb::IMessage<DummyMessageContainingEnum> {
    private static readonly pb::MessageParser<DummyMessageContainingEnum> _parser = new pb::MessageParser<DummyMessageContainingEnum>(() => new DummyMessageContainingEnum());
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<DummyMessageContainingEnum> Parser { get { return _parser; } }

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

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

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

    partial void OnConstruction();

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

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

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(DummyMessageContainingEnum 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(DummyMessageContainingEnum 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 DummyMessageContainingEnum message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static partial class Types {
      public enum TestEnumType {
        [pbr::OriginalName("TEST_OPTION_ENUM_UNSPECIFIED")] TestOptionEnumUnspecified = 0,
        [pbr::OriginalName("TEST_OPTION_ENUM_TYPE1")] TestOptionEnumType1 = 22,
        [pbr::OriginalName("TEST_OPTION_ENUM_TYPE2")] TestOptionEnumType2 = -23,
      }

    }
    #endregion

  }

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

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

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

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

    partial void OnConstruction();

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

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

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(DummyMessageInvalidAsOptionType 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(DummyMessageInvalidAsOptionType 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 CustomOptionMinIntegerValues : pb::IMessage<CustomOptionMinIntegerValues> {
    private static readonly pb::MessageParser<CustomOptionMinIntegerValues> _parser = new pb::MessageParser<CustomOptionMinIntegerValues>(() => new CustomOptionMinIntegerValues());
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<CustomOptionMinIntegerValues> Parser { get { return _parser; } }

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

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

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

    partial void OnConstruction();

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

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

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(CustomOptionMinIntegerValues 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(CustomOptionMinIntegerValues 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 CustomOptionMaxIntegerValues : pb::IMessage<CustomOptionMaxIntegerValues> {
    private static readonly pb::MessageParser<CustomOptionMaxIntegerValues> _parser = new pb::MessageParser<CustomOptionMaxIntegerValues>(() => new CustomOptionMaxIntegerValues());
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<CustomOptionMaxIntegerValues> Parser { get { return _parser; } }

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

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

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

    partial void OnConstruction();

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

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

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(CustomOptionMaxIntegerValues 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(CustomOptionMaxIntegerValues 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 CustomOptionOtherValues : pb::IMessage<CustomOptionOtherValues> {
    private static readonly pb::MessageParser<CustomOptionOtherValues> _parser = new pb::MessageParser<CustomOptionOtherValues>(() => new CustomOptionOtherValues());
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<CustomOptionOtherValues> Parser { get { return _parser; } }

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

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

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

    partial void OnConstruction();

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

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

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(CustomOptionOtherValues 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(CustomOptionOtherValues 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 SettingRealsFromPositiveInts : pb::IMessage<SettingRealsFromPositiveInts> {
    private static readonly pb::MessageParser<SettingRealsFromPositiveInts> _parser = new pb::MessageParser<SettingRealsFromPositiveInts>(() => new SettingRealsFromPositiveInts());
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<SettingRealsFromPositiveInts> Parser { get { return _parser; } }

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

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

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

    partial void OnConstruction();

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

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

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(SettingRealsFromPositiveInts 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(SettingRealsFromPositiveInts 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 SettingRealsFromNegativeInts : pb::IMessage<SettingRealsFromNegativeInts> {
    private static readonly pb::MessageParser<SettingRealsFromNegativeInts> _parser = new pb::MessageParser<SettingRealsFromNegativeInts>(() => new SettingRealsFromNegativeInts());
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<SettingRealsFromNegativeInts> Parser { get { return _parser; } }

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

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

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

    partial void OnConstruction();

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

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

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(SettingRealsFromNegativeInts 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(SettingRealsFromNegativeInts 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 ComplexOptionType1 : pb::IMessage<ComplexOptionType1> {
    private static readonly pb::MessageParser<ComplexOptionType1> _parser = new pb::MessageParser<ComplexOptionType1>(() => new ComplexOptionType1());
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<ComplexOptionType1> Parser { get { return _parser; } }

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

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

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

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public ComplexOptionType1(ComplexOptionType1 other) : this() {
      foo_ = other.foo_;
      foo2_ = other.foo2_;
      foo3_ = other.foo3_;
      foo4_ = other.foo4_.Clone();
    }

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

    /// <summary>Field number for the "foo" field.</summary>
    public const int FooFieldNumber = 1;
    private int foo_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int Foo {
      get { return foo_; }
      set {
        foo_ = value;
      }
    }

    /// <summary>Field number for the "foo2" field.</summary>
    public const int Foo2FieldNumber = 2;
    private int foo2_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int Foo2 {
      get { return foo2_; }
      set {
        foo2_ = value;
      }
    }

    /// <summary>Field number for the "foo3" field.</summary>
    public const int Foo3FieldNumber = 3;
    private int foo3_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int Foo3 {
      get { return foo3_; }
      set {
        foo3_ = value;
      }
    }

    /// <summary>Field number for the "foo4" field.</summary>
    public const int Foo4FieldNumber = 4;
    private static readonly pb::FieldCodec<int> _repeated_foo4_codec
        = pb::FieldCodec.ForInt32(34);
    private readonly pbc::RepeatedField<int> foo4_ = new pbc::RepeatedField<int>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<int> Foo4 {
      get { return foo4_; }
    }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(ComplexOptionType1 other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Foo != other.Foo) return false;
      if (Foo2 != other.Foo2) return false;
      if (Foo3 != other.Foo3) return false;
      if(!foo4_.Equals(other.foo4_)) return false;
      return true;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (Foo != 0) hash ^= Foo.GetHashCode();
      if (Foo2 != 0) hash ^= Foo2.GetHashCode();
      if (Foo3 != 0) hash ^= Foo3.GetHashCode();
      hash ^= foo4_.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 (Foo != 0) {
        output.WriteRawTag(8);
        output.WriteInt32(Foo);
      }
      if (Foo2 != 0) {
        output.WriteRawTag(16);
        output.WriteInt32(Foo2);
      }
      if (Foo3 != 0) {
        output.WriteRawTag(24);
        output.WriteInt32(Foo3);
      }
      foo4_.WriteTo(output, _repeated_foo4_codec);
    }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(ComplexOptionType1 other) {
      if (other == null) {
        return;
      }
      if (other.Foo != 0) {
        Foo = other.Foo;
      }
      if (other.Foo2 != 0) {
        Foo2 = other.Foo2;
      }
      if (other.Foo3 != 0) {
        Foo3 = other.Foo3;
      }
      foo4_.Add(other.foo4_);
    }

    [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: {
            Foo = input.ReadInt32();
            break;
          }
          case 16: {
            Foo2 = input.ReadInt32();
            break;
          }
          case 24: {
            Foo3 = input.ReadInt32();
            break;
          }
          case 34:
          case 32: {
            foo4_.AddEntriesFrom(input, _repeated_foo4_codec);
            break;
          }
        }
      }
    }

  }

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

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

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

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

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public ComplexOptionType2(ComplexOptionType2 other) : this() {
      Bar = other.bar_ != null ? other.Bar.Clone() : null;
      baz_ = other.baz_;
      Fred = other.fred_ != null ? other.Fred.Clone() : null;
      barney_ = other.barney_.Clone();
    }

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

    /// <summary>Field number for the "bar" field.</summary>
    public const int BarFieldNumber = 1;
    private global::UnitTest.Issues.TestProtos.ComplexOptionType1 bar_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::UnitTest.Issues.TestProtos.ComplexOptionType1 Bar {
      get { return bar_; }
      set {
        bar_ = value;
      }
    }

    /// <summary>Field number for the "baz" field.</summary>
    public const int BazFieldNumber = 2;
    private int baz_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int Baz {
      get { return baz_; }
      set {
        baz_ = value;
      }
    }

    /// <summary>Field number for the "fred" field.</summary>
    public const int FredFieldNumber = 3;
    private global::UnitTest.Issues.TestProtos.ComplexOptionType2.Types.ComplexOptionType4 fred_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::UnitTest.Issues.TestProtos.ComplexOptionType2.Types.ComplexOptionType4 Fred {
      get { return fred_; }
      set {
        fred_ = value;
      }
    }

    /// <summary>Field number for the "barney" field.</summary>
    public const int BarneyFieldNumber = 4;
    private static readonly pb::FieldCodec<global::UnitTest.Issues.TestProtos.ComplexOptionType2.Types.ComplexOptionType4> _repeated_barney_codec
        = pb::FieldCodec.ForMessage(34, global::UnitTest.Issues.TestProtos.ComplexOptionType2.Types.ComplexOptionType4.Parser);
    private readonly pbc::RepeatedField<global::UnitTest.Issues.TestProtos.ComplexOptionType2.Types.ComplexOptionType4> barney_ = new pbc::RepeatedField<global::UnitTest.Issues.TestProtos.ComplexOptionType2.Types.ComplexOptionType4>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public pbc::RepeatedField<global::UnitTest.Issues.TestProtos.ComplexOptionType2.Types.ComplexOptionType4> Barney {
      get { return barney_; }
    }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(ComplexOptionType2 other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (!object.Equals(Bar, other.Bar)) return false;
      if (Baz != other.Baz) return false;
      if (!object.Equals(Fred, other.Fred)) return false;
      if(!barney_.Equals(other.barney_)) return false;
      return true;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (bar_ != null) hash ^= Bar.GetHashCode();
      if (Baz != 0) hash ^= Baz.GetHashCode();
      if (fred_ != null) hash ^= Fred.GetHashCode();
      hash ^= barney_.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 (bar_ != null) {
        output.WriteRawTag(10);
        output.WriteMessage(Bar);
      }
      if (Baz != 0) {
        output.WriteRawTag(16);
        output.WriteInt32(Baz);
      }
      if (fred_ != null) {
        output.WriteRawTag(26);
        output.WriteMessage(Fred);
      }
      barney_.WriteTo(output, _repeated_barney_codec);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (bar_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Bar);
      }
      if (Baz != 0) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Baz);
      }
      if (fred_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Fred);
      }
      size += barney_.CalculateSize(_repeated_barney_codec);
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(ComplexOptionType2 other) {
      if (other == null) {
        return;
      }
      if (other.bar_ != null) {
        if (bar_ == null) {
          bar_ = new global::UnitTest.Issues.TestProtos.ComplexOptionType1();
        }
        Bar.MergeFrom(other.Bar);
      }
      if (other.Baz != 0) {
        Baz = other.Baz;
      }
      if (other.fred_ != null) {
        if (fred_ == null) {
          fred_ = new global::UnitTest.Issues.TestProtos.ComplexOptionType2.Types.ComplexOptionType4();
        }
        Fred.MergeFrom(other.Fred);
      }
      barney_.Add(other.barney_);
    }

    [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: {
            if (bar_ == null) {
              bar_ = new global::UnitTest.Issues.TestProtos.ComplexOptionType1();
            }
            input.ReadMessage(bar_);
            break;
          }
          case 16: {
            Baz = input.ReadInt32();
            break;
          }
          case 26: {
            if (fred_ == null) {
              fred_ = new global::UnitTest.Issues.TestProtos.ComplexOptionType2.Types.ComplexOptionType4();
            }
            input.ReadMessage(fred_);
            break;
          }
          case 34: {
            barney_.AddEntriesFrom(input, _repeated_barney_codec);
            break;
          }
        }
      }
    }

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

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

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

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

        partial void OnConstruction();

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

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

        /// <summary>Field number for the "waldo" field.</summary>
        public const int WaldoFieldNumber = 1;
        private int waldo_;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int Waldo {
          get { return waldo_; }
          set {
            waldo_ = value;
          }
        }

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

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

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

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

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

        [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: {
                Waldo = input.ReadInt32();
                break;
              }
            }
          }
        }

      }

    }
    #endregion

  }

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

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

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

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

    partial void OnConstruction();

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

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

    /// <summary>Field number for the "qux" field.</summary>
    public const int QuxFieldNumber = 1;
    private int qux_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int Qux {
      get { return qux_; }
      set {
        qux_ = value;
      }
    }

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

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

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

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

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

    [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: {
            Qux = input.ReadInt32();
            break;
          }
        }
      }
    }

  }

  /// <summary>
  /// Note that we try various different ways of naming the same extension.
  /// </summary>
  public sealed partial class VariousComplexOptions : pb::IMessage<VariousComplexOptions> {
    private static readonly pb::MessageParser<VariousComplexOptions> _parser = new pb::MessageParser<VariousComplexOptions>(() => new VariousComplexOptions());
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<VariousComplexOptions> Parser { get { return _parser; } }

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

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

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

    partial void OnConstruction();

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

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

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(VariousComplexOptions 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(VariousComplexOptions 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;
        }
      }
    }

  }

  /// <summary>
  /// A helper type used to test aggregate option parsing
  /// </summary>
  public sealed partial class Aggregate : pb::IMessage<Aggregate> {
    private static readonly pb::MessageParser<Aggregate> _parser = new pb::MessageParser<Aggregate>(() => new Aggregate());
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<Aggregate> Parser { get { return _parser; } }

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

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

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

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public Aggregate(Aggregate other) : this() {
      i_ = other.i_;
      s_ = other.s_;
      Sub = other.sub_ != null ? other.Sub.Clone() : null;
    }

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

    /// <summary>Field number for the "i" field.</summary>
    public const int IFieldNumber = 1;
    private int i_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int I {
      get { return i_; }
      set {
        i_ = value;
      }
    }

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

    /// <summary>Field number for the "sub" field.</summary>
    public const int SubFieldNumber = 3;
    private global::UnitTest.Issues.TestProtos.Aggregate sub_;
    /// <summary>
    /// A nested object
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public global::UnitTest.Issues.TestProtos.Aggregate Sub {
      get { return sub_; }
      set {
        sub_ = value;
      }
    }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(Aggregate other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (I != other.I) return false;
      if (S != other.S) return false;
      if (!object.Equals(Sub, other.Sub)) return false;
      return true;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public override int GetHashCode() {
      int hash = 1;
      if (I != 0) hash ^= I.GetHashCode();
      if (S.Length != 0) hash ^= S.GetHashCode();
      if (sub_ != null) hash ^= Sub.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 (I != 0) {
        output.WriteRawTag(8);
        output.WriteInt32(I);
      }
      if (S.Length != 0) {
        output.WriteRawTag(18);
        output.WriteString(S);
      }
      if (sub_ != null) {
        output.WriteRawTag(26);
        output.WriteMessage(Sub);
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int CalculateSize() {
      int size = 0;
      if (I != 0) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(I);
      }
      if (S.Length != 0) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(S);
      }
      if (sub_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Sub);
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public void MergeFrom(Aggregate other) {
      if (other == null) {
        return;
      }
      if (other.I != 0) {
        I = other.I;
      }
      if (other.S.Length != 0) {
        S = other.S;
      }
      if (other.sub_ != null) {
        if (sub_ == null) {
          sub_ = new global::UnitTest.Issues.TestProtos.Aggregate();
        }
        Sub.MergeFrom(other.Sub);
      }
    }

    [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: {
            I = input.ReadInt32();
            break;
          }
          case 18: {
            S = input.ReadString();
            break;
          }
          case 26: {
            if (sub_ == null) {
              sub_ = new global::UnitTest.Issues.TestProtos.Aggregate();
            }
            input.ReadMessage(sub_);
            break;
          }
        }
      }
    }

  }

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

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

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

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

    partial void OnConstruction();

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

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

    /// <summary>Field number for the "fieldname" field.</summary>
    public const int FieldnameFieldNumber = 1;
    private int fieldname_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public int Fieldname {
      get { return fieldname_; }
      set {
        fieldname_ = value;
      }
    }

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

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

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

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

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

    [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: {
            Fieldname = input.ReadInt32();
            break;
          }
        }
      }
    }

  }

  /// <summary>
  /// Test custom options for nested type.
  /// </summary>
  public sealed partial class NestedOptionType : pb::IMessage<NestedOptionType> {
    private static readonly pb::MessageParser<NestedOptionType> _parser = new pb::MessageParser<NestedOptionType>(() => new NestedOptionType());
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static pb::MessageParser<NestedOptionType> Parser { get { return _parser; } }

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

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

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

    partial void OnConstruction();

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

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

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public bool Equals(NestedOptionType 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(NestedOptionType 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 NestedOptionType message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    public static partial class Types {
      public enum NestedEnum {
        [pbr::OriginalName("UNSPECIFIED")] Unspecified = 0,
        [pbr::OriginalName("NESTED_ENUM_VALUE")] Value = 1,
      }

      public sealed partial class NestedMessage : pb::IMessage<NestedMessage> {
        private static readonly pb::MessageParser<NestedMessage> _parser = new pb::MessageParser<NestedMessage>(() => new NestedMessage());
        [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::UnitTest.Issues.TestProtos.NestedOptionType.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() {
          nestedField_ = other.nestedField_;
        }

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

        /// <summary>Field number for the "nested_field" field.</summary>
        public const int NestedFieldFieldNumber = 1;
        private int nestedField_;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        public int NestedField {
          get { return nestedField_; }
          set {
            nestedField_ = value;
          }
        }

        [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 (NestedField != other.NestedField) return false;
          return true;
        }

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

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

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

        [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: {
                NestedField = input.ReadInt32();
                break;
              }
            }
          }
        }

      }

    }
    #endregion

  }

  #endregion

}

#endregion Designer generated code
