// Generated by ProtoGen, Version=2.3.0.277, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48.  DO NOT EDIT!

using pb = global::Google.ProtocolBuffers;
using pbc = global::Google.ProtocolBuffers.Collections;
using pbd = global::Google.ProtocolBuffers.Descriptors;
using scg = global::System.Collections.Generic;
namespace Google.ProtocolBuffers.TestProtos {
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public static partial class UnitTestCustomOptionsProtoFile {
  
    #region Extension registration
    public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.FileOpt1);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.MessageOpt1);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.FieldOpt1);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.FieldOpt2);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.EnumOpt1);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.EnumValueOpt1);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.ServiceOpt1);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.MethodOpt1);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.BoolOpt);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Int32Opt);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Int64Opt);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Uint32Opt);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Uint64Opt);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Sint32Opt);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Sint64Opt);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Fixed32Opt);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Fixed64Opt);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Sfixed32Opt);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Sfixed64Opt);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.FloatOpt);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.DoubleOpt);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.StringOpt);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.BytesOpt);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.EnumOpt);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.MessageTypeOpt);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Quux);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Corge);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Grault);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Garply);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.ComplexOpt1);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.ComplexOpt2);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.ComplexOpt3);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.ComplexOpt6);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4.ComplexOpt4);
    }
    #endregion
    #region Extensions
    public const int FileOpt1FieldNumber = 7736974;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<ulong> FileOpt1;
    public const int MessageOpt1FieldNumber = 7739036;
    public static pb::GeneratedExtensionBase<int> MessageOpt1;
    public const int FieldOpt1FieldNumber = 7740936;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<ulong> FieldOpt1;
    public const int FieldOpt2FieldNumber = 7753913;
    public static pb::GeneratedExtensionBase<int> FieldOpt2;
    public const int EnumOpt1FieldNumber = 7753576;
    public static pb::GeneratedExtensionBase<int> EnumOpt1;
    public const int EnumValueOpt1FieldNumber = 1560678;
    public static pb::GeneratedExtensionBase<int> EnumValueOpt1;
    public const int ServiceOpt1FieldNumber = 7887650;
    public static pb::GeneratedExtensionBase<long> ServiceOpt1;
    public const int MethodOpt1FieldNumber = 7890860;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.MethodOpt1> MethodOpt1;
    public const int BoolOptFieldNumber = 7706090;
    public static pb::GeneratedExtensionBase<bool> BoolOpt;
    public const int Int32OptFieldNumber = 7705709;
    public static pb::GeneratedExtensionBase<int> Int32Opt;
    public const int Int64OptFieldNumber = 7705542;
    public static pb::GeneratedExtensionBase<long> Int64Opt;
    public const int Uint32OptFieldNumber = 7704880;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<uint> Uint32Opt;
    public const int Uint64OptFieldNumber = 7702367;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<ulong> Uint64Opt;
    public const int Sint32OptFieldNumber = 7701568;
    public static pb::GeneratedExtensionBase<int> Sint32Opt;
    public const int Sint64OptFieldNumber = 7700863;
    public static pb::GeneratedExtensionBase<long> Sint64Opt;
    public const int Fixed32OptFieldNumber = 7700307;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<uint> Fixed32Opt;
    public const int Fixed64OptFieldNumber = 7700194;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<ulong> Fixed64Opt;
    public const int Sfixed32OptFieldNumber = 7698645;
    public static pb::GeneratedExtensionBase<int> Sfixed32Opt;
    public const int Sfixed64OptFieldNumber = 7685475;
    public static pb::GeneratedExtensionBase<long> Sfixed64Opt;
    public const int FloatOptFieldNumber = 7675390;
    public static pb::GeneratedExtensionBase<float> FloatOpt;
    public const int DoubleOptFieldNumber = 7673293;
    public static pb::GeneratedExtensionBase<double> DoubleOpt;
    public const int StringOptFieldNumber = 7673285;
    public static pb::GeneratedExtensionBase<string> StringOpt;
    public const int BytesOptFieldNumber = 7673238;
    public static pb::GeneratedExtensionBase<pb::ByteString> BytesOpt;
    public const int EnumOptFieldNumber = 7673233;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.DummyMessageContainingEnum.Types.TestEnumType> EnumOpt;
    public const int MessageTypeOptFieldNumber = 7665967;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.DummyMessageInvalidAsOptionType> MessageTypeOpt;
    public const int QuuxFieldNumber = 7663707;
    public static pb::GeneratedExtensionBase<int> Quux;
    public const int CorgeFieldNumber = 7663442;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3> Corge;
    public const int GraultFieldNumber = 7650927;
    public static pb::GeneratedExtensionBase<int> Grault;
    public const int GarplyFieldNumber = 7649992;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1> Garply;
    public const int ComplexOpt1FieldNumber = 7646756;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1> ComplexOpt1;
    public const int ComplexOpt2FieldNumber = 7636949;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2> ComplexOpt2;
    public const int ComplexOpt3FieldNumber = 7636463;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3> ComplexOpt3;
    public const int ComplexOpt6FieldNumber = 7595468;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.ComplexOpt6> ComplexOpt6;
    #endregion
    
    #region Static variables
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestMessageWithCustomOptions__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestMessageWithCustomOptions, global::Google.ProtocolBuffers.TestProtos.TestMessageWithCustomOptions.Builder> internal__static_protobuf_unittest_TestMessageWithCustomOptions__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_CustomOptionFooRequest__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.CustomOptionFooRequest, global::Google.ProtocolBuffers.TestProtos.CustomOptionFooRequest.Builder> internal__static_protobuf_unittest_CustomOptionFooRequest__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_CustomOptionFooResponse__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.CustomOptionFooResponse, global::Google.ProtocolBuffers.TestProtos.CustomOptionFooResponse.Builder> internal__static_protobuf_unittest_CustomOptionFooResponse__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_DummyMessageContainingEnum__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.DummyMessageContainingEnum, global::Google.ProtocolBuffers.TestProtos.DummyMessageContainingEnum.Builder> internal__static_protobuf_unittest_DummyMessageContainingEnum__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_DummyMessageInvalidAsOptionType__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.DummyMessageInvalidAsOptionType, global::Google.ProtocolBuffers.TestProtos.DummyMessageInvalidAsOptionType.Builder> internal__static_protobuf_unittest_DummyMessageInvalidAsOptionType__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_CustomOptionMinIntegerValues__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.CustomOptionMinIntegerValues, global::Google.ProtocolBuffers.TestProtos.CustomOptionMinIntegerValues.Builder> internal__static_protobuf_unittest_CustomOptionMinIntegerValues__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_CustomOptionMaxIntegerValues__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.CustomOptionMaxIntegerValues, global::Google.ProtocolBuffers.TestProtos.CustomOptionMaxIntegerValues.Builder> internal__static_protobuf_unittest_CustomOptionMaxIntegerValues__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_CustomOptionOtherValues__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.CustomOptionOtherValues, global::Google.ProtocolBuffers.TestProtos.CustomOptionOtherValues.Builder> internal__static_protobuf_unittest_CustomOptionOtherValues__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_SettingRealsFromPositiveInts__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.SettingRealsFromPositiveInts, global::Google.ProtocolBuffers.TestProtos.SettingRealsFromPositiveInts.Builder> internal__static_protobuf_unittest_SettingRealsFromPositiveInts__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_SettingRealsFromNegativeInts__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.SettingRealsFromNegativeInts, global::Google.ProtocolBuffers.TestProtos.SettingRealsFromNegativeInts.Builder> internal__static_protobuf_unittest_SettingRealsFromNegativeInts__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_ComplexOptionType1__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1, global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1.Builder> internal__static_protobuf_unittest_ComplexOptionType1__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_ComplexOptionType2__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2, global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Builder> internal__static_protobuf_unittest_ComplexOptionType2__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_ComplexOptionType2_ComplexOptionType4__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4, global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4.Builder> internal__static_protobuf_unittest_ComplexOptionType2_ComplexOptionType4__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_ComplexOptionType3__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3, global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Builder> internal__static_protobuf_unittest_ComplexOptionType3__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_ComplexOptionType3_ComplexOptionType5__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5, global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5.Builder> internal__static_protobuf_unittest_ComplexOptionType3_ComplexOptionType5__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_ComplexOpt6__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.ComplexOpt6, global::Google.ProtocolBuffers.TestProtos.ComplexOpt6.Builder> internal__static_protobuf_unittest_ComplexOpt6__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_VariousComplexOptions__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.VariousComplexOptions, global::Google.ProtocolBuffers.TestProtos.VariousComplexOptions.Builder> internal__static_protobuf_unittest_VariousComplexOptions__FieldAccessorTable;
    #endregion
    #region Descriptor
    public static pbd::FileDescriptor Descriptor {
      get { return descriptor; }
    }
    private static pbd::FileDescriptor descriptor;
    
    static UnitTestCustomOptionsProtoFile() {
      byte[] descriptorData = global::System.Convert.FromBase64String(
          "Ci1nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfY3VzdG9tX29wdGlvbnMucHJv" + 
          "dG8SEXByb3RvYnVmX3VuaXR0ZXN0GiRnb29nbGUvcHJvdG9idWYvY3NoYXJw" + 
          "X29wdGlvbnMucHJvdG8aIGdvb2dsZS9wcm90b2J1Zi9kZXNjcmlwdG9yLnBy" + 
          "b3RvIo0BChxUZXN0TWVzc2FnZVdpdGhDdXN0b21PcHRpb25zEh4KBmZpZWxk" + 
          "MRgBIAEoCUIOCAHB4MMdLeF1CgIAAAAiOwoGQW5FbnVtEg8KC0FORU5VTV9W" + 
          "QUwxEAESFgoLQU5FTlVNX1ZBTDIQAhoFsIb6BXsaCMX2yR3r/P//OhAIAODp" + 
          "wh3I//////////8BIhgKFkN1c3RvbU9wdGlvbkZvb1JlcXVlc3QiGQoXQ3Vz" + 
          "dG9tT3B0aW9uRm9vUmVzcG9uc2UibQoaRHVtbXlNZXNzYWdlQ29udGFpbmlu" + 
          "Z0VudW0iTwoMVGVzdEVudW1UeXBlEhoKFlRFU1RfT1BUSU9OX0VOVU1fVFlQ" + 
          "RTEQFhIjChZURVNUX09QVElPTl9FTlVNX1RZUEUyEOn//////////wEiIQof" + 
          "RHVtbXlNZXNzYWdlSW52YWxpZEFzT3B0aW9uVHlwZSKKAQocQ3VzdG9tT3B0" + 
          "aW9uTWluSW50ZWdlclZhbHVlczpqmdaoHQAAAAAAAACArY2vHQAAAICR7q8d" + 
          "AAAAAAAAAACd9a8dAAAAAPiXsB3///////////8BgMSwHf////8P+PWwHQCA" + 
          "k7IdALC8sh2AgICAgICAgIAB6MayHYCAgID4/////wHQ3rIdACKRAQocQ3Vz" + 
          "dG9tT3B0aW9uTWF4SW50ZWdlclZhbHVlczpxmdaoHf////////9/rY2vHf//" + 
          "/3+R7q8d//////////+d9a8d//////iXsB3+//////////8BgMSwHf7///8P" + 
          "+PWwHf///////////wGAk7Id/////w+wvLId//////////9/6MayHf////8H" + 
          "0N6yHQEibgoXQ3VzdG9tT3B0aW9uT3RoZXJWYWx1ZXM6U4jZoh3p////////" + 
          "//8BstmiHQtIZWxsbwBXb3JsZKrcoh0OSGVsbG8sICJXb3JsZCLp3KId+1mM" + 
          "QsrA8z/136Md54dFQejGsh2c//////////8BIjQKHFNldHRpbmdSZWFsc0Zy" + 
          "b21Qb3NpdGl2ZUludHM6FOncoh0AAAAAAEBjQPXfox0AAEBBIjQKHFNldHRp" + 
          "bmdSZWFsc0Zyb21OZWdhdGl2ZUludHM6FOncoh0AAAAAAEBjwPXfox0AAEDB" + 
          "IkcKEkNvbXBsZXhPcHRpb25UeXBlMRILCgNmb28YASABKAUSDAoEZm9vMhgC" + 
          "IAEoBRIMCgRmb28zGAMgASgFKggIZBCAgICAAiLBAgoSQ29tcGxleE9wdGlv" + 
          "blR5cGUyEjIKA2JhchgBIAEoCzIlLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBs" + 
          "ZXhPcHRpb25UeXBlMRILCgNiYXoYAiABKAUSRgoEZnJlZBgDIAEoCzI4LnBy" + 
          "b3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMi5Db21wbGV4T3B0" + 
          "aW9uVHlwZTQalwEKEkNvbXBsZXhPcHRpb25UeXBlNBINCgV3YWxkbxgBIAEo" + 
          "BTJyCgxjb21wbGV4X29wdDQSHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9w" + 
          "dGlvbnMYivXRAyABKAsyOC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0" + 
          "aW9uVHlwZTIuQ29tcGxleE9wdGlvblR5cGU0KggIZBCAgICAAiKcAQoSQ29t" + 
          "cGxleE9wdGlvblR5cGUzEgsKA3F1eBgBIAEoBRJUChJjb21wbGV4b3B0aW9u" + 
          "dHlwZTUYAiABKAoyOC5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9u" + 
          "VHlwZTMuQ29tcGxleE9wdGlvblR5cGU1GiMKEkNvbXBsZXhPcHRpb25UeXBl" + 
          "NRINCgVwbHVnaBgDIAEoBSIfCgtDb21wbGV4T3B0NhIQCgV4eXp6eRjfv88D" + 
          "IAEoBSLQAQoVVmFyaW91c0NvbXBsZXhPcHRpb25zOrYB49z8HPj9+xwY5Nz8" + 
          "HNKojx0DCLMP+t6QHQIICfrekB0EExgWFKr9kB0DENsHqv2QHQb45pcdjgWq" + 
          "/ZAdBQoDCOcFqv2QHQgKBtiFnh3PD6r9kB0KCgiS9Z0dAwjYD6r9kB0IwqyX" + 
          "HQMI5QWq/ZAdC8Kslx0G2IWeHc4Pqv2QHQ3CrJcdCJL1nR0DCMkQqv2QHQUa" + 
          "AwjBAqLilR0CCCqi4pUdBtiFnh3EAqLilR0IkvWdHQMI7AYqNgoKTWV0aG9k" + 
          "T3B0MRITCg9NRVRIT0RPUFQxX1ZBTDEQARITCg9NRVRIT0RPUFQxX1ZBTDIQ" + 
          "AjKOAQocVGVzdFNlcnZpY2VXaXRoQ3VzdG9tT3B0aW9ucxJjCgNGb28SKS5w" + 
          "cm90b2J1Zl91bml0dGVzdC5DdXN0b21PcHRpb25Gb29SZXF1ZXN0GioucHJv" + 
          "dG9idWZfdW5pdHRlc3QuQ3VzdG9tT3B0aW9uRm9vUmVzcG9uc2UiBeD6jB4C" + 
          "GgmQsose09uAy0k6MgoJZmlsZV9vcHQxEhwuZ29vZ2xlLnByb3RvYnVmLkZp" + 
          "bGVPcHRpb25zGI6d2AMgASgEOjgKDG1lc3NhZ2Vfb3B0MRIfLmdvb2dsZS5w" + 
          "cm90b2J1Zi5NZXNzYWdlT3B0aW9ucxicrdgDIAEoBTo0CgpmaWVsZF9vcHQx" + 
          "Eh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxiIvNgDIAEoBjo4Cgpm" + 
          "aWVsZF9vcHQyEh0uZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucxi5odkD" + 
          "IAEoBToCNDI6MgoJZW51bV9vcHQxEhwuZ29vZ2xlLnByb3RvYnVmLkVudW1P" + 
          "cHRpb25zGOie2QMgASgPOjwKD2VudW1fdmFsdWVfb3B0MRIhLmdvb2dsZS5w" + 
          "cm90b2J1Zi5FbnVtVmFsdWVPcHRpb25zGOagXyABKAU6OAoMc2VydmljZV9v" + 
          "cHQxEh8uZ29vZ2xlLnByb3RvYnVmLlNlcnZpY2VPcHRpb25zGKK24QMgASgS" + 
          "OlUKC21ldGhvZF9vcHQxEh4uZ29vZ2xlLnByb3RvYnVmLk1ldGhvZE9wdGlv" + 
          "bnMYrM/hAyABKA4yHS5wcm90b2J1Zl91bml0dGVzdC5NZXRob2RPcHQxOjQK" + 
          "CGJvb2xfb3B0Eh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGOqr" + 
          "1gMgASgIOjUKCWludDMyX29wdBIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdl" + 
          "T3B0aW9ucxjtqNYDIAEoBTo1CglpbnQ2NF9vcHQSHy5nb29nbGUucHJvdG9i" + 
          "dWYuTWVzc2FnZU9wdGlvbnMYxqfWAyABKAM6NgoKdWludDMyX29wdBIfLmdv" + 
          "b2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxiwotYDIAEoDTo2Cgp1aW50" + 
          "NjRfb3B0Eh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGN+O1gMg" + 
          "ASgEOjYKCnNpbnQzMl9vcHQSHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9w" + 
          "dGlvbnMYwIjWAyABKBE6NgoKc2ludDY0X29wdBIfLmdvb2dsZS5wcm90b2J1" + 
          "Zi5NZXNzYWdlT3B0aW9ucxj/gtYDIAEoEjo3CgtmaXhlZDMyX29wdBIfLmdv" + 
          "b2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxjT/tUDIAEoBzo3CgtmaXhl" + 
          "ZDY0X29wdBIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxji/dUD" + 
          "IAEoBjo4CgxzZml4ZWQzMl9vcHQSHy5nb29nbGUucHJvdG9idWYuTWVzc2Fn" + 
          "ZU9wdGlvbnMY1fHVAyABKA86OAoMc2ZpeGVkNjRfb3B0Eh8uZ29vZ2xlLnBy" + 
          "b3RvYnVmLk1lc3NhZ2VPcHRpb25zGOOK1QMgASgQOjUKCWZsb2F0X29wdBIf" + 
          "Lmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxj+u9QDIAEoAjo2Cgpk" + 
          "b3VibGVfb3B0Eh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGM2r" + 
          "1AMgASgBOjYKCnN0cmluZ19vcHQSHy5nb29nbGUucHJvdG9idWYuTWVzc2Fn" + 
          "ZU9wdGlvbnMYxavUAyABKAk6NQoJYnl0ZXNfb3B0Eh8uZ29vZ2xlLnByb3Rv" + 
          "YnVmLk1lc3NhZ2VPcHRpb25zGJar1AMgASgMOnAKCGVudW1fb3B0Eh8uZ29v" + 
          "Z2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGJGr1AMgASgOMjoucHJvdG9i" + 
          "dWZfdW5pdHRlc3QuRHVtbXlNZXNzYWdlQ29udGFpbmluZ0VudW0uVGVzdEVu" + 
          "dW1UeXBlOnAKEG1lc3NhZ2VfdHlwZV9vcHQSHy5nb29nbGUucHJvdG9idWYu" + 
          "TWVzc2FnZU9wdGlvbnMYr/LTAyABKAsyMi5wcm90b2J1Zl91bml0dGVzdC5E" + 
          "dW1teU1lc3NhZ2VJbnZhbGlkQXNPcHRpb25UeXBlOjYKBHF1dXgSJS5wcm90" + 
          "b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTEY2+DTAyABKAU6XgoF" + 
          "Y29yZ2USJS5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTEY" + 
          "0t7TAyABKAsyJS5wcm90b2J1Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlw" + 
          "ZTM6OAoGZ3JhdWx0EiUucHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlv" + 
          "blR5cGUyGO/80gMgASgFOl8KBmdhcnBseRIlLnByb3RvYnVmX3VuaXR0ZXN0" + 
          "LkNvbXBsZXhPcHRpb25UeXBlMhjI9dIDIAEoCzIlLnByb3RvYnVmX3VuaXR0" + 
          "ZXN0LkNvbXBsZXhPcHRpb25UeXBlMTpfCgxjb21wbGV4X29wdDESHy5nb29n" + 
          "bGUucHJvdG9idWYuTWVzc2FnZU9wdGlvbnMYpNzSAyABKAsyJS5wcm90b2J1" + 
          "Zl91bml0dGVzdC5Db21wbGV4T3B0aW9uVHlwZTE6XwoMY29tcGxleF9vcHQy" + 
          "Eh8uZ29vZ2xlLnByb3RvYnVmLk1lc3NhZ2VPcHRpb25zGNWP0gMgASgLMiUu" + 
          "cHJvdG9idWZfdW5pdHRlc3QuQ29tcGxleE9wdGlvblR5cGUyOl8KDGNvbXBs" + 
          "ZXhfb3B0MxIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9ucxjvi9ID" + 
          "IAEoCzIlLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHRpb25UeXBlMzpX" + 
          "Cgtjb21wbGV4b3B0NhIfLmdvb2dsZS5wcm90b2J1Zi5NZXNzYWdlT3B0aW9u" + 
          "cxjMy88DIAEoCjIeLnByb3RvYnVmX3VuaXR0ZXN0LkNvbXBsZXhPcHQ2Qk/C" + 
          "PkMKIUdvb2dsZS5Qcm90b2NvbEJ1ZmZlcnMuVGVzdFByb3RvcxIeVW5pdFRl" + 
          "c3RDdXN0b21PcHRpb25zUHJvdG9GaWxl8OjBHeqtwOUk");
      pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
        descriptor = root;
        internal__static_protobuf_unittest_TestMessageWithCustomOptions__Descriptor = Descriptor.MessageTypes[0];
        internal__static_protobuf_unittest_TestMessageWithCustomOptions__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestMessageWithCustomOptions, global::Google.ProtocolBuffers.TestProtos.TestMessageWithCustomOptions.Builder>(internal__static_protobuf_unittest_TestMessageWithCustomOptions__Descriptor,
                new string[] { "Field1", });
        internal__static_protobuf_unittest_CustomOptionFooRequest__Descriptor = Descriptor.MessageTypes[1];
        internal__static_protobuf_unittest_CustomOptionFooRequest__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.CustomOptionFooRequest, global::Google.ProtocolBuffers.TestProtos.CustomOptionFooRequest.Builder>(internal__static_protobuf_unittest_CustomOptionFooRequest__Descriptor,
                new string[] { });
        internal__static_protobuf_unittest_CustomOptionFooResponse__Descriptor = Descriptor.MessageTypes[2];
        internal__static_protobuf_unittest_CustomOptionFooResponse__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.CustomOptionFooResponse, global::Google.ProtocolBuffers.TestProtos.CustomOptionFooResponse.Builder>(internal__static_protobuf_unittest_CustomOptionFooResponse__Descriptor,
                new string[] { });
        internal__static_protobuf_unittest_DummyMessageContainingEnum__Descriptor = Descriptor.MessageTypes[3];
        internal__static_protobuf_unittest_DummyMessageContainingEnum__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.DummyMessageContainingEnum, global::Google.ProtocolBuffers.TestProtos.DummyMessageContainingEnum.Builder>(internal__static_protobuf_unittest_DummyMessageContainingEnum__Descriptor,
                new string[] { });
        internal__static_protobuf_unittest_DummyMessageInvalidAsOptionType__Descriptor = Descriptor.MessageTypes[4];
        internal__static_protobuf_unittest_DummyMessageInvalidAsOptionType__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.DummyMessageInvalidAsOptionType, global::Google.ProtocolBuffers.TestProtos.DummyMessageInvalidAsOptionType.Builder>(internal__static_protobuf_unittest_DummyMessageInvalidAsOptionType__Descriptor,
                new string[] { });
        internal__static_protobuf_unittest_CustomOptionMinIntegerValues__Descriptor = Descriptor.MessageTypes[5];
        internal__static_protobuf_unittest_CustomOptionMinIntegerValues__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.CustomOptionMinIntegerValues, global::Google.ProtocolBuffers.TestProtos.CustomOptionMinIntegerValues.Builder>(internal__static_protobuf_unittest_CustomOptionMinIntegerValues__Descriptor,
                new string[] { });
        internal__static_protobuf_unittest_CustomOptionMaxIntegerValues__Descriptor = Descriptor.MessageTypes[6];
        internal__static_protobuf_unittest_CustomOptionMaxIntegerValues__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.CustomOptionMaxIntegerValues, global::Google.ProtocolBuffers.TestProtos.CustomOptionMaxIntegerValues.Builder>(internal__static_protobuf_unittest_CustomOptionMaxIntegerValues__Descriptor,
                new string[] { });
        internal__static_protobuf_unittest_CustomOptionOtherValues__Descriptor = Descriptor.MessageTypes[7];
        internal__static_protobuf_unittest_CustomOptionOtherValues__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.CustomOptionOtherValues, global::Google.ProtocolBuffers.TestProtos.CustomOptionOtherValues.Builder>(internal__static_protobuf_unittest_CustomOptionOtherValues__Descriptor,
                new string[] { });
        internal__static_protobuf_unittest_SettingRealsFromPositiveInts__Descriptor = Descriptor.MessageTypes[8];
        internal__static_protobuf_unittest_SettingRealsFromPositiveInts__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.SettingRealsFromPositiveInts, global::Google.ProtocolBuffers.TestProtos.SettingRealsFromPositiveInts.Builder>(internal__static_protobuf_unittest_SettingRealsFromPositiveInts__Descriptor,
                new string[] { });
        internal__static_protobuf_unittest_SettingRealsFromNegativeInts__Descriptor = Descriptor.MessageTypes[9];
        internal__static_protobuf_unittest_SettingRealsFromNegativeInts__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.SettingRealsFromNegativeInts, global::Google.ProtocolBuffers.TestProtos.SettingRealsFromNegativeInts.Builder>(internal__static_protobuf_unittest_SettingRealsFromNegativeInts__Descriptor,
                new string[] { });
        internal__static_protobuf_unittest_ComplexOptionType1__Descriptor = Descriptor.MessageTypes[10];
        internal__static_protobuf_unittest_ComplexOptionType1__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1, global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1.Builder>(internal__static_protobuf_unittest_ComplexOptionType1__Descriptor,
                new string[] { "Foo", "Foo2", "Foo3", });
        internal__static_protobuf_unittest_ComplexOptionType2__Descriptor = Descriptor.MessageTypes[11];
        internal__static_protobuf_unittest_ComplexOptionType2__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2, global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Builder>(internal__static_protobuf_unittest_ComplexOptionType2__Descriptor,
                new string[] { "Bar", "Baz", "Fred", });
        internal__static_protobuf_unittest_ComplexOptionType2_ComplexOptionType4__Descriptor = internal__static_protobuf_unittest_ComplexOptionType2__Descriptor.NestedTypes[0];
        internal__static_protobuf_unittest_ComplexOptionType2_ComplexOptionType4__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4, global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4.Builder>(internal__static_protobuf_unittest_ComplexOptionType2_ComplexOptionType4__Descriptor,
                new string[] { "Waldo", });
        global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4.ComplexOpt4 = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4.Descriptor.Extensions[0]);
        internal__static_protobuf_unittest_ComplexOptionType3__Descriptor = Descriptor.MessageTypes[12];
        internal__static_protobuf_unittest_ComplexOptionType3__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3, global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Builder>(internal__static_protobuf_unittest_ComplexOptionType3__Descriptor,
                new string[] { "Qux", "ComplexOptionType5", });
        internal__static_protobuf_unittest_ComplexOptionType3_ComplexOptionType5__Descriptor = internal__static_protobuf_unittest_ComplexOptionType3__Descriptor.NestedTypes[0];
        internal__static_protobuf_unittest_ComplexOptionType3_ComplexOptionType5__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5, global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5.Builder>(internal__static_protobuf_unittest_ComplexOptionType3_ComplexOptionType5__Descriptor,
                new string[] { "Plugh", });
        internal__static_protobuf_unittest_ComplexOpt6__Descriptor = Descriptor.MessageTypes[13];
        internal__static_protobuf_unittest_ComplexOpt6__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.ComplexOpt6, global::Google.ProtocolBuffers.TestProtos.ComplexOpt6.Builder>(internal__static_protobuf_unittest_ComplexOpt6__Descriptor,
                new string[] { "Xyzzy", });
        internal__static_protobuf_unittest_VariousComplexOptions__Descriptor = Descriptor.MessageTypes[14];
        internal__static_protobuf_unittest_VariousComplexOptions__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.VariousComplexOptions, global::Google.ProtocolBuffers.TestProtos.VariousComplexOptions.Builder>(internal__static_protobuf_unittest_VariousComplexOptions__Descriptor,
                new string[] { });
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.FileOpt1 = pb::GeneratedSingleExtension<ulong>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[0]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.MessageOpt1 = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[1]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.FieldOpt1 = pb::GeneratedSingleExtension<ulong>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[2]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.FieldOpt2 = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[3]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.EnumOpt1 = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[4]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.EnumValueOpt1 = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[5]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.ServiceOpt1 = pb::GeneratedSingleExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[6]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.MethodOpt1 = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.MethodOpt1>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[7]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.BoolOpt = pb::GeneratedSingleExtension<bool>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[8]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Int32Opt = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[9]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Int64Opt = pb::GeneratedSingleExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[10]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Uint32Opt = pb::GeneratedSingleExtension<uint>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[11]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Uint64Opt = pb::GeneratedSingleExtension<ulong>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[12]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Sint32Opt = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[13]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Sint64Opt = pb::GeneratedSingleExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[14]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Fixed32Opt = pb::GeneratedSingleExtension<uint>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[15]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Fixed64Opt = pb::GeneratedSingleExtension<ulong>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[16]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Sfixed32Opt = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[17]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Sfixed64Opt = pb::GeneratedSingleExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[18]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.FloatOpt = pb::GeneratedSingleExtension<float>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[19]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.DoubleOpt = pb::GeneratedSingleExtension<double>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[20]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.StringOpt = pb::GeneratedSingleExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[21]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.BytesOpt = pb::GeneratedSingleExtension<pb::ByteString>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[22]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.EnumOpt = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.DummyMessageContainingEnum.Types.TestEnumType>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[23]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.MessageTypeOpt = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.DummyMessageInvalidAsOptionType>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[24]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Quux = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[25]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Corge = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[26]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Grault = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[27]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Garply = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[28]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.ComplexOpt1 = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[29]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.ComplexOpt2 = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[30]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.ComplexOpt3 = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[31]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.ComplexOpt6 = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.ComplexOpt6>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor.Extensions[32]);
        pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();
        RegisterAllExtensions(registry);
        global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.RegisterAllExtensions(registry);
        global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.RegisterAllExtensions(registry);
        return registry;
      };
      pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
          new pbd::FileDescriptor[] {
          global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor, 
          global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProtoFile.Descriptor, 
          }, assigner);
    }
    #endregion
    
  }
  #region Enums
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public enum MethodOpt1 {
    METHODOPT1_VAL1 = 1,
    METHODOPT1_VAL2 = 2,
  }
  
  #endregion
  
  #region Messages
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public sealed partial class TestMessageWithCustomOptions : pb::GeneratedMessage<TestMessageWithCustomOptions, TestMessageWithCustomOptions.Builder> {
    private static readonly TestMessageWithCustomOptions defaultInstance = new Builder().BuildPartial();
    public static TestMessageWithCustomOptions DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestMessageWithCustomOptions DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestMessageWithCustomOptions ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_TestMessageWithCustomOptions__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestMessageWithCustomOptions, TestMessageWithCustomOptions.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_TestMessageWithCustomOptions__FieldAccessorTable; }
    }
    
    #region Nested types
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public static class Types {
      [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
      [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
      public enum AnEnum {
        ANENUM_VAL1 = 1,
        ANENUM_VAL2 = 2,
      }
      
    }
    #endregion
    
    public const int Field1FieldNumber = 1;
    private bool hasField1;
    private string field1_ = "";
    public bool HasField1 {
      get { return hasField1; }
    }
    public string Field1 {
      get { return field1_; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (HasField1) {
        output.WriteString(1, "field1", Field1);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasField1) {
          size += pb::CodedOutputStream.ComputeStringSize(1, Field1);
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static TestMessageWithCustomOptions ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestMessageWithCustomOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestMessageWithCustomOptions ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestMessageWithCustomOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestMessageWithCustomOptions ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestMessageWithCustomOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestMessageWithCustomOptions ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestMessageWithCustomOptions ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestMessageWithCustomOptions ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestMessageWithCustomOptions ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static Builder CreateBuilder() { return new Builder(); }
    public override Builder ToBuilder() { return CreateBuilder(this); }
    public override Builder CreateBuilderForType() { return new Builder(); }
    public static Builder CreateBuilder(TestMessageWithCustomOptions prototype) {
      return (Builder) new Builder().MergeFrom(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public sealed partial class Builder : pb::GeneratedBuilder<TestMessageWithCustomOptions, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestMessageWithCustomOptions result = new TestMessageWithCustomOptions();
      
      protected override TestMessageWithCustomOptions MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestMessageWithCustomOptions();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestMessageWithCustomOptions.Descriptor; }
      }
      
      public override TestMessageWithCustomOptions DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestMessageWithCustomOptions.DefaultInstance; }
      }
      
      public override TestMessageWithCustomOptions BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        TestMessageWithCustomOptions returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestMessageWithCustomOptions) {
          return MergeFrom((TestMessageWithCustomOptions) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestMessageWithCustomOptions other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestMessageWithCustomOptions.DefaultInstance) return this;
        if (other.HasField1) {
          Field1 = other.Field1;
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        pb::UnknownFieldSet.Builder unknownFields = null;
        while (true) {
          uint tag = input.ReadTag();
          switch (tag) {
            case 0: {
              if (unknownFields != null) {
                this.UnknownFields = unknownFields.Build();
              }
              return this;
            }
            default: {
              if (pb::WireFormat.IsEndGroupTag(tag)) {
                if (unknownFields != null) {
                  this.UnknownFields = unknownFields.Build();
                }
                return this;
              }
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
              break;
            }
            case 10: {
              Field1 = input.ReadString();
              break;
            }
          }
        }
      }
      
      
      public bool HasField1 {
        get { return result.HasField1; }
      }
      public string Field1 {
        get { return result.Field1; }
        set { SetField1(value); }
      }
      public Builder SetField1(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasField1 = true;
        result.field1_ = value;
        return this;
      }
      public Builder ClearField1() {
        result.hasField1 = false;
        result.field1_ = "";
        return this;
      }
    }
    static TestMessageWithCustomOptions() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public sealed partial class CustomOptionFooRequest : pb::GeneratedMessage<CustomOptionFooRequest, CustomOptionFooRequest.Builder> {
    private static readonly CustomOptionFooRequest defaultInstance = new Builder().BuildPartial();
    public static CustomOptionFooRequest DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override CustomOptionFooRequest DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override CustomOptionFooRequest ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_CustomOptionFooRequest__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<CustomOptionFooRequest, CustomOptionFooRequest.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_CustomOptionFooRequest__FieldAccessorTable; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static CustomOptionFooRequest ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static CustomOptionFooRequest ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static CustomOptionFooRequest ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static CustomOptionFooRequest ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static CustomOptionFooRequest ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static CustomOptionFooRequest ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static CustomOptionFooRequest ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static CustomOptionFooRequest ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static CustomOptionFooRequest ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static CustomOptionFooRequest ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static Builder CreateBuilder() { return new Builder(); }
    public override Builder ToBuilder() { return CreateBuilder(this); }
    public override Builder CreateBuilderForType() { return new Builder(); }
    public static Builder CreateBuilder(CustomOptionFooRequest prototype) {
      return (Builder) new Builder().MergeFrom(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public sealed partial class Builder : pb::GeneratedBuilder<CustomOptionFooRequest, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      CustomOptionFooRequest result = new CustomOptionFooRequest();
      
      protected override CustomOptionFooRequest MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new CustomOptionFooRequest();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.CustomOptionFooRequest.Descriptor; }
      }
      
      public override CustomOptionFooRequest DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.CustomOptionFooRequest.DefaultInstance; }
      }
      
      public override CustomOptionFooRequest BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        CustomOptionFooRequest returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is CustomOptionFooRequest) {
          return MergeFrom((CustomOptionFooRequest) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(CustomOptionFooRequest other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.CustomOptionFooRequest.DefaultInstance) return this;
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        pb::UnknownFieldSet.Builder unknownFields = null;
        while (true) {
          uint tag = input.ReadTag();
          switch (tag) {
            case 0: {
              if (unknownFields != null) {
                this.UnknownFields = unknownFields.Build();
              }
              return this;
            }
            default: {
              if (pb::WireFormat.IsEndGroupTag(tag)) {
                if (unknownFields != null) {
                  this.UnknownFields = unknownFields.Build();
                }
                return this;
              }
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
              break;
            }
          }
        }
      }
      
    }
    static CustomOptionFooRequest() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public sealed partial class CustomOptionFooResponse : pb::GeneratedMessage<CustomOptionFooResponse, CustomOptionFooResponse.Builder> {
    private static readonly CustomOptionFooResponse defaultInstance = new Builder().BuildPartial();
    public static CustomOptionFooResponse DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override CustomOptionFooResponse DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override CustomOptionFooResponse ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_CustomOptionFooResponse__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<CustomOptionFooResponse, CustomOptionFooResponse.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_CustomOptionFooResponse__FieldAccessorTable; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static CustomOptionFooResponse ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static CustomOptionFooResponse ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static CustomOptionFooResponse ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static CustomOptionFooResponse ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static CustomOptionFooResponse ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static CustomOptionFooResponse ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static CustomOptionFooResponse ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static CustomOptionFooResponse ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static CustomOptionFooResponse ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static CustomOptionFooResponse ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static Builder CreateBuilder() { return new Builder(); }
    public override Builder ToBuilder() { return CreateBuilder(this); }
    public override Builder CreateBuilderForType() { return new Builder(); }
    public static Builder CreateBuilder(CustomOptionFooResponse prototype) {
      return (Builder) new Builder().MergeFrom(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public sealed partial class Builder : pb::GeneratedBuilder<CustomOptionFooResponse, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      CustomOptionFooResponse result = new CustomOptionFooResponse();
      
      protected override CustomOptionFooResponse MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new CustomOptionFooResponse();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.CustomOptionFooResponse.Descriptor; }
      }
      
      public override CustomOptionFooResponse DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.CustomOptionFooResponse.DefaultInstance; }
      }
      
      public override CustomOptionFooResponse BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        CustomOptionFooResponse returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is CustomOptionFooResponse) {
          return MergeFrom((CustomOptionFooResponse) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(CustomOptionFooResponse other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.CustomOptionFooResponse.DefaultInstance) return this;
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        pb::UnknownFieldSet.Builder unknownFields = null;
        while (true) {
          uint tag = input.ReadTag();
          switch (tag) {
            case 0: {
              if (unknownFields != null) {
                this.UnknownFields = unknownFields.Build();
              }
              return this;
            }
            default: {
              if (pb::WireFormat.IsEndGroupTag(tag)) {
                if (unknownFields != null) {
                  this.UnknownFields = unknownFields.Build();
                }
                return this;
              }
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
              break;
            }
          }
        }
      }
      
    }
    static CustomOptionFooResponse() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public sealed partial class DummyMessageContainingEnum : pb::GeneratedMessage<DummyMessageContainingEnum, DummyMessageContainingEnum.Builder> {
    private static readonly DummyMessageContainingEnum defaultInstance = new Builder().BuildPartial();
    public static DummyMessageContainingEnum DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override DummyMessageContainingEnum DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override DummyMessageContainingEnum ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_DummyMessageContainingEnum__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<DummyMessageContainingEnum, DummyMessageContainingEnum.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_DummyMessageContainingEnum__FieldAccessorTable; }
    }
    
    #region Nested types
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public static class Types {
      [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
      [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
      public enum TestEnumType {
        TEST_OPTION_ENUM_TYPE1 = 22,
        TEST_OPTION_ENUM_TYPE2 = -23,
      }
      
    }
    #endregion
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static DummyMessageContainingEnum ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static DummyMessageContainingEnum ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static DummyMessageContainingEnum ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static DummyMessageContainingEnum ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static DummyMessageContainingEnum ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static DummyMessageContainingEnum ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static DummyMessageContainingEnum ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static DummyMessageContainingEnum ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static DummyMessageContainingEnum ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static DummyMessageContainingEnum ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static Builder CreateBuilder() { return new Builder(); }
    public override Builder ToBuilder() { return CreateBuilder(this); }
    public override Builder CreateBuilderForType() { return new Builder(); }
    public static Builder CreateBuilder(DummyMessageContainingEnum prototype) {
      return (Builder) new Builder().MergeFrom(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public sealed partial class Builder : pb::GeneratedBuilder<DummyMessageContainingEnum, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      DummyMessageContainingEnum result = new DummyMessageContainingEnum();
      
      protected override DummyMessageContainingEnum MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new DummyMessageContainingEnum();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.DummyMessageContainingEnum.Descriptor; }
      }
      
      public override DummyMessageContainingEnum DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.DummyMessageContainingEnum.DefaultInstance; }
      }
      
      public override DummyMessageContainingEnum BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        DummyMessageContainingEnum returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is DummyMessageContainingEnum) {
          return MergeFrom((DummyMessageContainingEnum) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(DummyMessageContainingEnum other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.DummyMessageContainingEnum.DefaultInstance) return this;
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        pb::UnknownFieldSet.Builder unknownFields = null;
        while (true) {
          uint tag = input.ReadTag();
          switch (tag) {
            case 0: {
              if (unknownFields != null) {
                this.UnknownFields = unknownFields.Build();
              }
              return this;
            }
            default: {
              if (pb::WireFormat.IsEndGroupTag(tag)) {
                if (unknownFields != null) {
                  this.UnknownFields = unknownFields.Build();
                }
                return this;
              }
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
              break;
            }
          }
        }
      }
      
    }
    static DummyMessageContainingEnum() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public sealed partial class DummyMessageInvalidAsOptionType : pb::GeneratedMessage<DummyMessageInvalidAsOptionType, DummyMessageInvalidAsOptionType.Builder> {
    private static readonly DummyMessageInvalidAsOptionType defaultInstance = new Builder().BuildPartial();
    public static DummyMessageInvalidAsOptionType DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override DummyMessageInvalidAsOptionType DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override DummyMessageInvalidAsOptionType ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_DummyMessageInvalidAsOptionType__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<DummyMessageInvalidAsOptionType, DummyMessageInvalidAsOptionType.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_DummyMessageInvalidAsOptionType__FieldAccessorTable; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static DummyMessageInvalidAsOptionType ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static DummyMessageInvalidAsOptionType ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static DummyMessageInvalidAsOptionType ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static DummyMessageInvalidAsOptionType ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static DummyMessageInvalidAsOptionType ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static DummyMessageInvalidAsOptionType ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static DummyMessageInvalidAsOptionType ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static DummyMessageInvalidAsOptionType ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static DummyMessageInvalidAsOptionType ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static DummyMessageInvalidAsOptionType ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static Builder CreateBuilder() { return new Builder(); }
    public override Builder ToBuilder() { return CreateBuilder(this); }
    public override Builder CreateBuilderForType() { return new Builder(); }
    public static Builder CreateBuilder(DummyMessageInvalidAsOptionType prototype) {
      return (Builder) new Builder().MergeFrom(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public sealed partial class Builder : pb::GeneratedBuilder<DummyMessageInvalidAsOptionType, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      DummyMessageInvalidAsOptionType result = new DummyMessageInvalidAsOptionType();
      
      protected override DummyMessageInvalidAsOptionType MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new DummyMessageInvalidAsOptionType();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.DummyMessageInvalidAsOptionType.Descriptor; }
      }
      
      public override DummyMessageInvalidAsOptionType DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.DummyMessageInvalidAsOptionType.DefaultInstance; }
      }
      
      public override DummyMessageInvalidAsOptionType BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        DummyMessageInvalidAsOptionType returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is DummyMessageInvalidAsOptionType) {
          return MergeFrom((DummyMessageInvalidAsOptionType) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(DummyMessageInvalidAsOptionType other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.DummyMessageInvalidAsOptionType.DefaultInstance) return this;
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        pb::UnknownFieldSet.Builder unknownFields = null;
        while (true) {
          uint tag = input.ReadTag();
          switch (tag) {
            case 0: {
              if (unknownFields != null) {
                this.UnknownFields = unknownFields.Build();
              }
              return this;
            }
            default: {
              if (pb::WireFormat.IsEndGroupTag(tag)) {
                if (unknownFields != null) {
                  this.UnknownFields = unknownFields.Build();
                }
                return this;
              }
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
              break;
            }
          }
        }
      }
      
    }
    static DummyMessageInvalidAsOptionType() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public sealed partial class CustomOptionMinIntegerValues : pb::GeneratedMessage<CustomOptionMinIntegerValues, CustomOptionMinIntegerValues.Builder> {
    private static readonly CustomOptionMinIntegerValues defaultInstance = new Builder().BuildPartial();
    public static CustomOptionMinIntegerValues DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override CustomOptionMinIntegerValues DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override CustomOptionMinIntegerValues ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_CustomOptionMinIntegerValues__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<CustomOptionMinIntegerValues, CustomOptionMinIntegerValues.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_CustomOptionMinIntegerValues__FieldAccessorTable; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static CustomOptionMinIntegerValues ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static CustomOptionMinIntegerValues ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static CustomOptionMinIntegerValues ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static CustomOptionMinIntegerValues ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static CustomOptionMinIntegerValues ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static CustomOptionMinIntegerValues ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static CustomOptionMinIntegerValues ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static CustomOptionMinIntegerValues ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static CustomOptionMinIntegerValues ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static CustomOptionMinIntegerValues ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static Builder CreateBuilder() { return new Builder(); }
    public override Builder ToBuilder() { return CreateBuilder(this); }
    public override Builder CreateBuilderForType() { return new Builder(); }
    public static Builder CreateBuilder(CustomOptionMinIntegerValues prototype) {
      return (Builder) new Builder().MergeFrom(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public sealed partial class Builder : pb::GeneratedBuilder<CustomOptionMinIntegerValues, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      CustomOptionMinIntegerValues result = new CustomOptionMinIntegerValues();
      
      protected override CustomOptionMinIntegerValues MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new CustomOptionMinIntegerValues();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.CustomOptionMinIntegerValues.Descriptor; }
      }
      
      public override CustomOptionMinIntegerValues DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.CustomOptionMinIntegerValues.DefaultInstance; }
      }
      
      public override CustomOptionMinIntegerValues BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        CustomOptionMinIntegerValues returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is CustomOptionMinIntegerValues) {
          return MergeFrom((CustomOptionMinIntegerValues) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(CustomOptionMinIntegerValues other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.CustomOptionMinIntegerValues.DefaultInstance) return this;
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        pb::UnknownFieldSet.Builder unknownFields = null;
        while (true) {
          uint tag = input.ReadTag();
          switch (tag) {
            case 0: {
              if (unknownFields != null) {
                this.UnknownFields = unknownFields.Build();
              }
              return this;
            }
            default: {
              if (pb::WireFormat.IsEndGroupTag(tag)) {
                if (unknownFields != null) {
                  this.UnknownFields = unknownFields.Build();
                }
                return this;
              }
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
              break;
            }
          }
        }
      }
      
    }
    static CustomOptionMinIntegerValues() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public sealed partial class CustomOptionMaxIntegerValues : pb::GeneratedMessage<CustomOptionMaxIntegerValues, CustomOptionMaxIntegerValues.Builder> {
    private static readonly CustomOptionMaxIntegerValues defaultInstance = new Builder().BuildPartial();
    public static CustomOptionMaxIntegerValues DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override CustomOptionMaxIntegerValues DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override CustomOptionMaxIntegerValues ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_CustomOptionMaxIntegerValues__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<CustomOptionMaxIntegerValues, CustomOptionMaxIntegerValues.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_CustomOptionMaxIntegerValues__FieldAccessorTable; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static CustomOptionMaxIntegerValues ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static CustomOptionMaxIntegerValues ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static CustomOptionMaxIntegerValues ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static CustomOptionMaxIntegerValues ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static CustomOptionMaxIntegerValues ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static CustomOptionMaxIntegerValues ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static CustomOptionMaxIntegerValues ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static CustomOptionMaxIntegerValues ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static CustomOptionMaxIntegerValues ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static CustomOptionMaxIntegerValues ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static Builder CreateBuilder() { return new Builder(); }
    public override Builder ToBuilder() { return CreateBuilder(this); }
    public override Builder CreateBuilderForType() { return new Builder(); }
    public static Builder CreateBuilder(CustomOptionMaxIntegerValues prototype) {
      return (Builder) new Builder().MergeFrom(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public sealed partial class Builder : pb::GeneratedBuilder<CustomOptionMaxIntegerValues, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      CustomOptionMaxIntegerValues result = new CustomOptionMaxIntegerValues();
      
      protected override CustomOptionMaxIntegerValues MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new CustomOptionMaxIntegerValues();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.CustomOptionMaxIntegerValues.Descriptor; }
      }
      
      public override CustomOptionMaxIntegerValues DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.CustomOptionMaxIntegerValues.DefaultInstance; }
      }
      
      public override CustomOptionMaxIntegerValues BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        CustomOptionMaxIntegerValues returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is CustomOptionMaxIntegerValues) {
          return MergeFrom((CustomOptionMaxIntegerValues) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(CustomOptionMaxIntegerValues other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.CustomOptionMaxIntegerValues.DefaultInstance) return this;
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        pb::UnknownFieldSet.Builder unknownFields = null;
        while (true) {
          uint tag = input.ReadTag();
          switch (tag) {
            case 0: {
              if (unknownFields != null) {
                this.UnknownFields = unknownFields.Build();
              }
              return this;
            }
            default: {
              if (pb::WireFormat.IsEndGroupTag(tag)) {
                if (unknownFields != null) {
                  this.UnknownFields = unknownFields.Build();
                }
                return this;
              }
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
              break;
            }
          }
        }
      }
      
    }
    static CustomOptionMaxIntegerValues() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public sealed partial class CustomOptionOtherValues : pb::GeneratedMessage<CustomOptionOtherValues, CustomOptionOtherValues.Builder> {
    private static readonly CustomOptionOtherValues defaultInstance = new Builder().BuildPartial();
    public static CustomOptionOtherValues DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override CustomOptionOtherValues DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override CustomOptionOtherValues ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_CustomOptionOtherValues__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<CustomOptionOtherValues, CustomOptionOtherValues.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_CustomOptionOtherValues__FieldAccessorTable; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static CustomOptionOtherValues ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static CustomOptionOtherValues ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static CustomOptionOtherValues ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static CustomOptionOtherValues ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static CustomOptionOtherValues ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static CustomOptionOtherValues ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static CustomOptionOtherValues ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static CustomOptionOtherValues ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static CustomOptionOtherValues ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static CustomOptionOtherValues ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static Builder CreateBuilder() { return new Builder(); }
    public override Builder ToBuilder() { return CreateBuilder(this); }
    public override Builder CreateBuilderForType() { return new Builder(); }
    public static Builder CreateBuilder(CustomOptionOtherValues prototype) {
      return (Builder) new Builder().MergeFrom(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public sealed partial class Builder : pb::GeneratedBuilder<CustomOptionOtherValues, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      CustomOptionOtherValues result = new CustomOptionOtherValues();
      
      protected override CustomOptionOtherValues MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new CustomOptionOtherValues();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.CustomOptionOtherValues.Descriptor; }
      }
      
      public override CustomOptionOtherValues DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.CustomOptionOtherValues.DefaultInstance; }
      }
      
      public override CustomOptionOtherValues BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        CustomOptionOtherValues returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is CustomOptionOtherValues) {
          return MergeFrom((CustomOptionOtherValues) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(CustomOptionOtherValues other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.CustomOptionOtherValues.DefaultInstance) return this;
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        pb::UnknownFieldSet.Builder unknownFields = null;
        while (true) {
          uint tag = input.ReadTag();
          switch (tag) {
            case 0: {
              if (unknownFields != null) {
                this.UnknownFields = unknownFields.Build();
              }
              return this;
            }
            default: {
              if (pb::WireFormat.IsEndGroupTag(tag)) {
                if (unknownFields != null) {
                  this.UnknownFields = unknownFields.Build();
                }
                return this;
              }
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
              break;
            }
          }
        }
      }
      
    }
    static CustomOptionOtherValues() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public sealed partial class SettingRealsFromPositiveInts : pb::GeneratedMessage<SettingRealsFromPositiveInts, SettingRealsFromPositiveInts.Builder> {
    private static readonly SettingRealsFromPositiveInts defaultInstance = new Builder().BuildPartial();
    public static SettingRealsFromPositiveInts DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override SettingRealsFromPositiveInts DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override SettingRealsFromPositiveInts ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_SettingRealsFromPositiveInts__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<SettingRealsFromPositiveInts, SettingRealsFromPositiveInts.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_SettingRealsFromPositiveInts__FieldAccessorTable; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static SettingRealsFromPositiveInts ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static SettingRealsFromPositiveInts ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static SettingRealsFromPositiveInts ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static SettingRealsFromPositiveInts ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static SettingRealsFromPositiveInts ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static SettingRealsFromPositiveInts ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static SettingRealsFromPositiveInts ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static SettingRealsFromPositiveInts ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static SettingRealsFromPositiveInts ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static SettingRealsFromPositiveInts ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static Builder CreateBuilder() { return new Builder(); }
    public override Builder ToBuilder() { return CreateBuilder(this); }
    public override Builder CreateBuilderForType() { return new Builder(); }
    public static Builder CreateBuilder(SettingRealsFromPositiveInts prototype) {
      return (Builder) new Builder().MergeFrom(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public sealed partial class Builder : pb::GeneratedBuilder<SettingRealsFromPositiveInts, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      SettingRealsFromPositiveInts result = new SettingRealsFromPositiveInts();
      
      protected override SettingRealsFromPositiveInts MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new SettingRealsFromPositiveInts();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.SettingRealsFromPositiveInts.Descriptor; }
      }
      
      public override SettingRealsFromPositiveInts DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.SettingRealsFromPositiveInts.DefaultInstance; }
      }
      
      public override SettingRealsFromPositiveInts BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        SettingRealsFromPositiveInts returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is SettingRealsFromPositiveInts) {
          return MergeFrom((SettingRealsFromPositiveInts) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(SettingRealsFromPositiveInts other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.SettingRealsFromPositiveInts.DefaultInstance) return this;
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        pb::UnknownFieldSet.Builder unknownFields = null;
        while (true) {
          uint tag = input.ReadTag();
          switch (tag) {
            case 0: {
              if (unknownFields != null) {
                this.UnknownFields = unknownFields.Build();
              }
              return this;
            }
            default: {
              if (pb::WireFormat.IsEndGroupTag(tag)) {
                if (unknownFields != null) {
                  this.UnknownFields = unknownFields.Build();
                }
                return this;
              }
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
              break;
            }
          }
        }
      }
      
    }
    static SettingRealsFromPositiveInts() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public sealed partial class SettingRealsFromNegativeInts : pb::GeneratedMessage<SettingRealsFromNegativeInts, SettingRealsFromNegativeInts.Builder> {
    private static readonly SettingRealsFromNegativeInts defaultInstance = new Builder().BuildPartial();
    public static SettingRealsFromNegativeInts DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override SettingRealsFromNegativeInts DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override SettingRealsFromNegativeInts ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_SettingRealsFromNegativeInts__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<SettingRealsFromNegativeInts, SettingRealsFromNegativeInts.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_SettingRealsFromNegativeInts__FieldAccessorTable; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static SettingRealsFromNegativeInts ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static SettingRealsFromNegativeInts ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static SettingRealsFromNegativeInts ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static SettingRealsFromNegativeInts ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static SettingRealsFromNegativeInts ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static SettingRealsFromNegativeInts ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static SettingRealsFromNegativeInts ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static SettingRealsFromNegativeInts ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static SettingRealsFromNegativeInts ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static SettingRealsFromNegativeInts ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static Builder CreateBuilder() { return new Builder(); }
    public override Builder ToBuilder() { return CreateBuilder(this); }
    public override Builder CreateBuilderForType() { return new Builder(); }
    public static Builder CreateBuilder(SettingRealsFromNegativeInts prototype) {
      return (Builder) new Builder().MergeFrom(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public sealed partial class Builder : pb::GeneratedBuilder<SettingRealsFromNegativeInts, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      SettingRealsFromNegativeInts result = new SettingRealsFromNegativeInts();
      
      protected override SettingRealsFromNegativeInts MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new SettingRealsFromNegativeInts();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.SettingRealsFromNegativeInts.Descriptor; }
      }
      
      public override SettingRealsFromNegativeInts DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.SettingRealsFromNegativeInts.DefaultInstance; }
      }
      
      public override SettingRealsFromNegativeInts BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        SettingRealsFromNegativeInts returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is SettingRealsFromNegativeInts) {
          return MergeFrom((SettingRealsFromNegativeInts) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(SettingRealsFromNegativeInts other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.SettingRealsFromNegativeInts.DefaultInstance) return this;
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        pb::UnknownFieldSet.Builder unknownFields = null;
        while (true) {
          uint tag = input.ReadTag();
          switch (tag) {
            case 0: {
              if (unknownFields != null) {
                this.UnknownFields = unknownFields.Build();
              }
              return this;
            }
            default: {
              if (pb::WireFormat.IsEndGroupTag(tag)) {
                if (unknownFields != null) {
                  this.UnknownFields = unknownFields.Build();
                }
                return this;
              }
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
              break;
            }
          }
        }
      }
      
    }
    static SettingRealsFromNegativeInts() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public sealed partial class ComplexOptionType1 : pb::ExtendableMessage<ComplexOptionType1, ComplexOptionType1.Builder> {
    private static readonly ComplexOptionType1 defaultInstance = new Builder().BuildPartial();
    public static ComplexOptionType1 DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override ComplexOptionType1 DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override ComplexOptionType1 ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_ComplexOptionType1__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<ComplexOptionType1, ComplexOptionType1.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_ComplexOptionType1__FieldAccessorTable; }
    }
    
    public const int FooFieldNumber = 1;
    private bool hasFoo;
    private int foo_ = 0;
    public bool HasFoo {
      get { return hasFoo; }
    }
    public int Foo {
      get { return foo_; }
    }
    
    public const int Foo2FieldNumber = 2;
    private bool hasFoo2;
    private int foo2_ = 0;
    public bool HasFoo2 {
      get { return hasFoo2; }
    }
    public int Foo2 {
      get { return foo2_; }
    }
    
    public const int Foo3FieldNumber = 3;
    private bool hasFoo3;
    private int foo3_ = 0;
    public bool HasFoo3 {
      get { return hasFoo3; }
    }
    public int Foo3 {
      get { return foo3_; }
    }
    
    public override bool IsInitialized {
      get {
        if (!ExtensionsAreInitialized) return false;
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      pb::ExtendableMessage<ComplexOptionType1, ComplexOptionType1.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
      if (HasFoo) {
        output.WriteInt32(1, "foo", Foo);
      }
      if (HasFoo2) {
        output.WriteInt32(2, "foo2", Foo2);
      }
      if (HasFoo3) {
        output.WriteInt32(3, "foo3", Foo3);
      }
      extensionWriter.WriteUntil(536870912, output);
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasFoo) {
          size += pb::CodedOutputStream.ComputeInt32Size(1, Foo);
        }
        if (HasFoo2) {
          size += pb::CodedOutputStream.ComputeInt32Size(2, Foo2);
        }
        if (HasFoo3) {
          size += pb::CodedOutputStream.ComputeInt32Size(3, Foo3);
        }
        size += ExtensionsSerializedSize;
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static ComplexOptionType1 ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static ComplexOptionType1 ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static ComplexOptionType1 ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static ComplexOptionType1 ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static ComplexOptionType1 ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static ComplexOptionType1 ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static ComplexOptionType1 ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static ComplexOptionType1 ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static ComplexOptionType1 ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static ComplexOptionType1 ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static Builder CreateBuilder() { return new Builder(); }
    public override Builder ToBuilder() { return CreateBuilder(this); }
    public override Builder CreateBuilderForType() { return new Builder(); }
    public static Builder CreateBuilder(ComplexOptionType1 prototype) {
      return (Builder) new Builder().MergeFrom(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public sealed partial class Builder : pb::ExtendableBuilder<ComplexOptionType1, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      ComplexOptionType1 result = new ComplexOptionType1();
      
      protected override ComplexOptionType1 MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new ComplexOptionType1();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1.Descriptor; }
      }
      
      public override ComplexOptionType1 DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1.DefaultInstance; }
      }
      
      public override ComplexOptionType1 BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        ComplexOptionType1 returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is ComplexOptionType1) {
          return MergeFrom((ComplexOptionType1) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(ComplexOptionType1 other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1.DefaultInstance) return this;
        if (other.HasFoo) {
          Foo = other.Foo;
        }
        if (other.HasFoo2) {
          Foo2 = other.Foo2;
        }
        if (other.HasFoo3) {
          Foo3 = other.Foo3;
        }
          this.MergeExtensionFields(other);
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        pb::UnknownFieldSet.Builder unknownFields = null;
        while (true) {
          uint tag = input.ReadTag();
          switch (tag) {
            case 0: {
              if (unknownFields != null) {
                this.UnknownFields = unknownFields.Build();
              }
              return this;
            }
            default: {
              if (pb::WireFormat.IsEndGroupTag(tag)) {
                if (unknownFields != null) {
                  this.UnknownFields = unknownFields.Build();
                }
                return this;
              }
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
              break;
            }
            case 8: {
              Foo = input.ReadInt32();
              break;
            }
            case 16: {
              Foo2 = input.ReadInt32();
              break;
            }
            case 24: {
              Foo3 = input.ReadInt32();
              break;
            }
          }
        }
      }
      
      
      public bool HasFoo {
        get { return result.HasFoo; }
      }
      public int Foo {
        get { return result.Foo; }
        set { SetFoo(value); }
      }
      public Builder SetFoo(int value) {
        result.hasFoo = true;
        result.foo_ = value;
        return this;
      }
      public Builder ClearFoo() {
        result.hasFoo = false;
        result.foo_ = 0;
        return this;
      }
      
      public bool HasFoo2 {
        get { return result.HasFoo2; }
      }
      public int Foo2 {
        get { return result.Foo2; }
        set { SetFoo2(value); }
      }
      public Builder SetFoo2(int value) {
        result.hasFoo2 = true;
        result.foo2_ = value;
        return this;
      }
      public Builder ClearFoo2() {
        result.hasFoo2 = false;
        result.foo2_ = 0;
        return this;
      }
      
      public bool HasFoo3 {
        get { return result.HasFoo3; }
      }
      public int Foo3 {
        get { return result.Foo3; }
        set { SetFoo3(value); }
      }
      public Builder SetFoo3(int value) {
        result.hasFoo3 = true;
        result.foo3_ = value;
        return this;
      }
      public Builder ClearFoo3() {
        result.hasFoo3 = false;
        result.foo3_ = 0;
        return this;
      }
    }
    static ComplexOptionType1() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public sealed partial class ComplexOptionType2 : pb::ExtendableMessage<ComplexOptionType2, ComplexOptionType2.Builder> {
    private static readonly ComplexOptionType2 defaultInstance = new Builder().BuildPartial();
    public static ComplexOptionType2 DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override ComplexOptionType2 DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override ComplexOptionType2 ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_ComplexOptionType2__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<ComplexOptionType2, ComplexOptionType2.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_ComplexOptionType2__FieldAccessorTable; }
    }
    
    #region Nested types
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public static class Types {
      [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
      [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
      [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
      public sealed partial class ComplexOptionType4 : pb::GeneratedMessage<ComplexOptionType4, ComplexOptionType4.Builder> {
        private static readonly ComplexOptionType4 defaultInstance = new Builder().BuildPartial();
        public static ComplexOptionType4 DefaultInstance {
          get { return defaultInstance; }
        }
        
        public override ComplexOptionType4 DefaultInstanceForType {
          get { return defaultInstance; }
        }
        
        protected override ComplexOptionType4 ThisMessage {
          get { return this; }
        }
        
        public static pbd::MessageDescriptor Descriptor {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_ComplexOptionType2_ComplexOptionType4__Descriptor; }
        }
        
        protected override pb::FieldAccess.FieldAccessorTable<ComplexOptionType4, ComplexOptionType4.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_ComplexOptionType2_ComplexOptionType4__FieldAccessorTable; }
        }
        
        public const int ComplexOpt4FieldNumber = 7633546;
        public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4> ComplexOpt4;
        public const int WaldoFieldNumber = 1;
        private bool hasWaldo;
        private int waldo_ = 0;
        public bool HasWaldo {
          get { return hasWaldo; }
        }
        public int Waldo {
          get { return waldo_; }
        }
        
        public override bool IsInitialized {
          get {
            return true;
          }
        }
        
        public override void WriteTo(pb::ICodedOutputStream output) {
          int size = SerializedSize;
          if (HasWaldo) {
            output.WriteInt32(1, "waldo", Waldo);
          }
          UnknownFields.WriteTo(output);
        }
        
        private int memoizedSerializedSize = -1;
        public override int SerializedSize {
          get {
            int size = memoizedSerializedSize;
            if (size != -1) return size;
            
            size = 0;
            if (HasWaldo) {
              size += pb::CodedOutputStream.ComputeInt32Size(1, Waldo);
            }
            size += UnknownFields.SerializedSize;
            memoizedSerializedSize = size;
            return size;
          }
        }
        
        public static ComplexOptionType4 ParseFrom(pb::ByteString data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static ComplexOptionType4 ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static ComplexOptionType4 ParseFrom(byte[] data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static ComplexOptionType4 ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static ComplexOptionType4 ParseFrom(global::System.IO.Stream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static ComplexOptionType4 ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static ComplexOptionType4 ParseDelimitedFrom(global::System.IO.Stream input) {
          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
        }
        public static ComplexOptionType4 ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
        }
        public static ComplexOptionType4 ParseFrom(pb::CodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static ComplexOptionType4 ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static Builder CreateBuilder() { return new Builder(); }
        public override Builder ToBuilder() { return CreateBuilder(this); }
        public override Builder CreateBuilderForType() { return new Builder(); }
        public static Builder CreateBuilder(ComplexOptionType4 prototype) {
          return (Builder) new Builder().MergeFrom(prototype);
        }
        
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
        public sealed partial class Builder : pb::GeneratedBuilder<ComplexOptionType4, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {}
          
          ComplexOptionType4 result = new ComplexOptionType4();
          
          protected override ComplexOptionType4 MessageBeingBuilt {
            get { return result; }
          }
          
          public override Builder Clear() {
            result = new ComplexOptionType4();
            return this;
          }
          
          public override Builder Clone() {
            return new Builder().MergeFrom(result);
          }
          
          public override pbd::MessageDescriptor DescriptorForType {
            get { return global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4.Descriptor; }
          }
          
          public override ComplexOptionType4 DefaultInstanceForType {
            get { return global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4.DefaultInstance; }
          }
          
          public override ComplexOptionType4 BuildPartial() {
            if (result == null) {
              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
            }
            ComplexOptionType4 returnMe = result;
            result = null;
            return returnMe;
          }
          
          public override Builder MergeFrom(pb::IMessage other) {
            if (other is ComplexOptionType4) {
              return MergeFrom((ComplexOptionType4) other);
            } else {
              base.MergeFrom(other);
              return this;
            }
          }
          
          public override Builder MergeFrom(ComplexOptionType4 other) {
            if (other == global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4.DefaultInstance) return this;
            if (other.HasWaldo) {
              Waldo = other.Waldo;
            }
            this.MergeUnknownFields(other.UnknownFields);
            return this;
          }
          
          public override Builder MergeFrom(pb::CodedInputStream input) {
            return MergeFrom(input, pb::ExtensionRegistry.Empty);
          }
          
          public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
            pb::UnknownFieldSet.Builder unknownFields = null;
            while (true) {
              uint tag = input.ReadTag();
              switch (tag) {
                case 0: {
                  if (unknownFields != null) {
                    this.UnknownFields = unknownFields.Build();
                  }
                  return this;
                }
                default: {
                  if (pb::WireFormat.IsEndGroupTag(tag)) {
                    if (unknownFields != null) {
                      this.UnknownFields = unknownFields.Build();
                    }
                    return this;
                  }
                  if (unknownFields == null) {
                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                  }
                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);
                  break;
                }
                case 8: {
                  Waldo = input.ReadInt32();
                  break;
                }
              }
            }
          }
          
          
          public bool HasWaldo {
            get { return result.HasWaldo; }
          }
          public int Waldo {
            get { return result.Waldo; }
            set { SetWaldo(value); }
          }
          public Builder SetWaldo(int value) {
            result.hasWaldo = true;
            result.waldo_ = value;
            return this;
          }
          public Builder ClearWaldo() {
            result.hasWaldo = false;
            result.waldo_ = 0;
            return this;
          }
        }
        static ComplexOptionType4() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor, null);
        }
      }
      
    }
    #endregion
    
    public const int BarFieldNumber = 1;
    private bool hasBar;
    private global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1 bar_ = global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1.DefaultInstance;
    public bool HasBar {
      get { return hasBar; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1 Bar {
      get { return bar_; }
    }
    
    public const int BazFieldNumber = 2;
    private bool hasBaz;
    private int baz_ = 0;
    public bool HasBaz {
      get { return hasBaz; }
    }
    public int Baz {
      get { return baz_; }
    }
    
    public const int FredFieldNumber = 3;
    private bool hasFred;
    private global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4 fred_ = global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4.DefaultInstance;
    public bool HasFred {
      get { return hasFred; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4 Fred {
      get { return fred_; }
    }
    
    public override bool IsInitialized {
      get {
        if (HasFred) {
          if (!Fred.IsInitialized) return false;
        }
        if (!ExtensionsAreInitialized) return false;
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      pb::ExtendableMessage<ComplexOptionType2, ComplexOptionType2.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
      if (HasBar) {
        output.WriteMessage(1, "bar", Bar);
      }
      if (HasBaz) {
        output.WriteInt32(2, "baz", Baz);
      }
      if (HasFred) {
        output.WriteMessage(3, "fred", Fred);
      }
      extensionWriter.WriteUntil(536870912, output);
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasBar) {
          size += pb::CodedOutputStream.ComputeMessageSize(1, Bar);
        }
        if (HasBaz) {
          size += pb::CodedOutputStream.ComputeInt32Size(2, Baz);
        }
        if (HasFred) {
          size += pb::CodedOutputStream.ComputeMessageSize(3, Fred);
        }
        size += ExtensionsSerializedSize;
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static ComplexOptionType2 ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static ComplexOptionType2 ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static ComplexOptionType2 ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static ComplexOptionType2 ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static ComplexOptionType2 ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static ComplexOptionType2 ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static ComplexOptionType2 ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static ComplexOptionType2 ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static ComplexOptionType2 ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static ComplexOptionType2 ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static Builder CreateBuilder() { return new Builder(); }
    public override Builder ToBuilder() { return CreateBuilder(this); }
    public override Builder CreateBuilderForType() { return new Builder(); }
    public static Builder CreateBuilder(ComplexOptionType2 prototype) {
      return (Builder) new Builder().MergeFrom(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public sealed partial class Builder : pb::ExtendableBuilder<ComplexOptionType2, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      ComplexOptionType2 result = new ComplexOptionType2();
      
      protected override ComplexOptionType2 MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new ComplexOptionType2();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Descriptor; }
      }
      
      public override ComplexOptionType2 DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.DefaultInstance; }
      }
      
      public override ComplexOptionType2 BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        ComplexOptionType2 returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is ComplexOptionType2) {
          return MergeFrom((ComplexOptionType2) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(ComplexOptionType2 other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.DefaultInstance) return this;
        if (other.HasBar) {
          MergeBar(other.Bar);
        }
        if (other.HasBaz) {
          Baz = other.Baz;
        }
        if (other.HasFred) {
          MergeFred(other.Fred);
        }
          this.MergeExtensionFields(other);
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        pb::UnknownFieldSet.Builder unknownFields = null;
        while (true) {
          uint tag = input.ReadTag();
          switch (tag) {
            case 0: {
              if (unknownFields != null) {
                this.UnknownFields = unknownFields.Build();
              }
              return this;
            }
            default: {
              if (pb::WireFormat.IsEndGroupTag(tag)) {
                if (unknownFields != null) {
                  this.UnknownFields = unknownFields.Build();
                }
                return this;
              }
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
              break;
            }
            case 10: {
              global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1.CreateBuilder();
              if (HasBar) {
                subBuilder.MergeFrom(Bar);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              Bar = subBuilder.BuildPartial();
              break;
            }
            case 16: {
              Baz = input.ReadInt32();
              break;
            }
            case 26: {
              global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4.CreateBuilder();
              if (HasFred) {
                subBuilder.MergeFrom(Fred);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              Fred = subBuilder.BuildPartial();
              break;
            }
          }
        }
      }
      
      
      public bool HasBar {
       get { return result.HasBar; }
      }
      public global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1 Bar {
        get { return result.Bar; }
        set { SetBar(value); }
      }
      public Builder SetBar(global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1 value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasBar = true;
        result.bar_ = value;
        return this;
      }
      public Builder SetBar(global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.hasBar = true;
        result.bar_ = builderForValue.Build();
        return this;
      }
      public Builder MergeBar(global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1 value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        if (result.HasBar &&
            result.bar_ != global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1.DefaultInstance) {
            result.bar_ = global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1.CreateBuilder(result.bar_).MergeFrom(value).BuildPartial();
        } else {
          result.bar_ = value;
        }
        result.hasBar = true;
        return this;
      }
      public Builder ClearBar() {
        result.hasBar = false;
        result.bar_ = global::Google.ProtocolBuffers.TestProtos.ComplexOptionType1.DefaultInstance;
        return this;
      }
      
      public bool HasBaz {
        get { return result.HasBaz; }
      }
      public int Baz {
        get { return result.Baz; }
        set { SetBaz(value); }
      }
      public Builder SetBaz(int value) {
        result.hasBaz = true;
        result.baz_ = value;
        return this;
      }
      public Builder ClearBaz() {
        result.hasBaz = false;
        result.baz_ = 0;
        return this;
      }
      
      public bool HasFred {
       get { return result.HasFred; }
      }
      public global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4 Fred {
        get { return result.Fred; }
        set { SetFred(value); }
      }
      public Builder SetFred(global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4 value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasFred = true;
        result.fred_ = value;
        return this;
      }
      public Builder SetFred(global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.hasFred = true;
        result.fred_ = builderForValue.Build();
        return this;
      }
      public Builder MergeFred(global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4 value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        if (result.HasFred &&
            result.fred_ != global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4.DefaultInstance) {
            result.fred_ = global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4.CreateBuilder(result.fred_).MergeFrom(value).BuildPartial();
        } else {
          result.fred_ = value;
        }
        result.hasFred = true;
        return this;
      }
      public Builder ClearFred() {
        result.hasFred = false;
        result.fred_ = global::Google.ProtocolBuffers.TestProtos.ComplexOptionType2.Types.ComplexOptionType4.DefaultInstance;
        return this;
      }
    }
    static ComplexOptionType2() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public sealed partial class ComplexOptionType3 : pb::GeneratedMessage<ComplexOptionType3, ComplexOptionType3.Builder> {
    private static readonly ComplexOptionType3 defaultInstance = new Builder().BuildPartial();
    public static ComplexOptionType3 DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override ComplexOptionType3 DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override ComplexOptionType3 ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_ComplexOptionType3__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<ComplexOptionType3, ComplexOptionType3.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_ComplexOptionType3__FieldAccessorTable; }
    }
    
    #region Nested types
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public static class Types {
      [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
      [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
      [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
      public sealed partial class ComplexOptionType5 : pb::GeneratedMessage<ComplexOptionType5, ComplexOptionType5.Builder> {
        private static readonly ComplexOptionType5 defaultInstance = new Builder().BuildPartial();
        public static ComplexOptionType5 DefaultInstance {
          get { return defaultInstance; }
        }
        
        public override ComplexOptionType5 DefaultInstanceForType {
          get { return defaultInstance; }
        }
        
        protected override ComplexOptionType5 ThisMessage {
          get { return this; }
        }
        
        public static pbd::MessageDescriptor Descriptor {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_ComplexOptionType3_ComplexOptionType5__Descriptor; }
        }
        
        protected override pb::FieldAccess.FieldAccessorTable<ComplexOptionType5, ComplexOptionType5.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_ComplexOptionType3_ComplexOptionType5__FieldAccessorTable; }
        }
        
        public const int PlughFieldNumber = 3;
        private bool hasPlugh;
        private int plugh_ = 0;
        public bool HasPlugh {
          get { return hasPlugh; }
        }
        public int Plugh {
          get { return plugh_; }
        }
        
        public override bool IsInitialized {
          get {
            return true;
          }
        }
        
        public override void WriteTo(pb::ICodedOutputStream output) {
          int size = SerializedSize;
          if (HasPlugh) {
            output.WriteInt32(3, "plugh", Plugh);
          }
          UnknownFields.WriteTo(output);
        }
        
        private int memoizedSerializedSize = -1;
        public override int SerializedSize {
          get {
            int size = memoizedSerializedSize;
            if (size != -1) return size;
            
            size = 0;
            if (HasPlugh) {
              size += pb::CodedOutputStream.ComputeInt32Size(3, Plugh);
            }
            size += UnknownFields.SerializedSize;
            memoizedSerializedSize = size;
            return size;
          }
        }
        
        public static ComplexOptionType5 ParseFrom(pb::ByteString data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static ComplexOptionType5 ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static ComplexOptionType5 ParseFrom(byte[] data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static ComplexOptionType5 ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static ComplexOptionType5 ParseFrom(global::System.IO.Stream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static ComplexOptionType5 ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static ComplexOptionType5 ParseDelimitedFrom(global::System.IO.Stream input) {
          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
        }
        public static ComplexOptionType5 ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
        }
        public static ComplexOptionType5 ParseFrom(pb::CodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static ComplexOptionType5 ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static Builder CreateBuilder() { return new Builder(); }
        public override Builder ToBuilder() { return CreateBuilder(this); }
        public override Builder CreateBuilderForType() { return new Builder(); }
        public static Builder CreateBuilder(ComplexOptionType5 prototype) {
          return (Builder) new Builder().MergeFrom(prototype);
        }
        
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
        public sealed partial class Builder : pb::GeneratedBuilder<ComplexOptionType5, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {}
          
          ComplexOptionType5 result = new ComplexOptionType5();
          
          protected override ComplexOptionType5 MessageBeingBuilt {
            get { return result; }
          }
          
          public override Builder Clear() {
            result = new ComplexOptionType5();
            return this;
          }
          
          public override Builder Clone() {
            return new Builder().MergeFrom(result);
          }
          
          public override pbd::MessageDescriptor DescriptorForType {
            get { return global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5.Descriptor; }
          }
          
          public override ComplexOptionType5 DefaultInstanceForType {
            get { return global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5.DefaultInstance; }
          }
          
          public override ComplexOptionType5 BuildPartial() {
            if (result == null) {
              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
            }
            ComplexOptionType5 returnMe = result;
            result = null;
            return returnMe;
          }
          
          public override Builder MergeFrom(pb::IMessage other) {
            if (other is ComplexOptionType5) {
              return MergeFrom((ComplexOptionType5) other);
            } else {
              base.MergeFrom(other);
              return this;
            }
          }
          
          public override Builder MergeFrom(ComplexOptionType5 other) {
            if (other == global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5.DefaultInstance) return this;
            if (other.HasPlugh) {
              Plugh = other.Plugh;
            }
            this.MergeUnknownFields(other.UnknownFields);
            return this;
          }
          
          public override Builder MergeFrom(pb::CodedInputStream input) {
            return MergeFrom(input, pb::ExtensionRegistry.Empty);
          }
          
          public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
            pb::UnknownFieldSet.Builder unknownFields = null;
            while (true) {
              uint tag = input.ReadTag();
              switch (tag) {
                case 0: {
                  if (unknownFields != null) {
                    this.UnknownFields = unknownFields.Build();
                  }
                  return this;
                }
                default: {
                  if (pb::WireFormat.IsEndGroupTag(tag)) {
                    if (unknownFields != null) {
                      this.UnknownFields = unknownFields.Build();
                    }
                    return this;
                  }
                  if (unknownFields == null) {
                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                  }
                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);
                  break;
                }
                case 24: {
                  Plugh = input.ReadInt32();
                  break;
                }
              }
            }
          }
          
          
          public bool HasPlugh {
            get { return result.HasPlugh; }
          }
          public int Plugh {
            get { return result.Plugh; }
            set { SetPlugh(value); }
          }
          public Builder SetPlugh(int value) {
            result.hasPlugh = true;
            result.plugh_ = value;
            return this;
          }
          public Builder ClearPlugh() {
            result.hasPlugh = false;
            result.plugh_ = 0;
            return this;
          }
        }
        static ComplexOptionType5() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor, null);
        }
      }
      
    }
    #endregion
    
    public const int QuxFieldNumber = 1;
    private bool hasQux;
    private int qux_ = 0;
    public bool HasQux {
      get { return hasQux; }
    }
    public int Qux {
      get { return qux_; }
    }
    
    public const int ComplexOptionType5FieldNumber = 2;
    private bool hasComplexOptionType5;
    private global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5 complexOptionType5_ = global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5.DefaultInstance;
    public bool HasComplexOptionType5 {
      get { return hasComplexOptionType5; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5 ComplexOptionType5 {
      get { return complexOptionType5_; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (HasQux) {
        output.WriteInt32(1, "qux", Qux);
      }
      if (HasComplexOptionType5) {
        output.WriteGroup(2, "complexoptiontype5", ComplexOptionType5);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasQux) {
          size += pb::CodedOutputStream.ComputeInt32Size(1, Qux);
        }
        if (HasComplexOptionType5) {
          size += pb::CodedOutputStream.ComputeGroupSize(2, ComplexOptionType5);
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static ComplexOptionType3 ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static ComplexOptionType3 ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static ComplexOptionType3 ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static ComplexOptionType3 ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static ComplexOptionType3 ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static ComplexOptionType3 ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static ComplexOptionType3 ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static ComplexOptionType3 ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static ComplexOptionType3 ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static ComplexOptionType3 ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static Builder CreateBuilder() { return new Builder(); }
    public override Builder ToBuilder() { return CreateBuilder(this); }
    public override Builder CreateBuilderForType() { return new Builder(); }
    public static Builder CreateBuilder(ComplexOptionType3 prototype) {
      return (Builder) new Builder().MergeFrom(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public sealed partial class Builder : pb::GeneratedBuilder<ComplexOptionType3, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      ComplexOptionType3 result = new ComplexOptionType3();
      
      protected override ComplexOptionType3 MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new ComplexOptionType3();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Descriptor; }
      }
      
      public override ComplexOptionType3 DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.DefaultInstance; }
      }
      
      public override ComplexOptionType3 BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        ComplexOptionType3 returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is ComplexOptionType3) {
          return MergeFrom((ComplexOptionType3) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(ComplexOptionType3 other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.DefaultInstance) return this;
        if (other.HasQux) {
          Qux = other.Qux;
        }
        if (other.HasComplexOptionType5) {
          MergeComplexOptionType5(other.ComplexOptionType5);
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        pb::UnknownFieldSet.Builder unknownFields = null;
        while (true) {
          uint tag = input.ReadTag();
          switch (tag) {
            case 0: {
              if (unknownFields != null) {
                this.UnknownFields = unknownFields.Build();
              }
              return this;
            }
            default: {
              if (pb::WireFormat.IsEndGroupTag(tag)) {
                if (unknownFields != null) {
                  this.UnknownFields = unknownFields.Build();
                }
                return this;
              }
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
              break;
            }
            case 8: {
              Qux = input.ReadInt32();
              break;
            }
            case 19: {
              global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5.CreateBuilder();
              if (HasComplexOptionType5) {
                subBuilder.MergeFrom(ComplexOptionType5);
              }
              input.ReadGroup(2, subBuilder, extensionRegistry);
              ComplexOptionType5 = subBuilder.BuildPartial();
              break;
            }
          }
        }
      }
      
      
      public bool HasQux {
        get { return result.HasQux; }
      }
      public int Qux {
        get { return result.Qux; }
        set { SetQux(value); }
      }
      public Builder SetQux(int value) {
        result.hasQux = true;
        result.qux_ = value;
        return this;
      }
      public Builder ClearQux() {
        result.hasQux = false;
        result.qux_ = 0;
        return this;
      }
      
      public bool HasComplexOptionType5 {
       get { return result.HasComplexOptionType5; }
      }
      public global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5 ComplexOptionType5 {
        get { return result.ComplexOptionType5; }
        set { SetComplexOptionType5(value); }
      }
      public Builder SetComplexOptionType5(global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5 value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasComplexOptionType5 = true;
        result.complexOptionType5_ = value;
        return this;
      }
      public Builder SetComplexOptionType5(global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.hasComplexOptionType5 = true;
        result.complexOptionType5_ = builderForValue.Build();
        return this;
      }
      public Builder MergeComplexOptionType5(global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5 value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        if (result.HasComplexOptionType5 &&
            result.complexOptionType5_ != global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5.DefaultInstance) {
            result.complexOptionType5_ = global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5.CreateBuilder(result.complexOptionType5_).MergeFrom(value).BuildPartial();
        } else {
          result.complexOptionType5_ = value;
        }
        result.hasComplexOptionType5 = true;
        return this;
      }
      public Builder ClearComplexOptionType5() {
        result.hasComplexOptionType5 = false;
        result.complexOptionType5_ = global::Google.ProtocolBuffers.TestProtos.ComplexOptionType3.Types.ComplexOptionType5.DefaultInstance;
        return this;
      }
    }
    static ComplexOptionType3() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public sealed partial class ComplexOpt6 : pb::GeneratedMessage<ComplexOpt6, ComplexOpt6.Builder> {
    private static readonly ComplexOpt6 defaultInstance = new Builder().BuildPartial();
    public static ComplexOpt6 DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override ComplexOpt6 DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override ComplexOpt6 ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_ComplexOpt6__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<ComplexOpt6, ComplexOpt6.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_ComplexOpt6__FieldAccessorTable; }
    }
    
    public const int XyzzyFieldNumber = 7593951;
    private bool hasXyzzy;
    private int xyzzy_ = 0;
    public bool HasXyzzy {
      get { return hasXyzzy; }
    }
    public int Xyzzy {
      get { return xyzzy_; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (HasXyzzy) {
        output.WriteInt32(7593951, "xyzzy", Xyzzy);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasXyzzy) {
          size += pb::CodedOutputStream.ComputeInt32Size(7593951, Xyzzy);
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static ComplexOpt6 ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static ComplexOpt6 ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static ComplexOpt6 ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static ComplexOpt6 ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static ComplexOpt6 ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static ComplexOpt6 ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static ComplexOpt6 ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static ComplexOpt6 ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static ComplexOpt6 ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static ComplexOpt6 ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static Builder CreateBuilder() { return new Builder(); }
    public override Builder ToBuilder() { return CreateBuilder(this); }
    public override Builder CreateBuilderForType() { return new Builder(); }
    public static Builder CreateBuilder(ComplexOpt6 prototype) {
      return (Builder) new Builder().MergeFrom(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public sealed partial class Builder : pb::GeneratedBuilder<ComplexOpt6, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      ComplexOpt6 result = new ComplexOpt6();
      
      protected override ComplexOpt6 MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new ComplexOpt6();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.ComplexOpt6.Descriptor; }
      }
      
      public override ComplexOpt6 DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.ComplexOpt6.DefaultInstance; }
      }
      
      public override ComplexOpt6 BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        ComplexOpt6 returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is ComplexOpt6) {
          return MergeFrom((ComplexOpt6) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(ComplexOpt6 other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.ComplexOpt6.DefaultInstance) return this;
        if (other.HasXyzzy) {
          Xyzzy = other.Xyzzy;
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        pb::UnknownFieldSet.Builder unknownFields = null;
        while (true) {
          uint tag = input.ReadTag();
          switch (tag) {
            case 0: {
              if (unknownFields != null) {
                this.UnknownFields = unknownFields.Build();
              }
              return this;
            }
            default: {
              if (pb::WireFormat.IsEndGroupTag(tag)) {
                if (unknownFields != null) {
                  this.UnknownFields = unknownFields.Build();
                }
                return this;
              }
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
              break;
            }
            case 60751608: {
              Xyzzy = input.ReadInt32();
              break;
            }
          }
        }
      }
      
      
      public bool HasXyzzy {
        get { return result.HasXyzzy; }
      }
      public int Xyzzy {
        get { return result.Xyzzy; }
        set { SetXyzzy(value); }
      }
      public Builder SetXyzzy(int value) {
        result.hasXyzzy = true;
        result.xyzzy_ = value;
        return this;
      }
      public Builder ClearXyzzy() {
        result.hasXyzzy = false;
        result.xyzzy_ = 0;
        return this;
      }
    }
    static ComplexOpt6() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public sealed partial class VariousComplexOptions : pb::GeneratedMessage<VariousComplexOptions, VariousComplexOptions.Builder> {
    private static readonly VariousComplexOptions defaultInstance = new Builder().BuildPartial();
    public static VariousComplexOptions DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override VariousComplexOptions DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override VariousComplexOptions ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_VariousComplexOptions__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<VariousComplexOptions, VariousComplexOptions.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.internal__static_protobuf_unittest_VariousComplexOptions__FieldAccessorTable; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static VariousComplexOptions ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static VariousComplexOptions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static VariousComplexOptions ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static VariousComplexOptions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static VariousComplexOptions ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static VariousComplexOptions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static VariousComplexOptions ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static VariousComplexOptions ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static VariousComplexOptions ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static VariousComplexOptions ParseFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static Builder CreateBuilder() { return new Builder(); }
    public override Builder ToBuilder() { return CreateBuilder(this); }
    public override Builder CreateBuilderForType() { return new Builder(); }
    public static Builder CreateBuilder(VariousComplexOptions prototype) {
      return (Builder) new Builder().MergeFrom(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public sealed partial class Builder : pb::GeneratedBuilder<VariousComplexOptions, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      VariousComplexOptions result = new VariousComplexOptions();
      
      protected override VariousComplexOptions MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new VariousComplexOptions();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.VariousComplexOptions.Descriptor; }
      }
      
      public override VariousComplexOptions DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.VariousComplexOptions.DefaultInstance; }
      }
      
      public override VariousComplexOptions BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        VariousComplexOptions returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is VariousComplexOptions) {
          return MergeFrom((VariousComplexOptions) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(VariousComplexOptions other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.VariousComplexOptions.DefaultInstance) return this;
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        pb::UnknownFieldSet.Builder unknownFields = null;
        while (true) {
          uint tag = input.ReadTag();
          switch (tag) {
            case 0: {
              if (unknownFields != null) {
                this.UnknownFields = unknownFields.Build();
              }
              return this;
            }
            default: {
              if (pb::WireFormat.IsEndGroupTag(tag)) {
                if (unknownFields != null) {
                  this.UnknownFields = unknownFields.Build();
                }
                return this;
              }
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag);
              break;
            }
          }
        }
      }
      
    }
    static VariousComplexOptions() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestCustomOptionsProtoFile.Descriptor, null);
    }
  }
  
  #endregion
  
  #region Services
  /*
  * Service generation is now disabled by default, use the following option to enable:
  * option (google.protobuf.csharp_file_options).service_generator_type = GENERIC;
  */
  #endregion
  
}
