// 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 UnitTestProtoFile {
  
    #region Extension registration
    public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalInt32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalInt64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalUint32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalUint64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalSint32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalSint64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalFixed32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalFixed64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalSfixed32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalSfixed64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalFloatExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalDoubleExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalBoolExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalStringExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalBytesExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalGroupExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalNestedMessageExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalForeignMessageExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalImportMessageExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalNestedEnumExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalForeignEnumExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalImportEnumExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalStringPieceExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalCordExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedInt32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedInt64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedUint32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedUint64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedSint32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedSint64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedFixed32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedFixed64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedSfixed32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedSfixed64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedFloatExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedDoubleExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedBoolExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedStringExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedBytesExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedGroupExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedNestedMessageExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedForeignMessageExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedImportMessageExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedNestedEnumExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedForeignEnumExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedImportEnumExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedStringPieceExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedCordExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultInt32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultInt64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultUint32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultUint64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultSint32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultSint64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultFixed32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultFixed64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultSfixed32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultSfixed64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultFloatExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultDoubleExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultBoolExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultStringExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultBytesExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultNestedEnumExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultForeignEnumExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultImportEnumExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultStringPieceExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultCordExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.MyExtensionString);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.MyExtensionInt);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedInt32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedInt64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedUint32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedUint64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedSint32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedSint64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedFixed32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedFixed64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedSfixed32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedSfixed64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedFloatExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedDoubleExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedBoolExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedEnumExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.TestNestedExtension.Test);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.TestRequired.Single);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.TestRequired.Multi);
    }
    #endregion
    #region Extensions
    public const int OptionalInt32ExtensionFieldNumber = 1;
    public static pb::GeneratedExtensionBase<int> OptionalInt32Extension;
    public const int OptionalInt64ExtensionFieldNumber = 2;
    public static pb::GeneratedExtensionBase<long> OptionalInt64Extension;
    public const int OptionalUint32ExtensionFieldNumber = 3;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<uint> OptionalUint32Extension;
    public const int OptionalUint64ExtensionFieldNumber = 4;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<ulong> OptionalUint64Extension;
    public const int OptionalSint32ExtensionFieldNumber = 5;
    public static pb::GeneratedExtensionBase<int> OptionalSint32Extension;
    public const int OptionalSint64ExtensionFieldNumber = 6;
    public static pb::GeneratedExtensionBase<long> OptionalSint64Extension;
    public const int OptionalFixed32ExtensionFieldNumber = 7;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<uint> OptionalFixed32Extension;
    public const int OptionalFixed64ExtensionFieldNumber = 8;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<ulong> OptionalFixed64Extension;
    public const int OptionalSfixed32ExtensionFieldNumber = 9;
    public static pb::GeneratedExtensionBase<int> OptionalSfixed32Extension;
    public const int OptionalSfixed64ExtensionFieldNumber = 10;
    public static pb::GeneratedExtensionBase<long> OptionalSfixed64Extension;
    public const int OptionalFloatExtensionFieldNumber = 11;
    public static pb::GeneratedExtensionBase<float> OptionalFloatExtension;
    public const int OptionalDoubleExtensionFieldNumber = 12;
    public static pb::GeneratedExtensionBase<double> OptionalDoubleExtension;
    public const int OptionalBoolExtensionFieldNumber = 13;
    public static pb::GeneratedExtensionBase<bool> OptionalBoolExtension;
    public const int OptionalStringExtensionFieldNumber = 14;
    public static pb::GeneratedExtensionBase<string> OptionalStringExtension;
    public const int OptionalBytesExtensionFieldNumber = 15;
    public static pb::GeneratedExtensionBase<pb::ByteString> OptionalBytesExtension;
    public const int OptionalGroupExtensionFieldNumber = 16;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.OptionalGroup_extension> OptionalGroupExtension;
    public const int OptionalNestedMessageExtensionFieldNumber = 18;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage> OptionalNestedMessageExtension;
    public const int OptionalForeignMessageExtensionFieldNumber = 19;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.ForeignMessage> OptionalForeignMessageExtension;
    public const int OptionalImportMessageExtensionFieldNumber = 20;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.ImportMessage> OptionalImportMessageExtension;
    public const int OptionalNestedEnumExtensionFieldNumber = 21;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum> OptionalNestedEnumExtension;
    public const int OptionalForeignEnumExtensionFieldNumber = 22;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> OptionalForeignEnumExtension;
    public const int OptionalImportEnumExtensionFieldNumber = 23;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.ImportEnum> OptionalImportEnumExtension;
    public const int OptionalStringPieceExtensionFieldNumber = 24;
    public static pb::GeneratedExtensionBase<string> OptionalStringPieceExtension;
    public const int OptionalCordExtensionFieldNumber = 25;
    public static pb::GeneratedExtensionBase<string> OptionalCordExtension;
    public const int RepeatedInt32ExtensionFieldNumber = 31;
    public static pb::GeneratedExtensionBase<scg::IList<int>> RepeatedInt32Extension;
    public const int RepeatedInt64ExtensionFieldNumber = 32;
    public static pb::GeneratedExtensionBase<scg::IList<long>> RepeatedInt64Extension;
    public const int RepeatedUint32ExtensionFieldNumber = 33;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<scg::IList<uint>> RepeatedUint32Extension;
    public const int RepeatedUint64ExtensionFieldNumber = 34;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<scg::IList<ulong>> RepeatedUint64Extension;
    public const int RepeatedSint32ExtensionFieldNumber = 35;
    public static pb::GeneratedExtensionBase<scg::IList<int>> RepeatedSint32Extension;
    public const int RepeatedSint64ExtensionFieldNumber = 36;
    public static pb::GeneratedExtensionBase<scg::IList<long>> RepeatedSint64Extension;
    public const int RepeatedFixed32ExtensionFieldNumber = 37;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<scg::IList<uint>> RepeatedFixed32Extension;
    public const int RepeatedFixed64ExtensionFieldNumber = 38;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<scg::IList<ulong>> RepeatedFixed64Extension;
    public const int RepeatedSfixed32ExtensionFieldNumber = 39;
    public static pb::GeneratedExtensionBase<scg::IList<int>> RepeatedSfixed32Extension;
    public const int RepeatedSfixed64ExtensionFieldNumber = 40;
    public static pb::GeneratedExtensionBase<scg::IList<long>> RepeatedSfixed64Extension;
    public const int RepeatedFloatExtensionFieldNumber = 41;
    public static pb::GeneratedExtensionBase<scg::IList<float>> RepeatedFloatExtension;
    public const int RepeatedDoubleExtensionFieldNumber = 42;
    public static pb::GeneratedExtensionBase<scg::IList<double>> RepeatedDoubleExtension;
    public const int RepeatedBoolExtensionFieldNumber = 43;
    public static pb::GeneratedExtensionBase<scg::IList<bool>> RepeatedBoolExtension;
    public const int RepeatedStringExtensionFieldNumber = 44;
    public static pb::GeneratedExtensionBase<scg::IList<string>> RepeatedStringExtension;
    public const int RepeatedBytesExtensionFieldNumber = 45;
    public static pb::GeneratedExtensionBase<scg::IList<pb::ByteString>> RepeatedBytesExtension;
    public const int RepeatedGroupExtensionFieldNumber = 46;
    public static pb::GeneratedExtensionBase<scg::IList<global::Google.ProtocolBuffers.TestProtos.RepeatedGroup_extension>> RepeatedGroupExtension;
    public const int RepeatedNestedMessageExtensionFieldNumber = 48;
    public static pb::GeneratedExtensionBase<scg::IList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage>> RepeatedNestedMessageExtension;
    public const int RepeatedForeignMessageExtensionFieldNumber = 49;
    public static pb::GeneratedExtensionBase<scg::IList<global::Google.ProtocolBuffers.TestProtos.ForeignMessage>> RepeatedForeignMessageExtension;
    public const int RepeatedImportMessageExtensionFieldNumber = 50;
    public static pb::GeneratedExtensionBase<scg::IList<global::Google.ProtocolBuffers.TestProtos.ImportMessage>> RepeatedImportMessageExtension;
    public const int RepeatedNestedEnumExtensionFieldNumber = 51;
    public static pb::GeneratedExtensionBase<scg::IList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum>> RepeatedNestedEnumExtension;
    public const int RepeatedForeignEnumExtensionFieldNumber = 52;
    public static pb::GeneratedExtensionBase<scg::IList<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>> RepeatedForeignEnumExtension;
    public const int RepeatedImportEnumExtensionFieldNumber = 53;
    public static pb::GeneratedExtensionBase<scg::IList<global::Google.ProtocolBuffers.TestProtos.ImportEnum>> RepeatedImportEnumExtension;
    public const int RepeatedStringPieceExtensionFieldNumber = 54;
    public static pb::GeneratedExtensionBase<scg::IList<string>> RepeatedStringPieceExtension;
    public const int RepeatedCordExtensionFieldNumber = 55;
    public static pb::GeneratedExtensionBase<scg::IList<string>> RepeatedCordExtension;
    public const int DefaultInt32ExtensionFieldNumber = 61;
    public static pb::GeneratedExtensionBase<int> DefaultInt32Extension;
    public const int DefaultInt64ExtensionFieldNumber = 62;
    public static pb::GeneratedExtensionBase<long> DefaultInt64Extension;
    public const int DefaultUint32ExtensionFieldNumber = 63;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<uint> DefaultUint32Extension;
    public const int DefaultUint64ExtensionFieldNumber = 64;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<ulong> DefaultUint64Extension;
    public const int DefaultSint32ExtensionFieldNumber = 65;
    public static pb::GeneratedExtensionBase<int> DefaultSint32Extension;
    public const int DefaultSint64ExtensionFieldNumber = 66;
    public static pb::GeneratedExtensionBase<long> DefaultSint64Extension;
    public const int DefaultFixed32ExtensionFieldNumber = 67;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<uint> DefaultFixed32Extension;
    public const int DefaultFixed64ExtensionFieldNumber = 68;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<ulong> DefaultFixed64Extension;
    public const int DefaultSfixed32ExtensionFieldNumber = 69;
    public static pb::GeneratedExtensionBase<int> DefaultSfixed32Extension;
    public const int DefaultSfixed64ExtensionFieldNumber = 70;
    public static pb::GeneratedExtensionBase<long> DefaultSfixed64Extension;
    public const int DefaultFloatExtensionFieldNumber = 71;
    public static pb::GeneratedExtensionBase<float> DefaultFloatExtension;
    public const int DefaultDoubleExtensionFieldNumber = 72;
    public static pb::GeneratedExtensionBase<double> DefaultDoubleExtension;
    public const int DefaultBoolExtensionFieldNumber = 73;
    public static pb::GeneratedExtensionBase<bool> DefaultBoolExtension;
    public const int DefaultStringExtensionFieldNumber = 74;
    public static pb::GeneratedExtensionBase<string> DefaultStringExtension;
    public const int DefaultBytesExtensionFieldNumber = 75;
    public static pb::GeneratedExtensionBase<pb::ByteString> DefaultBytesExtension;
    public const int DefaultNestedEnumExtensionFieldNumber = 81;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum> DefaultNestedEnumExtension;
    public const int DefaultForeignEnumExtensionFieldNumber = 82;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> DefaultForeignEnumExtension;
    public const int DefaultImportEnumExtensionFieldNumber = 83;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.ImportEnum> DefaultImportEnumExtension;
    public const int DefaultStringPieceExtensionFieldNumber = 84;
    public static pb::GeneratedExtensionBase<string> DefaultStringPieceExtension;
    public const int DefaultCordExtensionFieldNumber = 85;
    public static pb::GeneratedExtensionBase<string> DefaultCordExtension;
    public const int MyExtensionStringFieldNumber = 50;
    public static pb::GeneratedExtensionBase<string> MyExtensionString;
    public const int MyExtensionIntFieldNumber = 5;
    public static pb::GeneratedExtensionBase<int> MyExtensionInt;
    public const int PackedInt32ExtensionFieldNumber = 90;
    public static pb::GeneratedExtensionBase<scg::IList<int>> PackedInt32Extension;
    public const int PackedInt64ExtensionFieldNumber = 91;
    public static pb::GeneratedExtensionBase<scg::IList<long>> PackedInt64Extension;
    public const int PackedUint32ExtensionFieldNumber = 92;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<scg::IList<uint>> PackedUint32Extension;
    public const int PackedUint64ExtensionFieldNumber = 93;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<scg::IList<ulong>> PackedUint64Extension;
    public const int PackedSint32ExtensionFieldNumber = 94;
    public static pb::GeneratedExtensionBase<scg::IList<int>> PackedSint32Extension;
    public const int PackedSint64ExtensionFieldNumber = 95;
    public static pb::GeneratedExtensionBase<scg::IList<long>> PackedSint64Extension;
    public const int PackedFixed32ExtensionFieldNumber = 96;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<scg::IList<uint>> PackedFixed32Extension;
    public const int PackedFixed64ExtensionFieldNumber = 97;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<scg::IList<ulong>> PackedFixed64Extension;
    public const int PackedSfixed32ExtensionFieldNumber = 98;
    public static pb::GeneratedExtensionBase<scg::IList<int>> PackedSfixed32Extension;
    public const int PackedSfixed64ExtensionFieldNumber = 99;
    public static pb::GeneratedExtensionBase<scg::IList<long>> PackedSfixed64Extension;
    public const int PackedFloatExtensionFieldNumber = 100;
    public static pb::GeneratedExtensionBase<scg::IList<float>> PackedFloatExtension;
    public const int PackedDoubleExtensionFieldNumber = 101;
    public static pb::GeneratedExtensionBase<scg::IList<double>> PackedDoubleExtension;
    public const int PackedBoolExtensionFieldNumber = 102;
    public static pb::GeneratedExtensionBase<scg::IList<bool>> PackedBoolExtension;
    public const int PackedEnumExtensionFieldNumber = 103;
    public static pb::GeneratedExtensionBase<scg::IList<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>> PackedEnumExtension;
    #endregion
    
    #region Static variables
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestAllTypes__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder> internal__static_protobuf_unittest_TestAllTypes__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestAllTypes_NestedMessage__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.Builder> internal__static_protobuf_unittest_TestAllTypes_NestedMessage__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestAllTypes_OptionalGroup__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.OptionalGroup, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.OptionalGroup.Builder> internal__static_protobuf_unittest_TestAllTypes_OptionalGroup__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestAllTypes_RepeatedGroup__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup.Builder> internal__static_protobuf_unittest_TestAllTypes_RepeatedGroup__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestDeprecatedFields__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestDeprecatedFields, global::Google.ProtocolBuffers.TestProtos.TestDeprecatedFields.Builder> internal__static_protobuf_unittest_TestDeprecatedFields__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_ForeignMessage__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.ForeignMessage, global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder> internal__static_protobuf_unittest_ForeignMessage__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestAllExtensions__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestAllExtensions, global::Google.ProtocolBuffers.TestProtos.TestAllExtensions.Builder> internal__static_protobuf_unittest_TestAllExtensions__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_OptionalGroup_extension__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.OptionalGroup_extension, global::Google.ProtocolBuffers.TestProtos.OptionalGroup_extension.Builder> internal__static_protobuf_unittest_OptionalGroup_extension__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_RepeatedGroup_extension__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.RepeatedGroup_extension, global::Google.ProtocolBuffers.TestProtos.RepeatedGroup_extension.Builder> internal__static_protobuf_unittest_RepeatedGroup_extension__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestNestedExtension__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestNestedExtension, global::Google.ProtocolBuffers.TestProtos.TestNestedExtension.Builder> internal__static_protobuf_unittest_TestNestedExtension__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestRequired__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestRequired, global::Google.ProtocolBuffers.TestProtos.TestRequired.Builder> internal__static_protobuf_unittest_TestRequired__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestRequiredForeign__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestRequiredForeign, global::Google.ProtocolBuffers.TestProtos.TestRequiredForeign.Builder> internal__static_protobuf_unittest_TestRequiredForeign__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestForeignNested__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestForeignNested, global::Google.ProtocolBuffers.TestProtos.TestForeignNested.Builder> internal__static_protobuf_unittest_TestForeignNested__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestEmptyMessage__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestEmptyMessage, global::Google.ProtocolBuffers.TestProtos.TestEmptyMessage.Builder> internal__static_protobuf_unittest_TestEmptyMessage__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestEmptyMessageWithExtensions__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestEmptyMessageWithExtensions, global::Google.ProtocolBuffers.TestProtos.TestEmptyMessageWithExtensions.Builder> internal__static_protobuf_unittest_TestEmptyMessageWithExtensions__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestMultipleExtensionRanges__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestMultipleExtensionRanges, global::Google.ProtocolBuffers.TestProtos.TestMultipleExtensionRanges.Builder> internal__static_protobuf_unittest_TestMultipleExtensionRanges__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestReallyLargeTagNumber__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestReallyLargeTagNumber, global::Google.ProtocolBuffers.TestProtos.TestReallyLargeTagNumber.Builder> internal__static_protobuf_unittest_TestReallyLargeTagNumber__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestRecursiveMessage__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestRecursiveMessage, global::Google.ProtocolBuffers.TestProtos.TestRecursiveMessage.Builder> internal__static_protobuf_unittest_TestRecursiveMessage__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestMutualRecursionA__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionA, global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionA.Builder> internal__static_protobuf_unittest_TestMutualRecursionA__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestMutualRecursionB__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionB, global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionB.Builder> internal__static_protobuf_unittest_TestMutualRecursionB__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestDupFieldNumber__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber, global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Builder> internal__static_protobuf_unittest_TestDupFieldNumber__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestDupFieldNumber_Foo__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Foo, global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Foo.Builder> internal__static_protobuf_unittest_TestDupFieldNumber_Foo__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestDupFieldNumber_Bar__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Bar, global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Bar.Builder> internal__static_protobuf_unittest_TestDupFieldNumber_Bar__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestNestedMessageHasBits__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits, global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Builder> internal__static_protobuf_unittest_TestNestedMessageHasBits__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestNestedMessageHasBits_NestedMessage__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Types.NestedMessage, global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Types.NestedMessage.Builder> internal__static_protobuf_unittest_TestNestedMessageHasBits_NestedMessage__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestCamelCaseFieldNames__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestCamelCaseFieldNames, global::Google.ProtocolBuffers.TestProtos.TestCamelCaseFieldNames.Builder> internal__static_protobuf_unittest_TestCamelCaseFieldNames__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestFieldOrderings__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestFieldOrderings, global::Google.ProtocolBuffers.TestProtos.TestFieldOrderings.Builder> internal__static_protobuf_unittest_TestFieldOrderings__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestExtremeDefaultValues__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestExtremeDefaultValues, global::Google.ProtocolBuffers.TestProtos.TestExtremeDefaultValues.Builder> internal__static_protobuf_unittest_TestExtremeDefaultValues__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_OneString__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.OneString, global::Google.ProtocolBuffers.TestProtos.OneString.Builder> internal__static_protobuf_unittest_OneString__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_OneBytes__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.OneBytes, global::Google.ProtocolBuffers.TestProtos.OneBytes.Builder> internal__static_protobuf_unittest_OneBytes__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestPackedTypes__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestPackedTypes, global::Google.ProtocolBuffers.TestProtos.TestPackedTypes.Builder> internal__static_protobuf_unittest_TestPackedTypes__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestUnpackedTypes__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestUnpackedTypes, global::Google.ProtocolBuffers.TestProtos.TestUnpackedTypes.Builder> internal__static_protobuf_unittest_TestUnpackedTypes__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestPackedExtensions__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestPackedExtensions, global::Google.ProtocolBuffers.TestProtos.TestPackedExtensions.Builder> internal__static_protobuf_unittest_TestPackedExtensions__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestDynamicExtensions__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions, global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Builder> internal__static_protobuf_unittest_TestDynamicExtensions__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestDynamicExtensions_DynamicMessageType__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicMessageType, global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicMessageType.Builder> internal__static_protobuf_unittest_TestDynamicExtensions_DynamicMessageType__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestRepeatedScalarDifferentTagSizes__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestRepeatedScalarDifferentTagSizes, global::Google.ProtocolBuffers.TestProtos.TestRepeatedScalarDifferentTagSizes.Builder> internal__static_protobuf_unittest_TestRepeatedScalarDifferentTagSizes__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_FooRequest__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.FooRequest, global::Google.ProtocolBuffers.TestProtos.FooRequest.Builder> internal__static_protobuf_unittest_FooRequest__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_FooResponse__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.FooResponse, global::Google.ProtocolBuffers.TestProtos.FooResponse.Builder> internal__static_protobuf_unittest_FooResponse__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_BarRequest__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.BarRequest, global::Google.ProtocolBuffers.TestProtos.BarRequest.Builder> internal__static_protobuf_unittest_BarRequest__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_BarResponse__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.BarResponse, global::Google.ProtocolBuffers.TestProtos.BarResponse.Builder> internal__static_protobuf_unittest_BarResponse__FieldAccessorTable;
    #endregion
    #region Descriptor
    public static pbd::FileDescriptor Descriptor {
      get { return descriptor; }
    }
    private static pbd::FileDescriptor descriptor;
    
    static UnitTestProtoFile() {
      byte[] descriptorData = global::System.Convert.FromBase64String(
          "Ch5nb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8SEXByb3RvYnVmX3Vu" + 
          "aXR0ZXN0GiRnb29nbGUvcHJvdG9idWYvY3NoYXJwX29wdGlvbnMucHJvdG8a" + 
          "JWdvb2dsZS9wcm90b2J1Zi91bml0dGVzdF9pbXBvcnQucHJvdG8iuxUKDFRl" + 
          "c3RBbGxUeXBlcxIWCg5vcHRpb25hbF9pbnQzMhgBIAEoBRIWCg5vcHRpb25h" + 
          "bF9pbnQ2NBgCIAEoAxIXCg9vcHRpb25hbF91aW50MzIYAyABKA0SFwoPb3B0" + 
          "aW9uYWxfdWludDY0GAQgASgEEhcKD29wdGlvbmFsX3NpbnQzMhgFIAEoERIX" + 
          "Cg9vcHRpb25hbF9zaW50NjQYBiABKBISGAoQb3B0aW9uYWxfZml4ZWQzMhgH" + 
          "IAEoBxIYChBvcHRpb25hbF9maXhlZDY0GAggASgGEhkKEW9wdGlvbmFsX3Nm" + 
          "aXhlZDMyGAkgASgPEhkKEW9wdGlvbmFsX3NmaXhlZDY0GAogASgQEhYKDm9w" + 
          "dGlvbmFsX2Zsb2F0GAsgASgCEhcKD29wdGlvbmFsX2RvdWJsZRgMIAEoARIV" + 
          "Cg1vcHRpb25hbF9ib29sGA0gASgIEhcKD29wdGlvbmFsX3N0cmluZxgOIAEo" + 
          "CRIWCg5vcHRpb25hbF9ieXRlcxgPIAEoDBJECg1vcHRpb25hbGdyb3VwGBAg" + 
          "ASgKMi0ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk9wdGlvbmFs" + 
          "R3JvdXASTgoXb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2UYEiABKAsyLS5wcm90" + 
          "b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZRJDChhv" + 
          "cHRpb25hbF9mb3JlaWduX21lc3NhZ2UYEyABKAsyIS5wcm90b2J1Zl91bml0" + 
          "dGVzdC5Gb3JlaWduTWVzc2FnZRJIChdvcHRpb25hbF9pbXBvcnRfbWVzc2Fn" + 
          "ZRgUIAEoCzInLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRNZXNz" + 
          "YWdlEkgKFG9wdGlvbmFsX25lc3RlZF9lbnVtGBUgASgOMioucHJvdG9idWZf" + 
          "dW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW0SPQoVb3B0aW9uYWxf" + 
          "Zm9yZWlnbl9lbnVtGBYgASgOMh4ucHJvdG9idWZfdW5pdHRlc3QuRm9yZWln" + 
          "bkVudW0SQgoUb3B0aW9uYWxfaW1wb3J0X2VudW0YFyABKA4yJC5wcm90b2J1" + 
          "Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bRIhChVvcHRpb25hbF9zdHJp" + 
          "bmdfcGllY2UYGCABKAlCAggCEhkKDW9wdGlvbmFsX2NvcmQYGSABKAlCAggB" + 
          "EhYKDnJlcGVhdGVkX2ludDMyGB8gAygFEhYKDnJlcGVhdGVkX2ludDY0GCAg" + 
          "AygDEhcKD3JlcGVhdGVkX3VpbnQzMhghIAMoDRIXCg9yZXBlYXRlZF91aW50" + 
          "NjQYIiADKAQSFwoPcmVwZWF0ZWRfc2ludDMyGCMgAygREhcKD3JlcGVhdGVk" + 
          "X3NpbnQ2NBgkIAMoEhIYChByZXBlYXRlZF9maXhlZDMyGCUgAygHEhgKEHJl" + 
          "cGVhdGVkX2ZpeGVkNjQYJiADKAYSGQoRcmVwZWF0ZWRfc2ZpeGVkMzIYJyAD" + 
          "KA8SGQoRcmVwZWF0ZWRfc2ZpeGVkNjQYKCADKBASFgoOcmVwZWF0ZWRfZmxv" + 
          "YXQYKSADKAISFwoPcmVwZWF0ZWRfZG91YmxlGCogAygBEhUKDXJlcGVhdGVk" + 
          "X2Jvb2wYKyADKAgSFwoPcmVwZWF0ZWRfc3RyaW5nGCwgAygJEhYKDnJlcGVh" + 
          "dGVkX2J5dGVzGC0gAygMEkQKDXJlcGVhdGVkZ3JvdXAYLiADKAoyLS5wcm90" + 
          "b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuUmVwZWF0ZWRHcm91cBJOChdy" + 
          "ZXBlYXRlZF9uZXN0ZWRfbWVzc2FnZRgwIAMoCzItLnByb3RvYnVmX3VuaXR0" + 
          "ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlEkMKGHJlcGVhdGVkX2Zv" + 
          "cmVpZ25fbWVzc2FnZRgxIAMoCzIhLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVp" + 
          "Z25NZXNzYWdlEkgKF3JlcGVhdGVkX2ltcG9ydF9tZXNzYWdlGDIgAygLMicu" + 
          "cHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2USSAoUcmVw" + 
          "ZWF0ZWRfbmVzdGVkX2VudW0YMyADKA4yKi5wcm90b2J1Zl91bml0dGVzdC5U" + 
          "ZXN0QWxsVHlwZXMuTmVzdGVkRW51bRI9ChVyZXBlYXRlZF9mb3JlaWduX2Vu" + 
          "dW0YNCADKA4yHi5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bRJCChRy" + 
          "ZXBlYXRlZF9pbXBvcnRfZW51bRg1IAMoDjIkLnByb3RvYnVmX3VuaXR0ZXN0" + 
          "X2ltcG9ydC5JbXBvcnRFbnVtEiEKFXJlcGVhdGVkX3N0cmluZ19waWVjZRg2" + 
          "IAMoCUICCAISGQoNcmVwZWF0ZWRfY29yZBg3IAMoCUICCAESGQoNZGVmYXVs" + 
          "dF9pbnQzMhg9IAEoBToCNDESGQoNZGVmYXVsdF9pbnQ2NBg+IAEoAzoCNDIS" + 
          "GgoOZGVmYXVsdF91aW50MzIYPyABKA06AjQzEhoKDmRlZmF1bHRfdWludDY0" + 
          "GEAgASgEOgI0NBIbCg5kZWZhdWx0X3NpbnQzMhhBIAEoEToDLTQ1EhoKDmRl" + 
          "ZmF1bHRfc2ludDY0GEIgASgSOgI0NhIbCg9kZWZhdWx0X2ZpeGVkMzIYQyAB" + 
          "KAc6AjQ3EhsKD2RlZmF1bHRfZml4ZWQ2NBhEIAEoBjoCNDgSHAoQZGVmYXVs" + 
          "dF9zZml4ZWQzMhhFIAEoDzoCNDkSHQoQZGVmYXVsdF9zZml4ZWQ2NBhGIAEo" + 
          "EDoDLTUwEhsKDWRlZmF1bHRfZmxvYXQYRyABKAI6BDUxLjUSHQoOZGVmYXVs" + 
          "dF9kb3VibGUYSCABKAE6BTUyMDAwEhoKDGRlZmF1bHRfYm9vbBhJIAEoCDoE" + 
          "dHJ1ZRIdCg5kZWZhdWx0X3N0cmluZxhKIAEoCToFaGVsbG8SHAoNZGVmYXVs" + 
          "dF9ieXRlcxhLIAEoDDoFd29ybGQSTAoTZGVmYXVsdF9uZXN0ZWRfZW51bRhR" + 
          "IAEoDjIqLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRF" + 
          "bnVtOgNCQVISSQoUZGVmYXVsdF9mb3JlaWduX2VudW0YUiABKA4yHi5wcm90" + 
          "b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bToLRk9SRUlHTl9CQVISTQoTZGVm" + 
          "YXVsdF9pbXBvcnRfZW51bRhTIAEoDjIkLnByb3RvYnVmX3VuaXR0ZXN0X2lt" + 
          "cG9ydC5JbXBvcnRFbnVtOgpJTVBPUlRfQkFSEiUKFGRlZmF1bHRfc3RyaW5n" + 
          "X3BpZWNlGFQgASgJOgNhYmNCAggCEh0KDGRlZmF1bHRfY29yZBhVIAEoCToD" + 
          "MTIzQgIIARobCg1OZXN0ZWRNZXNzYWdlEgoKAmJiGAEgASgFGhoKDU9wdGlv" + 
          "bmFsR3JvdXASCQoBYRgRIAEoBRoaCg1SZXBlYXRlZEdyb3VwEgkKAWEYLyAB" + 
          "KAUiJwoKTmVzdGVkRW51bRIHCgNGT08QARIHCgNCQVIQAhIHCgNCQVoQAyI0" + 
          "ChRUZXN0RGVwcmVjYXRlZEZpZWxkcxIcChBkZXByZWNhdGVkX2ludDMyGAEg" + 
          "ASgFQgIYASIbCg5Gb3JlaWduTWVzc2FnZRIJCgFjGAEgASgFIh0KEVRlc3RB" + 
          "bGxFeHRlbnNpb25zKggIARCAgICAAiIkChdPcHRpb25hbEdyb3VwX2V4dGVu" + 
          "c2lvbhIJCgFhGBEgASgFIiQKF1JlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uEgkK" + 
          "AWEYLyABKAUiUAoTVGVzdE5lc3RlZEV4dGVuc2lvbjI5CgR0ZXN0EiQucHJv" + 
          "dG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMY6gcgASgJOgR0ZXN0" + 
          "ItUFCgxUZXN0UmVxdWlyZWQSCQoBYRgBIAIoBRIOCgZkdW1teTIYAiABKAUS" + 
          "CQoBYhgDIAIoBRIOCgZkdW1teTQYBCABKAUSDgoGZHVtbXk1GAUgASgFEg4K" + 
          "BmR1bW15NhgGIAEoBRIOCgZkdW1teTcYByABKAUSDgoGZHVtbXk4GAggASgF" + 
          "Eg4KBmR1bW15ORgJIAEoBRIPCgdkdW1teTEwGAogASgFEg8KB2R1bW15MTEY" + 
          "CyABKAUSDwoHZHVtbXkxMhgMIAEoBRIPCgdkdW1teTEzGA0gASgFEg8KB2R1" + 
          "bW15MTQYDiABKAUSDwoHZHVtbXkxNRgPIAEoBRIPCgdkdW1teTE2GBAgASgF" + 
          "Eg8KB2R1bW15MTcYESABKAUSDwoHZHVtbXkxOBgSIAEoBRIPCgdkdW1teTE5" + 
          "GBMgASgFEg8KB2R1bW15MjAYFCABKAUSDwoHZHVtbXkyMRgVIAEoBRIPCgdk" + 
          "dW1teTIyGBYgASgFEg8KB2R1bW15MjMYFyABKAUSDwoHZHVtbXkyNBgYIAEo" + 
          "BRIPCgdkdW1teTI1GBkgASgFEg8KB2R1bW15MjYYGiABKAUSDwoHZHVtbXky" + 
          "NxgbIAEoBRIPCgdkdW1teTI4GBwgASgFEg8KB2R1bW15MjkYHSABKAUSDwoH" + 
          "ZHVtbXkzMBgeIAEoBRIPCgdkdW1teTMxGB8gASgFEg8KB2R1bW15MzIYICAB" + 
          "KAUSCQoBYxghIAIoBTJWCgZzaW5nbGUSJC5wcm90b2J1Zl91bml0dGVzdC5U" + 
          "ZXN0QWxsRXh0ZW5zaW9ucxjoByABKAsyHy5wcm90b2J1Zl91bml0dGVzdC5U" + 
          "ZXN0UmVxdWlyZWQyVQoFbXVsdGkSJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0" + 
          "QWxsRXh0ZW5zaW9ucxjpByADKAsyHy5wcm90b2J1Zl91bml0dGVzdC5UZXN0" + 
          "UmVxdWlyZWQimgEKE1Rlc3RSZXF1aXJlZEZvcmVpZ24SOQoQb3B0aW9uYWxf" + 
          "bWVzc2FnZRgBIAEoCzIfLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJl" + 
          "ZBI5ChByZXBlYXRlZF9tZXNzYWdlGAIgAygLMh8ucHJvdG9idWZfdW5pdHRl" + 
          "c3QuVGVzdFJlcXVpcmVkEg0KBWR1bW15GAMgASgFIloKEVRlc3RGb3JlaWdu" + 
          "TmVzdGVkEkUKDmZvcmVpZ25fbmVzdGVkGAEgASgLMi0ucHJvdG9idWZfdW5p" + 
          "dHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2UiEgoQVGVzdEVtcHR5" + 
          "TWVzc2FnZSIqCh5UZXN0RW1wdHlNZXNzYWdlV2l0aEV4dGVuc2lvbnMqCAgB" + 
          "EICAgIACIjcKG1Rlc3RNdWx0aXBsZUV4dGVuc2lvblJhbmdlcyoECCoQKyoG" + 
          "CK8gEJQhKgoIgIAEEICAgIACIjQKGFRlc3RSZWFsbHlMYXJnZVRhZ051bWJl" + 
          "chIJCgFhGAEgASgFEg0KAmJiGP///38gASgFIlUKFFRlc3RSZWN1cnNpdmVN" + 
          "ZXNzYWdlEjIKAWEYASABKAsyJy5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVj" + 
          "dXJzaXZlTWVzc2FnZRIJCgFpGAIgASgFIksKFFRlc3RNdXR1YWxSZWN1cnNp" + 
          "b25BEjMKAmJiGAEgASgLMicucHJvdG9idWZfdW5pdHRlc3QuVGVzdE11dHVh" + 
          "bFJlY3Vyc2lvbkIiYgoUVGVzdE11dHVhbFJlY3Vyc2lvbkISMgoBYRgBIAEo" + 
          "CzInLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RNdXR1YWxSZWN1cnNpb25BEhYK" + 
          "Dm9wdGlvbmFsX2ludDMyGAIgASgFIrMBChJUZXN0RHVwRmllbGROdW1iZXIS" + 
          "CQoBYRgBIAEoBRI2CgNmb28YAiABKAoyKS5wcm90b2J1Zl91bml0dGVzdC5U" + 
          "ZXN0RHVwRmllbGROdW1iZXIuRm9vEjYKA2JhchgDIAEoCjIpLnByb3RvYnVm" + 
          "X3VuaXR0ZXN0LlRlc3REdXBGaWVsZE51bWJlci5CYXIaEAoDRm9vEgkKAWEY" + 
          "ASABKAUaEAoDQmFyEgkKAWEYASABKAUigAIKGFRlc3ROZXN0ZWRNZXNzYWdl" + 
          "SGFzQml0cxJaChdvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZRgBIAEoCzI5LnBy" + 
          "b3RvYnVmX3VuaXR0ZXN0LlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0" + 
          "ZWRNZXNzYWdlGocBCg1OZXN0ZWRNZXNzYWdlEiQKHG5lc3RlZG1lc3NhZ2Vf" + 
          "cmVwZWF0ZWRfaW50MzIYASADKAUSUAolbmVzdGVkbWVzc2FnZV9yZXBlYXRl" + 
          "ZF9mb3JlaWdubWVzc2FnZRgCIAMoCzIhLnByb3RvYnVmX3VuaXR0ZXN0LkZv" + 
          "cmVpZ25NZXNzYWdlIuUDChdUZXN0Q2FtZWxDYXNlRmllbGROYW1lcxIWCg5Q" + 
          "cmltaXRpdmVGaWVsZBgBIAEoBRITCgtTdHJpbmdGaWVsZBgCIAEoCRIxCglF" + 
          "bnVtRmllbGQYAyABKA4yHi5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51" + 
          "bRI3CgxNZXNzYWdlRmllbGQYBCABKAsyIS5wcm90b2J1Zl91bml0dGVzdC5G" + 
          "b3JlaWduTWVzc2FnZRIcChBTdHJpbmdQaWVjZUZpZWxkGAUgASgJQgIIAhIV" + 
          "CglDb3JkRmllbGQYBiABKAlCAggBEh4KFlJlcGVhdGVkUHJpbWl0aXZlRmll" + 
          "bGQYByADKAUSGwoTUmVwZWF0ZWRTdHJpbmdGaWVsZBgIIAMoCRI5ChFSZXBl" + 
          "YXRlZEVudW1GaWVsZBgJIAMoDjIeLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVp" + 
          "Z25FbnVtEj8KFFJlcGVhdGVkTWVzc2FnZUZpZWxkGAogAygLMiEucHJvdG9i" + 
          "dWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2USJAoYUmVwZWF0ZWRTdHJpbmdQ" + 
          "aWVjZUZpZWxkGAsgAygJQgIIAhIdChFSZXBlYXRlZENvcmRGaWVsZBgMIAMo" + 
          "CUICCAEiVQoSVGVzdEZpZWxkT3JkZXJpbmdzEhEKCW15X3N0cmluZxgLIAEo" + 
          "CRIOCgZteV9pbnQYASABKAMSEAoIbXlfZmxvYXQYZSABKAIqBAgCEAsqBAgM" + 
          "EGUi9gQKGFRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcxI/Cg1lc2NhcGVkX2J5" + 
          "dGVzGAEgASgMOihcMDAwXDAwMVwwMDdcMDEwXDAxNFxuXHJcdFwwMTNcXFwn" + 
          "XCJcMzc2EiAKDGxhcmdlX3VpbnQzMhgCIAEoDToKNDI5NDk2NzI5NRIqCgxs" + 
          "YXJnZV91aW50NjQYAyABKAQ6FDE4NDQ2NzQ0MDczNzA5NTUxNjE1EiAKC3Nt" + 
          "YWxsX2ludDMyGAQgASgFOgstMjE0NzQ4MzY0NxIpCgtzbWFsbF9pbnQ2NBgF" + 
          "IAEoAzoULTkyMjMzNzIwMzY4NTQ3NzU4MDcSGAoLdXRmOF9zdHJpbmcYBiAB" + 
          "KAk6A+GItBIVCgp6ZXJvX2Zsb2F0GAcgASgCOgEwEhQKCW9uZV9mbG9hdBgI" + 
          "IAEoAjoBMRIYCgtzbWFsbF9mbG9hdBgJIAEoAjoDMS41Eh4KEm5lZ2F0aXZl" + 
          "X29uZV9mbG9hdBgKIAEoAjoCLTESHAoObmVnYXRpdmVfZmxvYXQYCyABKAI6" + 
          "BC0xLjUSGwoLbGFyZ2VfZmxvYXQYDCABKAI6BjJlKzAwOBIlChRzbWFsbF9u" + 
          "ZWdhdGl2ZV9mbG9hdBgNIAEoAjoHLThlLTAyOBIXCgppbmZfZG91YmxlGA4g" + 
          "ASgBOgNpbmYSHAoObmVnX2luZl9kb3VibGUYDyABKAE6BC1pbmYSFwoKbmFu" + 
          "X2RvdWJsZRgQIAEoAToDbmFuEhYKCWluZl9mbG9hdBgRIAEoAjoDaW5mEhsK" + 
          "DW5lZ19pbmZfZmxvYXQYEiABKAI6BC1pbmYSFgoJbmFuX2Zsb2F0GBMgASgC" + 
          "OgNuYW4iGQoJT25lU3RyaW5nEgwKBGRhdGEYASABKAkiGAoIT25lQnl0ZXMS" + 
          "DAoEZGF0YRgBIAEoDCKqAwoPVGVzdFBhY2tlZFR5cGVzEhgKDHBhY2tlZF9p" + 
          "bnQzMhhaIAMoBUICEAESGAoMcGFja2VkX2ludDY0GFsgAygDQgIQARIZCg1w" + 
          "YWNrZWRfdWludDMyGFwgAygNQgIQARIZCg1wYWNrZWRfdWludDY0GF0gAygE" + 
          "QgIQARIZCg1wYWNrZWRfc2ludDMyGF4gAygRQgIQARIZCg1wYWNrZWRfc2lu" + 
          "dDY0GF8gAygSQgIQARIaCg5wYWNrZWRfZml4ZWQzMhhgIAMoB0ICEAESGgoO" + 
          "cGFja2VkX2ZpeGVkNjQYYSADKAZCAhABEhsKD3BhY2tlZF9zZml4ZWQzMhhi" + 
          "IAMoD0ICEAESGwoPcGFja2VkX3NmaXhlZDY0GGMgAygQQgIQARIYCgxwYWNr" + 
          "ZWRfZmxvYXQYZCADKAJCAhABEhkKDXBhY2tlZF9kb3VibGUYZSADKAFCAhAB" + 
          "EhcKC3BhY2tlZF9ib29sGGYgAygIQgIQARI3CgtwYWNrZWRfZW51bRhnIAMo" + 
          "DjIeLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtQgIQASLIAwoRVGVz" + 
          "dFVucGFja2VkVHlwZXMSGgoOdW5wYWNrZWRfaW50MzIYWiADKAVCAhAAEhoK" + 
          "DnVucGFja2VkX2ludDY0GFsgAygDQgIQABIbCg91bnBhY2tlZF91aW50MzIY" + 
          "XCADKA1CAhAAEhsKD3VucGFja2VkX3VpbnQ2NBhdIAMoBEICEAASGwoPdW5w" + 
          "YWNrZWRfc2ludDMyGF4gAygRQgIQABIbCg91bnBhY2tlZF9zaW50NjQYXyAD" + 
          "KBJCAhAAEhwKEHVucGFja2VkX2ZpeGVkMzIYYCADKAdCAhAAEhwKEHVucGFj" + 
          "a2VkX2ZpeGVkNjQYYSADKAZCAhAAEh0KEXVucGFja2VkX3NmaXhlZDMyGGIg" + 
          "AygPQgIQABIdChF1bnBhY2tlZF9zZml4ZWQ2NBhjIAMoEEICEAASGgoOdW5w" + 
          "YWNrZWRfZmxvYXQYZCADKAJCAhAAEhsKD3VucGFja2VkX2RvdWJsZRhlIAMo" + 
          "AUICEAASGQoNdW5wYWNrZWRfYm9vbBhmIAMoCEICEAASOQoNdW5wYWNrZWRf" + 
          "ZW51bRhnIAMoDjIeLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtQgIQ" + 
          "ACIgChRUZXN0UGFja2VkRXh0ZW5zaW9ucyoICAEQgICAgAIimQQKFVRlc3RE" + 
          "eW5hbWljRXh0ZW5zaW9ucxIZChBzY2FsYXJfZXh0ZW5zaW9uGNAPIAEoBxI3" + 
          "Cg5lbnVtX2V4dGVuc2lvbhjRDyABKA4yHi5wcm90b2J1Zl91bml0dGVzdC5G" + 
          "b3JlaWduRW51bRJZChZkeW5hbWljX2VudW1fZXh0ZW5zaW9uGNIPIAEoDjI4" + 
          "LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3REeW5hbWljRXh0ZW5zaW9ucy5EeW5h" + 
          "bWljRW51bVR5cGUSPQoRbWVzc2FnZV9leHRlbnNpb24Y0w8gASgLMiEucHJv" + 
          "dG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2USXwoZZHluYW1pY19tZXNz" + 
          "YWdlX2V4dGVuc2lvbhjUDyABKAsyOy5wcm90b2J1Zl91bml0dGVzdC5UZXN0" + 
          "RHluYW1pY0V4dGVuc2lvbnMuRHluYW1pY01lc3NhZ2VUeXBlEhsKEnJlcGVh" + 
          "dGVkX2V4dGVuc2lvbhjVDyADKAkSHQoQcGFja2VkX2V4dGVuc2lvbhjWDyAD" + 
          "KBFCAhABGiwKEkR5bmFtaWNNZXNzYWdlVHlwZRIWCg1keW5hbWljX2ZpZWxk" + 
          "GLQQIAEoBSJHCg9EeW5hbWljRW51bVR5cGUSEAoLRFlOQU1JQ19GT08QmBES" + 
          "EAoLRFlOQU1JQ19CQVIQmRESEAoLRFlOQU1JQ19CQVoQmhEiwAEKI1Rlc3RS" + 
          "ZXBlYXRlZFNjYWxhckRpZmZlcmVudFRhZ1NpemVzEhgKEHJlcGVhdGVkX2Zp" + 
          "eGVkMzIYDCADKAcSFgoOcmVwZWF0ZWRfaW50MzIYDSADKAUSGQoQcmVwZWF0" + 
          "ZWRfZml4ZWQ2NBj+DyADKAYSFwoOcmVwZWF0ZWRfaW50NjQY/w8gAygDEhgK" + 
          "DnJlcGVhdGVkX2Zsb2F0GP7/DyADKAISGQoPcmVwZWF0ZWRfdWludDY0GP//" + 
          "DyADKAQiDAoKRm9vUmVxdWVzdCINCgtGb29SZXNwb25zZSIMCgpCYXJSZXF1" + 
          "ZXN0Ig0KC0JhclJlc3BvbnNlKkAKC0ZvcmVpZ25FbnVtEg8KC0ZPUkVJR05f" + 
          "Rk9PEAQSDwoLRk9SRUlHTl9CQVIQBRIPCgtGT1JFSUdOX0JBWhAGKkcKFFRl" + 
          "c3RFbnVtV2l0aER1cFZhbHVlEggKBEZPTzEQARIICgRCQVIxEAISBwoDQkFa" + 
          "EAMSCAoERk9PMhABEggKBEJBUjIQAiqJAQoOVGVzdFNwYXJzZUVudW0SDAoI" + 
          "U1BBUlNFX0EQexIOCghTUEFSU0VfQhCm5wMSDwoIU1BBUlNFX0MQsrGABhIV" + 
          "CghTUEFSU0VfRBDx//////////8BEhUKCFNQQVJTRV9FELTe/P///////wES" + 
          "DAoIU1BBUlNFX0YQABIMCghTUEFSU0VfRxACMpkBCgtUZXN0U2VydmljZRJE" + 
          "CgNGb28SHS5wcm90b2J1Zl91bml0dGVzdC5Gb29SZXF1ZXN0Gh4ucHJvdG9i" + 
          "dWZfdW5pdHRlc3QuRm9vUmVzcG9uc2USRAoDQmFyEh0ucHJvdG9idWZfdW5p" + 
          "dHRlc3QuQmFyUmVxdWVzdBoeLnByb3RvYnVmX3VuaXR0ZXN0LkJhclJlc3Bv" + 
          "bnNlOkYKGG9wdGlvbmFsX2ludDMyX2V4dGVuc2lvbhIkLnByb3RvYnVmX3Vu" + 
          "aXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGAEgASgFOkYKGG9wdGlvbmFsX2lu" + 
          "dDY0X2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRl" + 
          "bnNpb25zGAIgASgDOkcKGW9wdGlvbmFsX3VpbnQzMl9leHRlbnNpb24SJC5w" + 
          "cm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxgDIAEoDTpHChlv" + 
          "cHRpb25hbF91aW50NjRfZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3Qu" + 
          "VGVzdEFsbEV4dGVuc2lvbnMYBCABKAQ6RwoZb3B0aW9uYWxfc2ludDMyX2V4" + 
          "dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25z" + 
          "GAUgASgROkcKGW9wdGlvbmFsX3NpbnQ2NF9leHRlbnNpb24SJC5wcm90b2J1" + 
          "Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxgGIAEoEjpIChpvcHRpb25h" + 
          "bF9maXhlZDMyX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RB" + 
          "bGxFeHRlbnNpb25zGAcgASgHOkgKGm9wdGlvbmFsX2ZpeGVkNjRfZXh0ZW5z" + 
          "aW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYCCAB" + 
          "KAY6SQobb3B0aW9uYWxfc2ZpeGVkMzJfZXh0ZW5zaW9uEiQucHJvdG9idWZf" + 
          "dW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYCSABKA86SQobb3B0aW9uYWxf" + 
          "c2ZpeGVkNjRfZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFs" + 
          "bEV4dGVuc2lvbnMYCiABKBA6RgoYb3B0aW9uYWxfZmxvYXRfZXh0ZW5zaW9u" + 
          "EiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYCyABKAI6" + 
          "RwoZb3B0aW9uYWxfZG91YmxlX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0" + 
          "ZXN0LlRlc3RBbGxFeHRlbnNpb25zGAwgASgBOkUKF29wdGlvbmFsX2Jvb2xf" + 
          "ZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lv" + 
          "bnMYDSABKAg6RwoZb3B0aW9uYWxfc3RyaW5nX2V4dGVuc2lvbhIkLnByb3Rv" + 
          "YnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGA4gASgJOkYKGG9wdGlv" + 
          "bmFsX2J5dGVzX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RB" + 
          "bGxFeHRlbnNpb25zGA8gASgMOnEKF29wdGlvbmFsZ3JvdXBfZXh0ZW5zaW9u" + 
          "EiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYECABKAoy" + 
          "Ki5wcm90b2J1Zl91bml0dGVzdC5PcHRpb25hbEdyb3VwX2V4dGVuc2lvbjp+" + 
          "CiFvcHRpb25hbF9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24SJC5wcm90b2J1" + 
          "Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxgSIAEoCzItLnByb3RvYnVm" + 
          "X3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlOnMKIm9wdGlv" + 
          "bmFsX2ZvcmVpZ25fbWVzc2FnZV9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0" + 
          "dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxgTIAEoCzIhLnByb3RvYnVmX3VuaXR0" + 
          "ZXN0LkZvcmVpZ25NZXNzYWdlOngKIW9wdGlvbmFsX2ltcG9ydF9tZXNzYWdl" + 
          "X2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNp" + 
          "b25zGBQgASgLMicucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1l" + 
          "c3NhZ2U6eAoeb3B0aW9uYWxfbmVzdGVkX2VudW1fZXh0ZW5zaW9uEiQucHJv" + 
          "dG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYFSABKA4yKi5wcm90" + 
          "b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bTptCh9vcHRp" + 
          "b25hbF9mb3JlaWduX2VudW1fZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRl" + 
          "c3QuVGVzdEFsbEV4dGVuc2lvbnMYFiABKA4yHi5wcm90b2J1Zl91bml0dGVz" + 
          "dC5Gb3JlaWduRW51bTpyCh5vcHRpb25hbF9pbXBvcnRfZW51bV9leHRlbnNp" + 
          "b24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxgXIAEo" + 
          "DjIkLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtOlEKH29w" + 
          "dGlvbmFsX3N0cmluZ19waWVjZV9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0" + 
          "dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxgYIAEoCUICCAI6SQoXb3B0aW9uYWxf" + 
          "Y29yZF9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0" + 
          "ZW5zaW9ucxgZIAEoCUICCAE6RgoYcmVwZWF0ZWRfaW50MzJfZXh0ZW5zaW9u" + 
          "EiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYHyADKAU6" + 
          "RgoYcmVwZWF0ZWRfaW50NjRfZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRl" + 
          "c3QuVGVzdEFsbEV4dGVuc2lvbnMYICADKAM6RwoZcmVwZWF0ZWRfdWludDMy" + 
          "X2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNp" + 
          "b25zGCEgAygNOkcKGXJlcGVhdGVkX3VpbnQ2NF9leHRlbnNpb24SJC5wcm90" + 
          "b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxgiIAMoBDpHChlyZXBl" + 
          "YXRlZF9zaW50MzJfZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVz" + 
          "dEFsbEV4dGVuc2lvbnMYIyADKBE6RwoZcmVwZWF0ZWRfc2ludDY0X2V4dGVu" + 
          "c2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGCQg" + 
          "AygSOkgKGnJlcGVhdGVkX2ZpeGVkMzJfZXh0ZW5zaW9uEiQucHJvdG9idWZf" + 
          "dW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYJSADKAc6SAoacmVwZWF0ZWRf" + 
          "Zml4ZWQ2NF9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxs" + 
          "RXh0ZW5zaW9ucxgmIAMoBjpJChtyZXBlYXRlZF9zZml4ZWQzMl9leHRlbnNp" + 
          "b24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxgnIAMo" + 
          "DzpJChtyZXBlYXRlZF9zZml4ZWQ2NF9leHRlbnNpb24SJC5wcm90b2J1Zl91" + 
          "bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxgoIAMoEDpGChhyZXBlYXRlZF9m" + 
          "bG9hdF9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0" + 
          "ZW5zaW9ucxgpIAMoAjpHChlyZXBlYXRlZF9kb3VibGVfZXh0ZW5zaW9uEiQu" + 
          "cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYKiADKAE6RQoX" + 
          "cmVwZWF0ZWRfYm9vbF9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5U" + 
          "ZXN0QWxsRXh0ZW5zaW9ucxgrIAMoCDpHChlyZXBlYXRlZF9zdHJpbmdfZXh0" + 
          "ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMY" + 
          "LCADKAk6RgoYcmVwZWF0ZWRfYnl0ZXNfZXh0ZW5zaW9uEiQucHJvdG9idWZf" + 
          "dW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYLSADKAw6cQoXcmVwZWF0ZWRn" + 
          "cm91cF9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0" + 
          "ZW5zaW9ucxguIAMoCjIqLnByb3RvYnVmX3VuaXR0ZXN0LlJlcGVhdGVkR3Jv" + 
          "dXBfZXh0ZW5zaW9uOn4KIXJlcGVhdGVkX25lc3RlZF9tZXNzYWdlX2V4dGVu" + 
          "c2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGDAg" + 
          "AygLMi0ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1l" + 
          "c3NhZ2U6cwoicmVwZWF0ZWRfZm9yZWlnbl9tZXNzYWdlX2V4dGVuc2lvbhIk" + 
          "LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGDEgAygLMiEu" + 
          "cHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2U6eAohcmVwZWF0ZWRf" + 
          "aW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3Qu" + 
          "VGVzdEFsbEV4dGVuc2lvbnMYMiADKAsyJy5wcm90b2J1Zl91bml0dGVzdF9p" + 
          "bXBvcnQuSW1wb3J0TWVzc2FnZTp4Ch5yZXBlYXRlZF9uZXN0ZWRfZW51bV9l" + 
          "eHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9u" + 
          "cxgzIAMoDjIqLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0" + 
          "ZWRFbnVtOm0KH3JlcGVhdGVkX2ZvcmVpZ25fZW51bV9leHRlbnNpb24SJC5w" + 
          "cm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxg0IAMoDjIeLnBy" + 
          "b3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtOnIKHnJlcGVhdGVkX2ltcG9y" + 
          "dF9lbnVtX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxF" + 
          "eHRlbnNpb25zGDUgAygOMiQucHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0Lklt" + 
          "cG9ydEVudW06UQofcmVwZWF0ZWRfc3RyaW5nX3BpZWNlX2V4dGVuc2lvbhIk" + 
          "LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGDYgAygJQgII" + 
          "AjpJChdyZXBlYXRlZF9jb3JkX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0" + 
          "ZXN0LlRlc3RBbGxFeHRlbnNpb25zGDcgAygJQgIIATpJChdkZWZhdWx0X2lu" + 
          "dDMyX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRl" + 
          "bnNpb25zGD0gASgFOgI0MTpJChdkZWZhdWx0X2ludDY0X2V4dGVuc2lvbhIk" + 
          "LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGD4gASgDOgI0" + 
          "MjpKChhkZWZhdWx0X3VpbnQzMl9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0" + 
          "dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxg/IAEoDToCNDM6SgoYZGVmYXVsdF91" + 
          "aW50NjRfZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4" + 
          "dGVuc2lvbnMYQCABKAQ6AjQ0OksKGGRlZmF1bHRfc2ludDMyX2V4dGVuc2lv" + 
          "bhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGEEgASgR" + 
          "OgMtNDU6SgoYZGVmYXVsdF9zaW50NjRfZXh0ZW5zaW9uEiQucHJvdG9idWZf" + 
          "dW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYQiABKBI6AjQ2OksKGWRlZmF1" + 
          "bHRfZml4ZWQzMl9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0" + 
          "QWxsRXh0ZW5zaW9ucxhDIAEoBzoCNDc6SwoZZGVmYXVsdF9maXhlZDY0X2V4" + 
          "dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25z" + 
          "GEQgASgGOgI0ODpMChpkZWZhdWx0X3NmaXhlZDMyX2V4dGVuc2lvbhIkLnBy" + 
          "b3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGEUgASgPOgI0OTpN" + 
          "ChpkZWZhdWx0X3NmaXhlZDY0X2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0" + 
          "ZXN0LlRlc3RBbGxFeHRlbnNpb25zGEYgASgQOgMtNTA6SwoXZGVmYXVsdF9m" + 
          "bG9hdF9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0" + 
          "ZW5zaW9ucxhHIAEoAjoENTEuNTpNChhkZWZhdWx0X2RvdWJsZV9leHRlbnNp" + 
          "b24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxhIIAEo" + 
          "AToFNTIwMDA6SgoWZGVmYXVsdF9ib29sX2V4dGVuc2lvbhIkLnByb3RvYnVm" + 
          "X3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGEkgASgIOgR0cnVlOk0KGGRl" + 
          "ZmF1bHRfc3RyaW5nX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRl" + 
          "c3RBbGxFeHRlbnNpb25zGEogASgJOgVoZWxsbzpMChdkZWZhdWx0X2J5dGVz" + 
          "X2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNp" + 
          "b25zGEsgASgMOgV3b3JsZDp8Ch1kZWZhdWx0X25lc3RlZF9lbnVtX2V4dGVu" + 
          "c2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGFEg" + 
          "ASgOMioucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVu" + 
          "dW06A0JBUjp5Ch5kZWZhdWx0X2ZvcmVpZ25fZW51bV9leHRlbnNpb24SJC5w" + 
          "cm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxhSIAEoDjIeLnBy" + 
          "b3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtOgtGT1JFSUdOX0JBUjp9Ch1k" + 
          "ZWZhdWx0X2ltcG9ydF9lbnVtX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0" + 
          "ZXN0LlRlc3RBbGxFeHRlbnNpb25zGFMgASgOMiQucHJvdG9idWZfdW5pdHRl" + 
          "c3RfaW1wb3J0LkltcG9ydEVudW06CklNUE9SVF9CQVI6VQoeZGVmYXVsdF9z" + 
          "dHJpbmdfcGllY2VfZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVz" + 
          "dEFsbEV4dGVuc2lvbnMYVCABKAk6A2FiY0ICCAI6TQoWZGVmYXVsdF9jb3Jk" + 
          "X2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNp" + 
          "b25zGFUgASgJOgMxMjNCAggBOkIKE215X2V4dGVuc2lvbl9zdHJpbmcSJS5w" + 
          "cm90b2J1Zl91bml0dGVzdC5UZXN0RmllbGRPcmRlcmluZ3MYMiABKAk6PwoQ" + 
          "bXlfZXh0ZW5zaW9uX2ludBIlLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RGaWVs" + 
          "ZE9yZGVyaW5ncxgFIAEoBTpLChZwYWNrZWRfaW50MzJfZXh0ZW5zaW9uEicu" + 
          "cHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZEV4dGVuc2lvbnMYWiADKAVC" + 
          "AhABOksKFnBhY2tlZF9pbnQ2NF9leHRlbnNpb24SJy5wcm90b2J1Zl91bml0" + 
          "dGVzdC5UZXN0UGFja2VkRXh0ZW5zaW9ucxhbIAMoA0ICEAE6TAoXcGFja2Vk" + 
          "X3VpbnQzMl9leHRlbnNpb24SJy5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFj" + 
          "a2VkRXh0ZW5zaW9ucxhcIAMoDUICEAE6TAoXcGFja2VkX3VpbnQ2NF9leHRl" + 
          "bnNpb24SJy5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRXh0ZW5zaW9u" + 
          "cxhdIAMoBEICEAE6TAoXcGFja2VkX3NpbnQzMl9leHRlbnNpb24SJy5wcm90" + 
          "b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRXh0ZW5zaW9ucxheIAMoEUICEAE6" + 
          "TAoXcGFja2VkX3NpbnQ2NF9leHRlbnNpb24SJy5wcm90b2J1Zl91bml0dGVz" + 
          "dC5UZXN0UGFja2VkRXh0ZW5zaW9ucxhfIAMoEkICEAE6TQoYcGFja2VkX2Zp" + 
          "eGVkMzJfZXh0ZW5zaW9uEicucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tl" + 
          "ZEV4dGVuc2lvbnMYYCADKAdCAhABOk0KGHBhY2tlZF9maXhlZDY0X2V4dGVu" + 
          "c2lvbhInLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRFeHRlbnNpb25z" + 
          "GGEgAygGQgIQATpOChlwYWNrZWRfc2ZpeGVkMzJfZXh0ZW5zaW9uEicucHJv" + 
          "dG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZEV4dGVuc2lvbnMYYiADKA9CAhAB" + 
          "Ok4KGXBhY2tlZF9zZml4ZWQ2NF9leHRlbnNpb24SJy5wcm90b2J1Zl91bml0" + 
          "dGVzdC5UZXN0UGFja2VkRXh0ZW5zaW9ucxhjIAMoEEICEAE6SwoWcGFja2Vk" + 
          "X2Zsb2F0X2V4dGVuc2lvbhInLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNr" + 
          "ZWRFeHRlbnNpb25zGGQgAygCQgIQATpMChdwYWNrZWRfZG91YmxlX2V4dGVu" + 
          "c2lvbhInLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRFeHRlbnNpb25z" + 
          "GGUgAygBQgIQATpKChVwYWNrZWRfYm9vbF9leHRlbnNpb24SJy5wcm90b2J1" + 
          "Zl91bml0dGVzdC5UZXN0UGFja2VkRXh0ZW5zaW9ucxhmIAMoCEICEAE6agoV" + 
          "cGFja2VkX2VudW1fZXh0ZW5zaW9uEicucHJvdG9idWZfdW5pdHRlc3QuVGVz" + 
          "dFBhY2tlZEV4dGVuc2lvbnMYZyADKA4yHi5wcm90b2J1Zl91bml0dGVzdC5G" + 
          "b3JlaWduRW51bUICEAFCSkINVW5pdHRlc3RQcm90b0gBwj42CiFHb29nbGUu" + 
          "UHJvdG9jb2xCdWZmZXJzLlRlc3RQcm90b3MSEVVuaXRUZXN0UHJvdG9GaWxl");
      pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
        descriptor = root;
        internal__static_protobuf_unittest_TestAllTypes__Descriptor = Descriptor.MessageTypes[0];
        internal__static_protobuf_unittest_TestAllTypes__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder>(internal__static_protobuf_unittest_TestAllTypes__Descriptor,
                new string[] { "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalGroup", "OptionalNestedMessage", "OptionalForeignMessage", "OptionalImportMessage", "OptionalNestedEnum", "OptionalForeignEnum", "OptionalImportEnum", "OptionalStringPiece", "OptionalCord", "RepeatedInt32", "RepeatedInt64", "RepeatedUint32", "RepeatedUint64", "RepeatedSint32", "RepeatedSint64", "RepeatedFixed32", "RepeatedFixed64", "RepeatedSfixed32", "RepeatedSfixed64", "RepeatedFloat", "RepeatedDouble", "RepeatedBool", "RepeatedString", "RepeatedBytes", "RepeatedGroup", "RepeatedNestedMessage", "RepeatedForeignMessage", "RepeatedImportMessage", "RepeatedNestedEnum", "RepeatedForeignEnum", "RepeatedImportEnum", "RepeatedStringPiece", "RepeatedCord", "DefaultInt32", "DefaultInt64", "DefaultUint32", "DefaultUint64", "DefaultSint32", "DefaultSint64", "DefaultFixed32", "DefaultFixed64", "DefaultSfixed32", "DefaultSfixed64", "DefaultFloat", "DefaultDouble", "DefaultBool", "DefaultString", "DefaultBytes", "DefaultNestedEnum", "DefaultForeignEnum", "DefaultImportEnum", "DefaultStringPiece", "DefaultCord", });
        internal__static_protobuf_unittest_TestAllTypes_NestedMessage__Descriptor = internal__static_protobuf_unittest_TestAllTypes__Descriptor.NestedTypes[0];
        internal__static_protobuf_unittest_TestAllTypes_NestedMessage__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.Builder>(internal__static_protobuf_unittest_TestAllTypes_NestedMessage__Descriptor,
                new string[] { "Bb", });
        internal__static_protobuf_unittest_TestAllTypes_OptionalGroup__Descriptor = internal__static_protobuf_unittest_TestAllTypes__Descriptor.NestedTypes[1];
        internal__static_protobuf_unittest_TestAllTypes_OptionalGroup__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.OptionalGroup, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.OptionalGroup.Builder>(internal__static_protobuf_unittest_TestAllTypes_OptionalGroup__Descriptor,
                new string[] { "A", });
        internal__static_protobuf_unittest_TestAllTypes_RepeatedGroup__Descriptor = internal__static_protobuf_unittest_TestAllTypes__Descriptor.NestedTypes[2];
        internal__static_protobuf_unittest_TestAllTypes_RepeatedGroup__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup.Builder>(internal__static_protobuf_unittest_TestAllTypes_RepeatedGroup__Descriptor,
                new string[] { "A", });
        internal__static_protobuf_unittest_TestDeprecatedFields__Descriptor = Descriptor.MessageTypes[1];
        internal__static_protobuf_unittest_TestDeprecatedFields__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestDeprecatedFields, global::Google.ProtocolBuffers.TestProtos.TestDeprecatedFields.Builder>(internal__static_protobuf_unittest_TestDeprecatedFields__Descriptor,
                new string[] { "DeprecatedInt32", });
        internal__static_protobuf_unittest_ForeignMessage__Descriptor = Descriptor.MessageTypes[2];
        internal__static_protobuf_unittest_ForeignMessage__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.ForeignMessage, global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder>(internal__static_protobuf_unittest_ForeignMessage__Descriptor,
                new string[] { "C", });
        internal__static_protobuf_unittest_TestAllExtensions__Descriptor = Descriptor.MessageTypes[3];
        internal__static_protobuf_unittest_TestAllExtensions__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestAllExtensions, global::Google.ProtocolBuffers.TestProtos.TestAllExtensions.Builder>(internal__static_protobuf_unittest_TestAllExtensions__Descriptor,
                new string[] { });
        internal__static_protobuf_unittest_OptionalGroup_extension__Descriptor = Descriptor.MessageTypes[4];
        internal__static_protobuf_unittest_OptionalGroup_extension__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.OptionalGroup_extension, global::Google.ProtocolBuffers.TestProtos.OptionalGroup_extension.Builder>(internal__static_protobuf_unittest_OptionalGroup_extension__Descriptor,
                new string[] { "A", });
        internal__static_protobuf_unittest_RepeatedGroup_extension__Descriptor = Descriptor.MessageTypes[5];
        internal__static_protobuf_unittest_RepeatedGroup_extension__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.RepeatedGroup_extension, global::Google.ProtocolBuffers.TestProtos.RepeatedGroup_extension.Builder>(internal__static_protobuf_unittest_RepeatedGroup_extension__Descriptor,
                new string[] { "A", });
        internal__static_protobuf_unittest_TestNestedExtension__Descriptor = Descriptor.MessageTypes[6];
        internal__static_protobuf_unittest_TestNestedExtension__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestNestedExtension, global::Google.ProtocolBuffers.TestProtos.TestNestedExtension.Builder>(internal__static_protobuf_unittest_TestNestedExtension__Descriptor,
                new string[] { });
        global::Google.ProtocolBuffers.TestProtos.TestNestedExtension.Test = pb::GeneratedSingleExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.TestNestedExtension.Descriptor.Extensions[0]);
        internal__static_protobuf_unittest_TestRequired__Descriptor = Descriptor.MessageTypes[7];
        internal__static_protobuf_unittest_TestRequired__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestRequired, global::Google.ProtocolBuffers.TestProtos.TestRequired.Builder>(internal__static_protobuf_unittest_TestRequired__Descriptor,
                new string[] { "A", "Dummy2", "B", "Dummy4", "Dummy5", "Dummy6", "Dummy7", "Dummy8", "Dummy9", "Dummy10", "Dummy11", "Dummy12", "Dummy13", "Dummy14", "Dummy15", "Dummy16", "Dummy17", "Dummy18", "Dummy19", "Dummy20", "Dummy21", "Dummy22", "Dummy23", "Dummy24", "Dummy25", "Dummy26", "Dummy27", "Dummy28", "Dummy29", "Dummy30", "Dummy31", "Dummy32", "C", });
        global::Google.ProtocolBuffers.TestProtos.TestRequired.Single = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.TestRequired>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.TestRequired.Descriptor.Extensions[0]);
        global::Google.ProtocolBuffers.TestProtos.TestRequired.Multi = pb::GeneratedRepeatExtension<global::Google.ProtocolBuffers.TestProtos.TestRequired>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.TestRequired.Descriptor.Extensions[1]);
        internal__static_protobuf_unittest_TestRequiredForeign__Descriptor = Descriptor.MessageTypes[8];
        internal__static_protobuf_unittest_TestRequiredForeign__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestRequiredForeign, global::Google.ProtocolBuffers.TestProtos.TestRequiredForeign.Builder>(internal__static_protobuf_unittest_TestRequiredForeign__Descriptor,
                new string[] { "OptionalMessage", "RepeatedMessage", "Dummy", });
        internal__static_protobuf_unittest_TestForeignNested__Descriptor = Descriptor.MessageTypes[9];
        internal__static_protobuf_unittest_TestForeignNested__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestForeignNested, global::Google.ProtocolBuffers.TestProtos.TestForeignNested.Builder>(internal__static_protobuf_unittest_TestForeignNested__Descriptor,
                new string[] { "ForeignNested", });
        internal__static_protobuf_unittest_TestEmptyMessage__Descriptor = Descriptor.MessageTypes[10];
        internal__static_protobuf_unittest_TestEmptyMessage__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestEmptyMessage, global::Google.ProtocolBuffers.TestProtos.TestEmptyMessage.Builder>(internal__static_protobuf_unittest_TestEmptyMessage__Descriptor,
                new string[] { });
        internal__static_protobuf_unittest_TestEmptyMessageWithExtensions__Descriptor = Descriptor.MessageTypes[11];
        internal__static_protobuf_unittest_TestEmptyMessageWithExtensions__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestEmptyMessageWithExtensions, global::Google.ProtocolBuffers.TestProtos.TestEmptyMessageWithExtensions.Builder>(internal__static_protobuf_unittest_TestEmptyMessageWithExtensions__Descriptor,
                new string[] { });
        internal__static_protobuf_unittest_TestMultipleExtensionRanges__Descriptor = Descriptor.MessageTypes[12];
        internal__static_protobuf_unittest_TestMultipleExtensionRanges__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestMultipleExtensionRanges, global::Google.ProtocolBuffers.TestProtos.TestMultipleExtensionRanges.Builder>(internal__static_protobuf_unittest_TestMultipleExtensionRanges__Descriptor,
                new string[] { });
        internal__static_protobuf_unittest_TestReallyLargeTagNumber__Descriptor = Descriptor.MessageTypes[13];
        internal__static_protobuf_unittest_TestReallyLargeTagNumber__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestReallyLargeTagNumber, global::Google.ProtocolBuffers.TestProtos.TestReallyLargeTagNumber.Builder>(internal__static_protobuf_unittest_TestReallyLargeTagNumber__Descriptor,
                new string[] { "A", "Bb", });
        internal__static_protobuf_unittest_TestRecursiveMessage__Descriptor = Descriptor.MessageTypes[14];
        internal__static_protobuf_unittest_TestRecursiveMessage__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestRecursiveMessage, global::Google.ProtocolBuffers.TestProtos.TestRecursiveMessage.Builder>(internal__static_protobuf_unittest_TestRecursiveMessage__Descriptor,
                new string[] { "A", "I", });
        internal__static_protobuf_unittest_TestMutualRecursionA__Descriptor = Descriptor.MessageTypes[15];
        internal__static_protobuf_unittest_TestMutualRecursionA__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionA, global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionA.Builder>(internal__static_protobuf_unittest_TestMutualRecursionA__Descriptor,
                new string[] { "Bb", });
        internal__static_protobuf_unittest_TestMutualRecursionB__Descriptor = Descriptor.MessageTypes[16];
        internal__static_protobuf_unittest_TestMutualRecursionB__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionB, global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionB.Builder>(internal__static_protobuf_unittest_TestMutualRecursionB__Descriptor,
                new string[] { "A", "OptionalInt32", });
        internal__static_protobuf_unittest_TestDupFieldNumber__Descriptor = Descriptor.MessageTypes[17];
        internal__static_protobuf_unittest_TestDupFieldNumber__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber, global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Builder>(internal__static_protobuf_unittest_TestDupFieldNumber__Descriptor,
                new string[] { "A", "Foo", "Bar", });
        internal__static_protobuf_unittest_TestDupFieldNumber_Foo__Descriptor = internal__static_protobuf_unittest_TestDupFieldNumber__Descriptor.NestedTypes[0];
        internal__static_protobuf_unittest_TestDupFieldNumber_Foo__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Foo, global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Foo.Builder>(internal__static_protobuf_unittest_TestDupFieldNumber_Foo__Descriptor,
                new string[] { "A", });
        internal__static_protobuf_unittest_TestDupFieldNumber_Bar__Descriptor = internal__static_protobuf_unittest_TestDupFieldNumber__Descriptor.NestedTypes[1];
        internal__static_protobuf_unittest_TestDupFieldNumber_Bar__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Bar, global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Bar.Builder>(internal__static_protobuf_unittest_TestDupFieldNumber_Bar__Descriptor,
                new string[] { "A", });
        internal__static_protobuf_unittest_TestNestedMessageHasBits__Descriptor = Descriptor.MessageTypes[18];
        internal__static_protobuf_unittest_TestNestedMessageHasBits__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits, global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Builder>(internal__static_protobuf_unittest_TestNestedMessageHasBits__Descriptor,
                new string[] { "OptionalNestedMessage", });
        internal__static_protobuf_unittest_TestNestedMessageHasBits_NestedMessage__Descriptor = internal__static_protobuf_unittest_TestNestedMessageHasBits__Descriptor.NestedTypes[0];
        internal__static_protobuf_unittest_TestNestedMessageHasBits_NestedMessage__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Types.NestedMessage, global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Types.NestedMessage.Builder>(internal__static_protobuf_unittest_TestNestedMessageHasBits_NestedMessage__Descriptor,
                new string[] { "NestedmessageRepeatedInt32", "NestedmessageRepeatedForeignmessage", });
        internal__static_protobuf_unittest_TestCamelCaseFieldNames__Descriptor = Descriptor.MessageTypes[19];
        internal__static_protobuf_unittest_TestCamelCaseFieldNames__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestCamelCaseFieldNames, global::Google.ProtocolBuffers.TestProtos.TestCamelCaseFieldNames.Builder>(internal__static_protobuf_unittest_TestCamelCaseFieldNames__Descriptor,
                new string[] { "PrimitiveField", "StringField", "EnumField", "MessageField", "StringPieceField", "CordField", "RepeatedPrimitiveField", "RepeatedStringField", "RepeatedEnumField", "RepeatedMessageField", "RepeatedStringPieceField", "RepeatedCordField", });
        internal__static_protobuf_unittest_TestFieldOrderings__Descriptor = Descriptor.MessageTypes[20];
        internal__static_protobuf_unittest_TestFieldOrderings__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestFieldOrderings, global::Google.ProtocolBuffers.TestProtos.TestFieldOrderings.Builder>(internal__static_protobuf_unittest_TestFieldOrderings__Descriptor,
                new string[] { "MyString", "MyInt", "MyFloat", });
        internal__static_protobuf_unittest_TestExtremeDefaultValues__Descriptor = Descriptor.MessageTypes[21];
        internal__static_protobuf_unittest_TestExtremeDefaultValues__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestExtremeDefaultValues, global::Google.ProtocolBuffers.TestProtos.TestExtremeDefaultValues.Builder>(internal__static_protobuf_unittest_TestExtremeDefaultValues__Descriptor,
                new string[] { "EscapedBytes", "LargeUint32", "LargeUint64", "SmallInt32", "SmallInt64", "Utf8String", "ZeroFloat", "OneFloat", "SmallFloat", "NegativeOneFloat", "NegativeFloat", "LargeFloat", "SmallNegativeFloat", "InfDouble", "NegInfDouble", "NanDouble", "InfFloat", "NegInfFloat", "NanFloat", });
        internal__static_protobuf_unittest_OneString__Descriptor = Descriptor.MessageTypes[22];
        internal__static_protobuf_unittest_OneString__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.OneString, global::Google.ProtocolBuffers.TestProtos.OneString.Builder>(internal__static_protobuf_unittest_OneString__Descriptor,
                new string[] { "Data", });
        internal__static_protobuf_unittest_OneBytes__Descriptor = Descriptor.MessageTypes[23];
        internal__static_protobuf_unittest_OneBytes__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.OneBytes, global::Google.ProtocolBuffers.TestProtos.OneBytes.Builder>(internal__static_protobuf_unittest_OneBytes__Descriptor,
                new string[] { "Data", });
        internal__static_protobuf_unittest_TestPackedTypes__Descriptor = Descriptor.MessageTypes[24];
        internal__static_protobuf_unittest_TestPackedTypes__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestPackedTypes, global::Google.ProtocolBuffers.TestProtos.TestPackedTypes.Builder>(internal__static_protobuf_unittest_TestPackedTypes__Descriptor,
                new string[] { "PackedInt32", "PackedInt64", "PackedUint32", "PackedUint64", "PackedSint32", "PackedSint64", "PackedFixed32", "PackedFixed64", "PackedSfixed32", "PackedSfixed64", "PackedFloat", "PackedDouble", "PackedBool", "PackedEnum", });
        internal__static_protobuf_unittest_TestUnpackedTypes__Descriptor = Descriptor.MessageTypes[25];
        internal__static_protobuf_unittest_TestUnpackedTypes__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestUnpackedTypes, global::Google.ProtocolBuffers.TestProtos.TestUnpackedTypes.Builder>(internal__static_protobuf_unittest_TestUnpackedTypes__Descriptor,
                new string[] { "UnpackedInt32", "UnpackedInt64", "UnpackedUint32", "UnpackedUint64", "UnpackedSint32", "UnpackedSint64", "UnpackedFixed32", "UnpackedFixed64", "UnpackedSfixed32", "UnpackedSfixed64", "UnpackedFloat", "UnpackedDouble", "UnpackedBool", "UnpackedEnum", });
        internal__static_protobuf_unittest_TestPackedExtensions__Descriptor = Descriptor.MessageTypes[26];
        internal__static_protobuf_unittest_TestPackedExtensions__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestPackedExtensions, global::Google.ProtocolBuffers.TestProtos.TestPackedExtensions.Builder>(internal__static_protobuf_unittest_TestPackedExtensions__Descriptor,
                new string[] { });
        internal__static_protobuf_unittest_TestDynamicExtensions__Descriptor = Descriptor.MessageTypes[27];
        internal__static_protobuf_unittest_TestDynamicExtensions__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions, global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Builder>(internal__static_protobuf_unittest_TestDynamicExtensions__Descriptor,
                new string[] { "ScalarExtension", "EnumExtension", "DynamicEnumExtension", "MessageExtension", "DynamicMessageExtension", "RepeatedExtension", "PackedExtension", });
        internal__static_protobuf_unittest_TestDynamicExtensions_DynamicMessageType__Descriptor = internal__static_protobuf_unittest_TestDynamicExtensions__Descriptor.NestedTypes[0];
        internal__static_protobuf_unittest_TestDynamicExtensions_DynamicMessageType__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicMessageType, global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicMessageType.Builder>(internal__static_protobuf_unittest_TestDynamicExtensions_DynamicMessageType__Descriptor,
                new string[] { "DynamicField", });
        internal__static_protobuf_unittest_TestRepeatedScalarDifferentTagSizes__Descriptor = Descriptor.MessageTypes[28];
        internal__static_protobuf_unittest_TestRepeatedScalarDifferentTagSizes__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestRepeatedScalarDifferentTagSizes, global::Google.ProtocolBuffers.TestProtos.TestRepeatedScalarDifferentTagSizes.Builder>(internal__static_protobuf_unittest_TestRepeatedScalarDifferentTagSizes__Descriptor,
                new string[] { "RepeatedFixed32", "RepeatedInt32", "RepeatedFixed64", "RepeatedInt64", "RepeatedFloat", "RepeatedUint64", });
        internal__static_protobuf_unittest_FooRequest__Descriptor = Descriptor.MessageTypes[29];
        internal__static_protobuf_unittest_FooRequest__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.FooRequest, global::Google.ProtocolBuffers.TestProtos.FooRequest.Builder>(internal__static_protobuf_unittest_FooRequest__Descriptor,
                new string[] { });
        internal__static_protobuf_unittest_FooResponse__Descriptor = Descriptor.MessageTypes[30];
        internal__static_protobuf_unittest_FooResponse__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.FooResponse, global::Google.ProtocolBuffers.TestProtos.FooResponse.Builder>(internal__static_protobuf_unittest_FooResponse__Descriptor,
                new string[] { });
        internal__static_protobuf_unittest_BarRequest__Descriptor = Descriptor.MessageTypes[31];
        internal__static_protobuf_unittest_BarRequest__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.BarRequest, global::Google.ProtocolBuffers.TestProtos.BarRequest.Builder>(internal__static_protobuf_unittest_BarRequest__Descriptor,
                new string[] { });
        internal__static_protobuf_unittest_BarResponse__Descriptor = Descriptor.MessageTypes[32];
        internal__static_protobuf_unittest_BarResponse__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.BarResponse, global::Google.ProtocolBuffers.TestProtos.BarResponse.Builder>(internal__static_protobuf_unittest_BarResponse__Descriptor,
                new string[] { });
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalInt32Extension = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[0]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalInt64Extension = pb::GeneratedSingleExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[1]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalUint32Extension = pb::GeneratedSingleExtension<uint>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[2]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalUint64Extension = pb::GeneratedSingleExtension<ulong>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[3]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalSint32Extension = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[4]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalSint64Extension = pb::GeneratedSingleExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[5]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalFixed32Extension = pb::GeneratedSingleExtension<uint>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[6]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalFixed64Extension = pb::GeneratedSingleExtension<ulong>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[7]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalSfixed32Extension = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[8]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalSfixed64Extension = pb::GeneratedSingleExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[9]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalFloatExtension = pb::GeneratedSingleExtension<float>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[10]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalDoubleExtension = pb::GeneratedSingleExtension<double>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[11]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalBoolExtension = pb::GeneratedSingleExtension<bool>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[12]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalStringExtension = pb::GeneratedSingleExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[13]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalBytesExtension = pb::GeneratedSingleExtension<pb::ByteString>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[14]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalGroupExtension = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.OptionalGroup_extension>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[15]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalNestedMessageExtension = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[16]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalForeignMessageExtension = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.ForeignMessage>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[17]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalImportMessageExtension = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.ImportMessage>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[18]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalNestedEnumExtension = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[19]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalForeignEnumExtension = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[20]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalImportEnumExtension = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.ImportEnum>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[21]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalStringPieceExtension = pb::GeneratedSingleExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[22]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.OptionalCordExtension = pb::GeneratedSingleExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[23]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedInt32Extension = pb::GeneratedRepeatExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[24]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedInt64Extension = pb::GeneratedRepeatExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[25]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedUint32Extension = pb::GeneratedRepeatExtension<uint>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[26]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedUint64Extension = pb::GeneratedRepeatExtension<ulong>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[27]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedSint32Extension = pb::GeneratedRepeatExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[28]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedSint64Extension = pb::GeneratedRepeatExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[29]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedFixed32Extension = pb::GeneratedRepeatExtension<uint>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[30]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedFixed64Extension = pb::GeneratedRepeatExtension<ulong>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[31]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedSfixed32Extension = pb::GeneratedRepeatExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[32]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedSfixed64Extension = pb::GeneratedRepeatExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[33]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedFloatExtension = pb::GeneratedRepeatExtension<float>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[34]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedDoubleExtension = pb::GeneratedRepeatExtension<double>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[35]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedBoolExtension = pb::GeneratedRepeatExtension<bool>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[36]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedStringExtension = pb::GeneratedRepeatExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[37]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedBytesExtension = pb::GeneratedRepeatExtension<pb::ByteString>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[38]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedGroupExtension = pb::GeneratedRepeatExtension<global::Google.ProtocolBuffers.TestProtos.RepeatedGroup_extension>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[39]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedNestedMessageExtension = pb::GeneratedRepeatExtension<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[40]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedForeignMessageExtension = pb::GeneratedRepeatExtension<global::Google.ProtocolBuffers.TestProtos.ForeignMessage>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[41]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedImportMessageExtension = pb::GeneratedRepeatExtension<global::Google.ProtocolBuffers.TestProtos.ImportMessage>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[42]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedNestedEnumExtension = pb::GeneratedRepeatExtension<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[43]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedForeignEnumExtension = pb::GeneratedRepeatExtension<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[44]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedImportEnumExtension = pb::GeneratedRepeatExtension<global::Google.ProtocolBuffers.TestProtos.ImportEnum>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[45]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedStringPieceExtension = pb::GeneratedRepeatExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[46]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RepeatedCordExtension = pb::GeneratedRepeatExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[47]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultInt32Extension = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[48]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultInt64Extension = pb::GeneratedSingleExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[49]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultUint32Extension = pb::GeneratedSingleExtension<uint>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[50]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultUint64Extension = pb::GeneratedSingleExtension<ulong>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[51]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultSint32Extension = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[52]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultSint64Extension = pb::GeneratedSingleExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[53]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultFixed32Extension = pb::GeneratedSingleExtension<uint>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[54]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultFixed64Extension = pb::GeneratedSingleExtension<ulong>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[55]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultSfixed32Extension = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[56]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultSfixed64Extension = pb::GeneratedSingleExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[57]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultFloatExtension = pb::GeneratedSingleExtension<float>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[58]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultDoubleExtension = pb::GeneratedSingleExtension<double>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[59]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultBoolExtension = pb::GeneratedSingleExtension<bool>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[60]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultStringExtension = pb::GeneratedSingleExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[61]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultBytesExtension = pb::GeneratedSingleExtension<pb::ByteString>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[62]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultNestedEnumExtension = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[63]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultForeignEnumExtension = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[64]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultImportEnumExtension = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.ImportEnum>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[65]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultStringPieceExtension = pb::GeneratedSingleExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[66]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.DefaultCordExtension = pb::GeneratedSingleExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[67]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.MyExtensionString = pb::GeneratedSingleExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[68]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.MyExtensionInt = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[69]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedInt32Extension = pb::GeneratedRepeatExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[70]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedInt64Extension = pb::GeneratedRepeatExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[71]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedUint32Extension = pb::GeneratedRepeatExtension<uint>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[72]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedUint64Extension = pb::GeneratedRepeatExtension<ulong>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[73]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedSint32Extension = pb::GeneratedRepeatExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[74]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedSint64Extension = pb::GeneratedRepeatExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[75]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedFixed32Extension = pb::GeneratedRepeatExtension<uint>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[76]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedFixed64Extension = pb::GeneratedRepeatExtension<ulong>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[77]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedSfixed32Extension = pb::GeneratedRepeatExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[78]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedSfixed64Extension = pb::GeneratedRepeatExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[79]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedFloatExtension = pb::GeneratedRepeatExtension<float>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[80]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedDoubleExtension = pb::GeneratedRepeatExtension<double>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[81]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedBoolExtension = pb::GeneratedRepeatExtension<bool>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[82]);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.PackedEnumExtension = pb::GeneratedRepeatExtension<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor.Extensions[83]);
        pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();
        RegisterAllExtensions(registry);
        global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.RegisterAllExtensions(registry);
        global::Google.ProtocolBuffers.TestProtos.UnitTestImportProtoFile.RegisterAllExtensions(registry);
        return registry;
      };
      pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
          new pbd::FileDescriptor[] {
          global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor, 
          global::Google.ProtocolBuffers.TestProtos.UnitTestImportProtoFile.Descriptor, 
          }, assigner);
    }
    #endregion
    
  }
  #region Enums
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public enum ForeignEnum {
    FOREIGN_FOO = 4,
    FOREIGN_BAR = 5,
    FOREIGN_BAZ = 6,
  }
  
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public enum TestEnumWithDupValue {
    FOO1 = 1,
    BAR1 = 2,
    BAZ = 3,
    FOO2 = 1,
    BAR2 = 2,
  }
  
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public enum TestSparseEnum {
    SPARSE_A = 123,
    SPARSE_B = 62374,
    SPARSE_C = 12589234,
    SPARSE_D = -15,
    SPARSE_E = -53452,
    SPARSE_F = 0,
    SPARSE_G = 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 TestAllTypes : pb::GeneratedMessage<TestAllTypes, TestAllTypes.Builder> {
    private static readonly TestAllTypes defaultInstance = new Builder().BuildPartial();
    public static TestAllTypes DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestAllTypes DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestAllTypes ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestAllTypes__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestAllTypes, TestAllTypes.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestAllTypes__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 NestedEnum {
        FOO = 1,
        BAR = 2,
        BAZ = 3,
      }
      
      [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
      [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
      [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
      public sealed partial class NestedMessage : pb::GeneratedMessage<NestedMessage, NestedMessage.Builder> {
        private static readonly NestedMessage defaultInstance = new Builder().BuildPartial();
        public static NestedMessage DefaultInstance {
          get { return defaultInstance; }
        }
        
        public override NestedMessage DefaultInstanceForType {
          get { return defaultInstance; }
        }
        
        protected override NestedMessage ThisMessage {
          get { return this; }
        }
        
        public static pbd::MessageDescriptor Descriptor {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestAllTypes_NestedMessage__Descriptor; }
        }
        
        protected override pb::FieldAccess.FieldAccessorTable<NestedMessage, NestedMessage.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestAllTypes_NestedMessage__FieldAccessorTable; }
        }
        
        public const int BbFieldNumber = 1;
        private bool hasBb;
        private int bb_ = 0;
        public bool HasBb {
          get { return hasBb; }
        }
        public int Bb {
          get { return bb_; }
        }
        
        public override bool IsInitialized {
          get {
            return true;
          }
        }
        
        public override void WriteTo(pb::ICodedOutputStream output) {
          int size = SerializedSize;
          if (HasBb) {
            output.WriteInt32(1, "bb", Bb);
          }
          UnknownFields.WriteTo(output);
        }
        
        private int memoizedSerializedSize = -1;
        public override int SerializedSize {
          get {
            int size = memoizedSerializedSize;
            if (size != -1) return size;
            
            size = 0;
            if (HasBb) {
              size += pb::CodedOutputStream.ComputeInt32Size(1, Bb);
            }
            size += UnknownFields.SerializedSize;
            memoizedSerializedSize = size;
            return size;
          }
        }
        
        public static NestedMessage ParseFrom(pb::ByteString data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static NestedMessage ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static NestedMessage ParseFrom(byte[] data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static NestedMessage ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static NestedMessage ParseFrom(global::System.IO.Stream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static NestedMessage ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static NestedMessage ParseDelimitedFrom(global::System.IO.Stream input) {
          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
        }
        public static NestedMessage ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
        }
        public static NestedMessage ParseFrom(pb::CodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static NestedMessage 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(NestedMessage 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<NestedMessage, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {}
          
          NestedMessage result = new NestedMessage();
          
          protected override NestedMessage MessageBeingBuilt {
            get { return result; }
          }
          
          public override Builder Clear() {
            result = new NestedMessage();
            return this;
          }
          
          public override Builder Clone() {
            return new Builder().MergeFrom(result);
          }
          
          public override pbd::MessageDescriptor DescriptorForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.Descriptor; }
          }
          
          public override NestedMessage DefaultInstanceForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.DefaultInstance; }
          }
          
          public override NestedMessage BuildPartial() {
            if (result == null) {
              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
            }
            NestedMessage returnMe = result;
            result = null;
            return returnMe;
          }
          
          public override Builder MergeFrom(pb::IMessage other) {
            if (other is NestedMessage) {
              return MergeFrom((NestedMessage) other);
            } else {
              base.MergeFrom(other);
              return this;
            }
          }
          
          public override Builder MergeFrom(NestedMessage other) {
            if (other == global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.DefaultInstance) return this;
            if (other.HasBb) {
              Bb = other.Bb;
            }
            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;
            uint tag;
            string field_name;
            while (input.ReadTag(out tag, out field_name)) {
              switch (tag) {
                case 0: {
                  throw pb::InvalidProtocolBufferException.InvalidTag();
                }
                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, field_name);
                  break;
                }
                case 8: {
                  result.hasBb |= input.ReadInt32(ref result.bb_);
                  break;
                }
              }
            }
            
            if (unknownFields != null) {
              this.UnknownFields = unknownFields.Build();
            }
            return this;
          }
          
          
          public bool HasBb {
            get { return result.HasBb; }
          }
          public int Bb {
            get { return result.Bb; }
            set { SetBb(value); }
          }
          public Builder SetBb(int value) {
            result.hasBb = true;
            result.bb_ = value;
            return this;
          }
          public Builder ClearBb() {
            result.hasBb = false;
            result.bb_ = 0;
            return this;
          }
        }
        static NestedMessage() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 OptionalGroup : pb::GeneratedMessage<OptionalGroup, OptionalGroup.Builder> {
        private static readonly OptionalGroup defaultInstance = new Builder().BuildPartial();
        public static OptionalGroup DefaultInstance {
          get { return defaultInstance; }
        }
        
        public override OptionalGroup DefaultInstanceForType {
          get { return defaultInstance; }
        }
        
        protected override OptionalGroup ThisMessage {
          get { return this; }
        }
        
        public static pbd::MessageDescriptor Descriptor {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestAllTypes_OptionalGroup__Descriptor; }
        }
        
        protected override pb::FieldAccess.FieldAccessorTable<OptionalGroup, OptionalGroup.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestAllTypes_OptionalGroup__FieldAccessorTable; }
        }
        
        public const int AFieldNumber = 17;
        private bool hasA;
        private int a_ = 0;
        public bool HasA {
          get { return hasA; }
        }
        public int A {
          get { return a_; }
        }
        
        public override bool IsInitialized {
          get {
            return true;
          }
        }
        
        public override void WriteTo(pb::ICodedOutputStream output) {
          int size = SerializedSize;
          if (HasA) {
            output.WriteInt32(17, "a", A);
          }
          UnknownFields.WriteTo(output);
        }
        
        private int memoizedSerializedSize = -1;
        public override int SerializedSize {
          get {
            int size = memoizedSerializedSize;
            if (size != -1) return size;
            
            size = 0;
            if (HasA) {
              size += pb::CodedOutputStream.ComputeInt32Size(17, A);
            }
            size += UnknownFields.SerializedSize;
            memoizedSerializedSize = size;
            return size;
          }
        }
        
        public static OptionalGroup ParseFrom(pb::ByteString data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static OptionalGroup ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static OptionalGroup ParseFrom(byte[] data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static OptionalGroup ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static OptionalGroup ParseFrom(global::System.IO.Stream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static OptionalGroup ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static OptionalGroup ParseDelimitedFrom(global::System.IO.Stream input) {
          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
        }
        public static OptionalGroup ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
        }
        public static OptionalGroup ParseFrom(pb::CodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static OptionalGroup 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(OptionalGroup 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<OptionalGroup, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {}
          
          OptionalGroup result = new OptionalGroup();
          
          protected override OptionalGroup MessageBeingBuilt {
            get { return result; }
          }
          
          public override Builder Clear() {
            result = new OptionalGroup();
            return this;
          }
          
          public override Builder Clone() {
            return new Builder().MergeFrom(result);
          }
          
          public override pbd::MessageDescriptor DescriptorForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.OptionalGroup.Descriptor; }
          }
          
          public override OptionalGroup DefaultInstanceForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.OptionalGroup.DefaultInstance; }
          }
          
          public override OptionalGroup BuildPartial() {
            if (result == null) {
              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
            }
            OptionalGroup returnMe = result;
            result = null;
            return returnMe;
          }
          
          public override Builder MergeFrom(pb::IMessage other) {
            if (other is OptionalGroup) {
              return MergeFrom((OptionalGroup) other);
            } else {
              base.MergeFrom(other);
              return this;
            }
          }
          
          public override Builder MergeFrom(OptionalGroup other) {
            if (other == global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.OptionalGroup.DefaultInstance) return this;
            if (other.HasA) {
              A = other.A;
            }
            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;
            uint tag;
            string field_name;
            while (input.ReadTag(out tag, out field_name)) {
              switch (tag) {
                case 0: {
                  throw pb::InvalidProtocolBufferException.InvalidTag();
                }
                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, field_name);
                  break;
                }
                case 136: {
                  result.hasA |= input.ReadInt32(ref result.a_);
                  break;
                }
              }
            }
            
            if (unknownFields != null) {
              this.UnknownFields = unknownFields.Build();
            }
            return this;
          }
          
          
          public bool HasA {
            get { return result.HasA; }
          }
          public int A {
            get { return result.A; }
            set { SetA(value); }
          }
          public Builder SetA(int value) {
            result.hasA = true;
            result.a_ = value;
            return this;
          }
          public Builder ClearA() {
            result.hasA = false;
            result.a_ = 0;
            return this;
          }
        }
        static OptionalGroup() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 RepeatedGroup : pb::GeneratedMessage<RepeatedGroup, RepeatedGroup.Builder> {
        private static readonly RepeatedGroup defaultInstance = new Builder().BuildPartial();
        public static RepeatedGroup DefaultInstance {
          get { return defaultInstance; }
        }
        
        public override RepeatedGroup DefaultInstanceForType {
          get { return defaultInstance; }
        }
        
        protected override RepeatedGroup ThisMessage {
          get { return this; }
        }
        
        public static pbd::MessageDescriptor Descriptor {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestAllTypes_RepeatedGroup__Descriptor; }
        }
        
        protected override pb::FieldAccess.FieldAccessorTable<RepeatedGroup, RepeatedGroup.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestAllTypes_RepeatedGroup__FieldAccessorTable; }
        }
        
        public const int AFieldNumber = 47;
        private bool hasA;
        private int a_ = 0;
        public bool HasA {
          get { return hasA; }
        }
        public int A {
          get { return a_; }
        }
        
        public override bool IsInitialized {
          get {
            return true;
          }
        }
        
        public override void WriteTo(pb::ICodedOutputStream output) {
          int size = SerializedSize;
          if (HasA) {
            output.WriteInt32(47, "a", A);
          }
          UnknownFields.WriteTo(output);
        }
        
        private int memoizedSerializedSize = -1;
        public override int SerializedSize {
          get {
            int size = memoizedSerializedSize;
            if (size != -1) return size;
            
            size = 0;
            if (HasA) {
              size += pb::CodedOutputStream.ComputeInt32Size(47, A);
            }
            size += UnknownFields.SerializedSize;
            memoizedSerializedSize = size;
            return size;
          }
        }
        
        public static RepeatedGroup ParseFrom(pb::ByteString data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static RepeatedGroup ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static RepeatedGroup ParseFrom(byte[] data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static RepeatedGroup ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static RepeatedGroup ParseFrom(global::System.IO.Stream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static RepeatedGroup ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static RepeatedGroup ParseDelimitedFrom(global::System.IO.Stream input) {
          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
        }
        public static RepeatedGroup ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
        }
        public static RepeatedGroup ParseFrom(pb::CodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static RepeatedGroup 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(RepeatedGroup 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<RepeatedGroup, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {}
          
          RepeatedGroup result = new RepeatedGroup();
          
          protected override RepeatedGroup MessageBeingBuilt {
            get { return result; }
          }
          
          public override Builder Clear() {
            result = new RepeatedGroup();
            return this;
          }
          
          public override Builder Clone() {
            return new Builder().MergeFrom(result);
          }
          
          public override pbd::MessageDescriptor DescriptorForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup.Descriptor; }
          }
          
          public override RepeatedGroup DefaultInstanceForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup.DefaultInstance; }
          }
          
          public override RepeatedGroup BuildPartial() {
            if (result == null) {
              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
            }
            RepeatedGroup returnMe = result;
            result = null;
            return returnMe;
          }
          
          public override Builder MergeFrom(pb::IMessage other) {
            if (other is RepeatedGroup) {
              return MergeFrom((RepeatedGroup) other);
            } else {
              base.MergeFrom(other);
              return this;
            }
          }
          
          public override Builder MergeFrom(RepeatedGroup other) {
            if (other == global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup.DefaultInstance) return this;
            if (other.HasA) {
              A = other.A;
            }
            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;
            uint tag;
            string field_name;
            while (input.ReadTag(out tag, out field_name)) {
              switch (tag) {
                case 0: {
                  throw pb::InvalidProtocolBufferException.InvalidTag();
                }
                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, field_name);
                  break;
                }
                case 376: {
                  result.hasA |= input.ReadInt32(ref result.a_);
                  break;
                }
              }
            }
            
            if (unknownFields != null) {
              this.UnknownFields = unknownFields.Build();
            }
            return this;
          }
          
          
          public bool HasA {
            get { return result.HasA; }
          }
          public int A {
            get { return result.A; }
            set { SetA(value); }
          }
          public Builder SetA(int value) {
            result.hasA = true;
            result.a_ = value;
            return this;
          }
          public Builder ClearA() {
            result.hasA = false;
            result.a_ = 0;
            return this;
          }
        }
        static RepeatedGroup() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
        }
      }
      
    }
    #endregion
    
    public const int OptionalInt32FieldNumber = 1;
    private bool hasOptionalInt32;
    private int optionalInt32_ = 0;
    public bool HasOptionalInt32 {
      get { return hasOptionalInt32; }
    }
    public int OptionalInt32 {
      get { return optionalInt32_; }
    }
    
    public const int OptionalInt64FieldNumber = 2;
    private bool hasOptionalInt64;
    private long optionalInt64_ = 0L;
    public bool HasOptionalInt64 {
      get { return hasOptionalInt64; }
    }
    public long OptionalInt64 {
      get { return optionalInt64_; }
    }
    
    public const int OptionalUint32FieldNumber = 3;
    private bool hasOptionalUint32;
    private uint optionalUint32_ = 0;
    public bool HasOptionalUint32 {
      get { return hasOptionalUint32; }
    }
    [global::System.CLSCompliant(false)]
    public uint OptionalUint32 {
      get { return optionalUint32_; }
    }
    
    public const int OptionalUint64FieldNumber = 4;
    private bool hasOptionalUint64;
    private ulong optionalUint64_ = 0UL;
    public bool HasOptionalUint64 {
      get { return hasOptionalUint64; }
    }
    [global::System.CLSCompliant(false)]
    public ulong OptionalUint64 {
      get { return optionalUint64_; }
    }
    
    public const int OptionalSint32FieldNumber = 5;
    private bool hasOptionalSint32;
    private int optionalSint32_ = 0;
    public bool HasOptionalSint32 {
      get { return hasOptionalSint32; }
    }
    public int OptionalSint32 {
      get { return optionalSint32_; }
    }
    
    public const int OptionalSint64FieldNumber = 6;
    private bool hasOptionalSint64;
    private long optionalSint64_ = 0;
    public bool HasOptionalSint64 {
      get { return hasOptionalSint64; }
    }
    public long OptionalSint64 {
      get { return optionalSint64_; }
    }
    
    public const int OptionalFixed32FieldNumber = 7;
    private bool hasOptionalFixed32;
    private uint optionalFixed32_ = 0;
    public bool HasOptionalFixed32 {
      get { return hasOptionalFixed32; }
    }
    [global::System.CLSCompliant(false)]
    public uint OptionalFixed32 {
      get { return optionalFixed32_; }
    }
    
    public const int OptionalFixed64FieldNumber = 8;
    private bool hasOptionalFixed64;
    private ulong optionalFixed64_ = 0;
    public bool HasOptionalFixed64 {
      get { return hasOptionalFixed64; }
    }
    [global::System.CLSCompliant(false)]
    public ulong OptionalFixed64 {
      get { return optionalFixed64_; }
    }
    
    public const int OptionalSfixed32FieldNumber = 9;
    private bool hasOptionalSfixed32;
    private int optionalSfixed32_ = 0;
    public bool HasOptionalSfixed32 {
      get { return hasOptionalSfixed32; }
    }
    public int OptionalSfixed32 {
      get { return optionalSfixed32_; }
    }
    
    public const int OptionalSfixed64FieldNumber = 10;
    private bool hasOptionalSfixed64;
    private long optionalSfixed64_ = 0;
    public bool HasOptionalSfixed64 {
      get { return hasOptionalSfixed64; }
    }
    public long OptionalSfixed64 {
      get { return optionalSfixed64_; }
    }
    
    public const int OptionalFloatFieldNumber = 11;
    private bool hasOptionalFloat;
    private float optionalFloat_ = 0F;
    public bool HasOptionalFloat {
      get { return hasOptionalFloat; }
    }
    public float OptionalFloat {
      get { return optionalFloat_; }
    }
    
    public const int OptionalDoubleFieldNumber = 12;
    private bool hasOptionalDouble;
    private double optionalDouble_ = 0D;
    public bool HasOptionalDouble {
      get { return hasOptionalDouble; }
    }
    public double OptionalDouble {
      get { return optionalDouble_; }
    }
    
    public const int OptionalBoolFieldNumber = 13;
    private bool hasOptionalBool;
    private bool optionalBool_ = false;
    public bool HasOptionalBool {
      get { return hasOptionalBool; }
    }
    public bool OptionalBool {
      get { return optionalBool_; }
    }
    
    public const int OptionalStringFieldNumber = 14;
    private bool hasOptionalString;
    private string optionalString_ = "";
    public bool HasOptionalString {
      get { return hasOptionalString; }
    }
    public string OptionalString {
      get { return optionalString_; }
    }
    
    public const int OptionalBytesFieldNumber = 15;
    private bool hasOptionalBytes;
    private pb::ByteString optionalBytes_ = pb::ByteString.Empty;
    public bool HasOptionalBytes {
      get { return hasOptionalBytes; }
    }
    public pb::ByteString OptionalBytes {
      get { return optionalBytes_; }
    }
    
    public const int OptionalGroupFieldNumber = 16;
    private bool hasOptionalGroup;
    private global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.OptionalGroup optionalGroup_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.OptionalGroup.DefaultInstance;
    public bool HasOptionalGroup {
      get { return hasOptionalGroup; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.OptionalGroup OptionalGroup {
      get { return optionalGroup_; }
    }
    
    public const int OptionalNestedMessageFieldNumber = 18;
    private bool hasOptionalNestedMessage;
    private global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage optionalNestedMessage_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.DefaultInstance;
    public bool HasOptionalNestedMessage {
      get { return hasOptionalNestedMessage; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage OptionalNestedMessage {
      get { return optionalNestedMessage_; }
    }
    
    public const int OptionalForeignMessageFieldNumber = 19;
    private bool hasOptionalForeignMessage;
    private global::Google.ProtocolBuffers.TestProtos.ForeignMessage optionalForeignMessage_ = global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance;
    public bool HasOptionalForeignMessage {
      get { return hasOptionalForeignMessage; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ForeignMessage OptionalForeignMessage {
      get { return optionalForeignMessage_; }
    }
    
    public const int OptionalImportMessageFieldNumber = 20;
    private bool hasOptionalImportMessage;
    private global::Google.ProtocolBuffers.TestProtos.ImportMessage optionalImportMessage_ = global::Google.ProtocolBuffers.TestProtos.ImportMessage.DefaultInstance;
    public bool HasOptionalImportMessage {
      get { return hasOptionalImportMessage; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ImportMessage OptionalImportMessage {
      get { return optionalImportMessage_; }
    }
    
    public const int OptionalNestedEnumFieldNumber = 21;
    private bool hasOptionalNestedEnum;
    private global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum optionalNestedEnum_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum.FOO;
    public bool HasOptionalNestedEnum {
      get { return hasOptionalNestedEnum; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum OptionalNestedEnum {
      get { return optionalNestedEnum_; }
    }
    
    public const int OptionalForeignEnumFieldNumber = 22;
    private bool hasOptionalForeignEnum;
    private global::Google.ProtocolBuffers.TestProtos.ForeignEnum optionalForeignEnum_ = global::Google.ProtocolBuffers.TestProtos.ForeignEnum.FOREIGN_FOO;
    public bool HasOptionalForeignEnum {
      get { return hasOptionalForeignEnum; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ForeignEnum OptionalForeignEnum {
      get { return optionalForeignEnum_; }
    }
    
    public const int OptionalImportEnumFieldNumber = 23;
    private bool hasOptionalImportEnum;
    private global::Google.ProtocolBuffers.TestProtos.ImportEnum optionalImportEnum_ = global::Google.ProtocolBuffers.TestProtos.ImportEnum.IMPORT_FOO;
    public bool HasOptionalImportEnum {
      get { return hasOptionalImportEnum; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ImportEnum OptionalImportEnum {
      get { return optionalImportEnum_; }
    }
    
    public const int OptionalStringPieceFieldNumber = 24;
    private bool hasOptionalStringPiece;
    private string optionalStringPiece_ = "";
    public bool HasOptionalStringPiece {
      get { return hasOptionalStringPiece; }
    }
    public string OptionalStringPiece {
      get { return optionalStringPiece_; }
    }
    
    public const int OptionalCordFieldNumber = 25;
    private bool hasOptionalCord;
    private string optionalCord_ = "";
    public bool HasOptionalCord {
      get { return hasOptionalCord; }
    }
    public string OptionalCord {
      get { return optionalCord_; }
    }
    
    public const int RepeatedInt32FieldNumber = 31;
    private pbc::PopsicleList<int> repeatedInt32_ = new pbc::PopsicleList<int>();
    public scg::IList<int> RepeatedInt32List {
      get { return pbc::Lists.AsReadOnly(repeatedInt32_); }
    }
    public int RepeatedInt32Count {
      get { return repeatedInt32_.Count; }
    }
    public int GetRepeatedInt32(int index) {
      return repeatedInt32_[index];
    }
    
    public const int RepeatedInt64FieldNumber = 32;
    private pbc::PopsicleList<long> repeatedInt64_ = new pbc::PopsicleList<long>();
    public scg::IList<long> RepeatedInt64List {
      get { return pbc::Lists.AsReadOnly(repeatedInt64_); }
    }
    public int RepeatedInt64Count {
      get { return repeatedInt64_.Count; }
    }
    public long GetRepeatedInt64(int index) {
      return repeatedInt64_[index];
    }
    
    public const int RepeatedUint32FieldNumber = 33;
    private pbc::PopsicleList<uint> repeatedUint32_ = new pbc::PopsicleList<uint>();
    [global::System.CLSCompliant(false)]
    public scg::IList<uint> RepeatedUint32List {
      get { return pbc::Lists.AsReadOnly(repeatedUint32_); }
    }
    public int RepeatedUint32Count {
      get { return repeatedUint32_.Count; }
    }
    [global::System.CLSCompliant(false)]
    public uint GetRepeatedUint32(int index) {
      return repeatedUint32_[index];
    }
    
    public const int RepeatedUint64FieldNumber = 34;
    private pbc::PopsicleList<ulong> repeatedUint64_ = new pbc::PopsicleList<ulong>();
    [global::System.CLSCompliant(false)]
    public scg::IList<ulong> RepeatedUint64List {
      get { return pbc::Lists.AsReadOnly(repeatedUint64_); }
    }
    public int RepeatedUint64Count {
      get { return repeatedUint64_.Count; }
    }
    [global::System.CLSCompliant(false)]
    public ulong GetRepeatedUint64(int index) {
      return repeatedUint64_[index];
    }
    
    public const int RepeatedSint32FieldNumber = 35;
    private pbc::PopsicleList<int> repeatedSint32_ = new pbc::PopsicleList<int>();
    public scg::IList<int> RepeatedSint32List {
      get { return pbc::Lists.AsReadOnly(repeatedSint32_); }
    }
    public int RepeatedSint32Count {
      get { return repeatedSint32_.Count; }
    }
    public int GetRepeatedSint32(int index) {
      return repeatedSint32_[index];
    }
    
    public const int RepeatedSint64FieldNumber = 36;
    private pbc::PopsicleList<long> repeatedSint64_ = new pbc::PopsicleList<long>();
    public scg::IList<long> RepeatedSint64List {
      get { return pbc::Lists.AsReadOnly(repeatedSint64_); }
    }
    public int RepeatedSint64Count {
      get { return repeatedSint64_.Count; }
    }
    public long GetRepeatedSint64(int index) {
      return repeatedSint64_[index];
    }
    
    public const int RepeatedFixed32FieldNumber = 37;
    private pbc::PopsicleList<uint> repeatedFixed32_ = new pbc::PopsicleList<uint>();
    [global::System.CLSCompliant(false)]
    public scg::IList<uint> RepeatedFixed32List {
      get { return pbc::Lists.AsReadOnly(repeatedFixed32_); }
    }
    public int RepeatedFixed32Count {
      get { return repeatedFixed32_.Count; }
    }
    [global::System.CLSCompliant(false)]
    public uint GetRepeatedFixed32(int index) {
      return repeatedFixed32_[index];
    }
    
    public const int RepeatedFixed64FieldNumber = 38;
    private pbc::PopsicleList<ulong> repeatedFixed64_ = new pbc::PopsicleList<ulong>();
    [global::System.CLSCompliant(false)]
    public scg::IList<ulong> RepeatedFixed64List {
      get { return pbc::Lists.AsReadOnly(repeatedFixed64_); }
    }
    public int RepeatedFixed64Count {
      get { return repeatedFixed64_.Count; }
    }
    [global::System.CLSCompliant(false)]
    public ulong GetRepeatedFixed64(int index) {
      return repeatedFixed64_[index];
    }
    
    public const int RepeatedSfixed32FieldNumber = 39;
    private pbc::PopsicleList<int> repeatedSfixed32_ = new pbc::PopsicleList<int>();
    public scg::IList<int> RepeatedSfixed32List {
      get { return pbc::Lists.AsReadOnly(repeatedSfixed32_); }
    }
    public int RepeatedSfixed32Count {
      get { return repeatedSfixed32_.Count; }
    }
    public int GetRepeatedSfixed32(int index) {
      return repeatedSfixed32_[index];
    }
    
    public const int RepeatedSfixed64FieldNumber = 40;
    private pbc::PopsicleList<long> repeatedSfixed64_ = new pbc::PopsicleList<long>();
    public scg::IList<long> RepeatedSfixed64List {
      get { return pbc::Lists.AsReadOnly(repeatedSfixed64_); }
    }
    public int RepeatedSfixed64Count {
      get { return repeatedSfixed64_.Count; }
    }
    public long GetRepeatedSfixed64(int index) {
      return repeatedSfixed64_[index];
    }
    
    public const int RepeatedFloatFieldNumber = 41;
    private pbc::PopsicleList<float> repeatedFloat_ = new pbc::PopsicleList<float>();
    public scg::IList<float> RepeatedFloatList {
      get { return pbc::Lists.AsReadOnly(repeatedFloat_); }
    }
    public int RepeatedFloatCount {
      get { return repeatedFloat_.Count; }
    }
    public float GetRepeatedFloat(int index) {
      return repeatedFloat_[index];
    }
    
    public const int RepeatedDoubleFieldNumber = 42;
    private pbc::PopsicleList<double> repeatedDouble_ = new pbc::PopsicleList<double>();
    public scg::IList<double> RepeatedDoubleList {
      get { return pbc::Lists.AsReadOnly(repeatedDouble_); }
    }
    public int RepeatedDoubleCount {
      get { return repeatedDouble_.Count; }
    }
    public double GetRepeatedDouble(int index) {
      return repeatedDouble_[index];
    }
    
    public const int RepeatedBoolFieldNumber = 43;
    private pbc::PopsicleList<bool> repeatedBool_ = new pbc::PopsicleList<bool>();
    public scg::IList<bool> RepeatedBoolList {
      get { return pbc::Lists.AsReadOnly(repeatedBool_); }
    }
    public int RepeatedBoolCount {
      get { return repeatedBool_.Count; }
    }
    public bool GetRepeatedBool(int index) {
      return repeatedBool_[index];
    }
    
    public const int RepeatedStringFieldNumber = 44;
    private pbc::PopsicleList<string> repeatedString_ = new pbc::PopsicleList<string>();
    public scg::IList<string> RepeatedStringList {
      get { return pbc::Lists.AsReadOnly(repeatedString_); }
    }
    public int RepeatedStringCount {
      get { return repeatedString_.Count; }
    }
    public string GetRepeatedString(int index) {
      return repeatedString_[index];
    }
    
    public const int RepeatedBytesFieldNumber = 45;
    private pbc::PopsicleList<pb::ByteString> repeatedBytes_ = new pbc::PopsicleList<pb::ByteString>();
    public scg::IList<pb::ByteString> RepeatedBytesList {
      get { return pbc::Lists.AsReadOnly(repeatedBytes_); }
    }
    public int RepeatedBytesCount {
      get { return repeatedBytes_.Count; }
    }
    public pb::ByteString GetRepeatedBytes(int index) {
      return repeatedBytes_[index];
    }
    
    public const int RepeatedGroupFieldNumber = 46;
    private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup> repeatedGroup_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup>();
    public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup> RepeatedGroupList {
      get { return repeatedGroup_; }
    }
    public int RepeatedGroupCount {
      get { return repeatedGroup_.Count; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup GetRepeatedGroup(int index) {
      return repeatedGroup_[index];
    }
    
    public const int RepeatedNestedMessageFieldNumber = 48;
    private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage> repeatedNestedMessage_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage>();
    public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage> RepeatedNestedMessageList {
      get { return repeatedNestedMessage_; }
    }
    public int RepeatedNestedMessageCount {
      get { return repeatedNestedMessage_.Count; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage GetRepeatedNestedMessage(int index) {
      return repeatedNestedMessage_[index];
    }
    
    public const int RepeatedForeignMessageFieldNumber = 49;
    private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignMessage> repeatedForeignMessage_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignMessage>();
    public scg::IList<global::Google.ProtocolBuffers.TestProtos.ForeignMessage> RepeatedForeignMessageList {
      get { return repeatedForeignMessage_; }
    }
    public int RepeatedForeignMessageCount {
      get { return repeatedForeignMessage_.Count; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ForeignMessage GetRepeatedForeignMessage(int index) {
      return repeatedForeignMessage_[index];
    }
    
    public const int RepeatedImportMessageFieldNumber = 50;
    private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.ImportMessage> repeatedImportMessage_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.ImportMessage>();
    public scg::IList<global::Google.ProtocolBuffers.TestProtos.ImportMessage> RepeatedImportMessageList {
      get { return repeatedImportMessage_; }
    }
    public int RepeatedImportMessageCount {
      get { return repeatedImportMessage_.Count; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ImportMessage GetRepeatedImportMessage(int index) {
      return repeatedImportMessage_[index];
    }
    
    public const int RepeatedNestedEnumFieldNumber = 51;
    private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum> repeatedNestedEnum_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum>();
    public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum> RepeatedNestedEnumList {
      get { return pbc::Lists.AsReadOnly(repeatedNestedEnum_); }
    }
    public int RepeatedNestedEnumCount {
      get { return repeatedNestedEnum_.Count; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum GetRepeatedNestedEnum(int index) {
      return repeatedNestedEnum_[index];
    }
    
    public const int RepeatedForeignEnumFieldNumber = 52;
    private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> repeatedForeignEnum_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>();
    public scg::IList<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> RepeatedForeignEnumList {
      get { return pbc::Lists.AsReadOnly(repeatedForeignEnum_); }
    }
    public int RepeatedForeignEnumCount {
      get { return repeatedForeignEnum_.Count; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ForeignEnum GetRepeatedForeignEnum(int index) {
      return repeatedForeignEnum_[index];
    }
    
    public const int RepeatedImportEnumFieldNumber = 53;
    private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.ImportEnum> repeatedImportEnum_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.ImportEnum>();
    public scg::IList<global::Google.ProtocolBuffers.TestProtos.ImportEnum> RepeatedImportEnumList {
      get { return pbc::Lists.AsReadOnly(repeatedImportEnum_); }
    }
    public int RepeatedImportEnumCount {
      get { return repeatedImportEnum_.Count; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ImportEnum GetRepeatedImportEnum(int index) {
      return repeatedImportEnum_[index];
    }
    
    public const int RepeatedStringPieceFieldNumber = 54;
    private pbc::PopsicleList<string> repeatedStringPiece_ = new pbc::PopsicleList<string>();
    public scg::IList<string> RepeatedStringPieceList {
      get { return pbc::Lists.AsReadOnly(repeatedStringPiece_); }
    }
    public int RepeatedStringPieceCount {
      get { return repeatedStringPiece_.Count; }
    }
    public string GetRepeatedStringPiece(int index) {
      return repeatedStringPiece_[index];
    }
    
    public const int RepeatedCordFieldNumber = 55;
    private pbc::PopsicleList<string> repeatedCord_ = new pbc::PopsicleList<string>();
    public scg::IList<string> RepeatedCordList {
      get { return pbc::Lists.AsReadOnly(repeatedCord_); }
    }
    public int RepeatedCordCount {
      get { return repeatedCord_.Count; }
    }
    public string GetRepeatedCord(int index) {
      return repeatedCord_[index];
    }
    
    public const int DefaultInt32FieldNumber = 61;
    private bool hasDefaultInt32;
    private int defaultInt32_ = 41;
    public bool HasDefaultInt32 {
      get { return hasDefaultInt32; }
    }
    public int DefaultInt32 {
      get { return defaultInt32_; }
    }
    
    public const int DefaultInt64FieldNumber = 62;
    private bool hasDefaultInt64;
    private long defaultInt64_ = 42L;
    public bool HasDefaultInt64 {
      get { return hasDefaultInt64; }
    }
    public long DefaultInt64 {
      get { return defaultInt64_; }
    }
    
    public const int DefaultUint32FieldNumber = 63;
    private bool hasDefaultUint32;
    private uint defaultUint32_ = 43;
    public bool HasDefaultUint32 {
      get { return hasDefaultUint32; }
    }
    [global::System.CLSCompliant(false)]
    public uint DefaultUint32 {
      get { return defaultUint32_; }
    }
    
    public const int DefaultUint64FieldNumber = 64;
    private bool hasDefaultUint64;
    private ulong defaultUint64_ = 44UL;
    public bool HasDefaultUint64 {
      get { return hasDefaultUint64; }
    }
    [global::System.CLSCompliant(false)]
    public ulong DefaultUint64 {
      get { return defaultUint64_; }
    }
    
    public const int DefaultSint32FieldNumber = 65;
    private bool hasDefaultSint32;
    private int defaultSint32_ = -45;
    public bool HasDefaultSint32 {
      get { return hasDefaultSint32; }
    }
    public int DefaultSint32 {
      get { return defaultSint32_; }
    }
    
    public const int DefaultSint64FieldNumber = 66;
    private bool hasDefaultSint64;
    private long defaultSint64_ = 46;
    public bool HasDefaultSint64 {
      get { return hasDefaultSint64; }
    }
    public long DefaultSint64 {
      get { return defaultSint64_; }
    }
    
    public const int DefaultFixed32FieldNumber = 67;
    private bool hasDefaultFixed32;
    private uint defaultFixed32_ = 47;
    public bool HasDefaultFixed32 {
      get { return hasDefaultFixed32; }
    }
    [global::System.CLSCompliant(false)]
    public uint DefaultFixed32 {
      get { return defaultFixed32_; }
    }
    
    public const int DefaultFixed64FieldNumber = 68;
    private bool hasDefaultFixed64;
    private ulong defaultFixed64_ = 48;
    public bool HasDefaultFixed64 {
      get { return hasDefaultFixed64; }
    }
    [global::System.CLSCompliant(false)]
    public ulong DefaultFixed64 {
      get { return defaultFixed64_; }
    }
    
    public const int DefaultSfixed32FieldNumber = 69;
    private bool hasDefaultSfixed32;
    private int defaultSfixed32_ = 49;
    public bool HasDefaultSfixed32 {
      get { return hasDefaultSfixed32; }
    }
    public int DefaultSfixed32 {
      get { return defaultSfixed32_; }
    }
    
    public const int DefaultSfixed64FieldNumber = 70;
    private bool hasDefaultSfixed64;
    private long defaultSfixed64_ = -50;
    public bool HasDefaultSfixed64 {
      get { return hasDefaultSfixed64; }
    }
    public long DefaultSfixed64 {
      get { return defaultSfixed64_; }
    }
    
    public const int DefaultFloatFieldNumber = 71;
    private bool hasDefaultFloat;
    private float defaultFloat_ = 51.5F;
    public bool HasDefaultFloat {
      get { return hasDefaultFloat; }
    }
    public float DefaultFloat {
      get { return defaultFloat_; }
    }
    
    public const int DefaultDoubleFieldNumber = 72;
    private bool hasDefaultDouble;
    private double defaultDouble_ = 52000D;
    public bool HasDefaultDouble {
      get { return hasDefaultDouble; }
    }
    public double DefaultDouble {
      get { return defaultDouble_; }
    }
    
    public const int DefaultBoolFieldNumber = 73;
    private bool hasDefaultBool;
    private bool defaultBool_ = true;
    public bool HasDefaultBool {
      get { return hasDefaultBool; }
    }
    public bool DefaultBool {
      get { return defaultBool_; }
    }
    
    public const int DefaultStringFieldNumber = 74;
    private bool hasDefaultString;
    private string defaultString_ = "hello";
    public bool HasDefaultString {
      get { return hasDefaultString; }
    }
    public string DefaultString {
      get { return defaultString_; }
    }
    
    public const int DefaultBytesFieldNumber = 75;
    private bool hasDefaultBytes;
    private pb::ByteString defaultBytes_ = (pb::ByteString) global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Descriptor.Fields[62].DefaultValue;
    public bool HasDefaultBytes {
      get { return hasDefaultBytes; }
    }
    public pb::ByteString DefaultBytes {
      get { return defaultBytes_; }
    }
    
    public const int DefaultNestedEnumFieldNumber = 81;
    private bool hasDefaultNestedEnum;
    private global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum defaultNestedEnum_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum.BAR;
    public bool HasDefaultNestedEnum {
      get { return hasDefaultNestedEnum; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum DefaultNestedEnum {
      get { return defaultNestedEnum_; }
    }
    
    public const int DefaultForeignEnumFieldNumber = 82;
    private bool hasDefaultForeignEnum;
    private global::Google.ProtocolBuffers.TestProtos.ForeignEnum defaultForeignEnum_ = global::Google.ProtocolBuffers.TestProtos.ForeignEnum.FOREIGN_BAR;
    public bool HasDefaultForeignEnum {
      get { return hasDefaultForeignEnum; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ForeignEnum DefaultForeignEnum {
      get { return defaultForeignEnum_; }
    }
    
    public const int DefaultImportEnumFieldNumber = 83;
    private bool hasDefaultImportEnum;
    private global::Google.ProtocolBuffers.TestProtos.ImportEnum defaultImportEnum_ = global::Google.ProtocolBuffers.TestProtos.ImportEnum.IMPORT_BAR;
    public bool HasDefaultImportEnum {
      get { return hasDefaultImportEnum; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ImportEnum DefaultImportEnum {
      get { return defaultImportEnum_; }
    }
    
    public const int DefaultStringPieceFieldNumber = 84;
    private bool hasDefaultStringPiece;
    private string defaultStringPiece_ = "abc";
    public bool HasDefaultStringPiece {
      get { return hasDefaultStringPiece; }
    }
    public string DefaultStringPiece {
      get { return defaultStringPiece_; }
    }
    
    public const int DefaultCordFieldNumber = 85;
    private bool hasDefaultCord;
    private string defaultCord_ = "123";
    public bool HasDefaultCord {
      get { return hasDefaultCord; }
    }
    public string DefaultCord {
      get { return defaultCord_; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (HasOptionalInt32) {
        output.WriteInt32(1, "optional_int32", OptionalInt32);
      }
      if (HasOptionalInt64) {
        output.WriteInt64(2, "optional_int64", OptionalInt64);
      }
      if (HasOptionalUint32) {
        output.WriteUInt32(3, "optional_uint32", OptionalUint32);
      }
      if (HasOptionalUint64) {
        output.WriteUInt64(4, "optional_uint64", OptionalUint64);
      }
      if (HasOptionalSint32) {
        output.WriteSInt32(5, "optional_sint32", OptionalSint32);
      }
      if (HasOptionalSint64) {
        output.WriteSInt64(6, "optional_sint64", OptionalSint64);
      }
      if (HasOptionalFixed32) {
        output.WriteFixed32(7, "optional_fixed32", OptionalFixed32);
      }
      if (HasOptionalFixed64) {
        output.WriteFixed64(8, "optional_fixed64", OptionalFixed64);
      }
      if (HasOptionalSfixed32) {
        output.WriteSFixed32(9, "optional_sfixed32", OptionalSfixed32);
      }
      if (HasOptionalSfixed64) {
        output.WriteSFixed64(10, "optional_sfixed64", OptionalSfixed64);
      }
      if (HasOptionalFloat) {
        output.WriteFloat(11, "optional_float", OptionalFloat);
      }
      if (HasOptionalDouble) {
        output.WriteDouble(12, "optional_double", OptionalDouble);
      }
      if (HasOptionalBool) {
        output.WriteBool(13, "optional_bool", OptionalBool);
      }
      if (HasOptionalString) {
        output.WriteString(14, "optional_string", OptionalString);
      }
      if (HasOptionalBytes) {
        output.WriteBytes(15, "optional_bytes", OptionalBytes);
      }
      if (HasOptionalGroup) {
        output.WriteGroup(16, "optionalgroup", OptionalGroup);
      }
      if (HasOptionalNestedMessage) {
        output.WriteMessage(18, "optional_nested_message", OptionalNestedMessage);
      }
      if (HasOptionalForeignMessage) {
        output.WriteMessage(19, "optional_foreign_message", OptionalForeignMessage);
      }
      if (HasOptionalImportMessage) {
        output.WriteMessage(20, "optional_import_message", OptionalImportMessage);
      }
      if (HasOptionalNestedEnum) {
        output.WriteEnum(21, "optional_nested_enum", (int) OptionalNestedEnum, OptionalNestedEnum.ToString());
      }
      if (HasOptionalForeignEnum) {
        output.WriteEnum(22, "optional_foreign_enum", (int) OptionalForeignEnum, OptionalForeignEnum.ToString());
      }
      if (HasOptionalImportEnum) {
        output.WriteEnum(23, "optional_import_enum", (int) OptionalImportEnum, OptionalImportEnum.ToString());
      }
      if (HasOptionalStringPiece) {
        output.WriteString(24, "optional_string_piece", OptionalStringPiece);
      }
      if (HasOptionalCord) {
        output.WriteString(25, "optional_cord", OptionalCord);
      }
      if (repeatedInt32_.Count > 0) {
        output.WriteArray(pbd::FieldType.Int32, 31, "repeated_int32", repeatedInt32_);
      }
      if (repeatedInt64_.Count > 0) {
        output.WriteArray(pbd::FieldType.Int64, 32, "repeated_int64", repeatedInt64_);
      }
      if (repeatedUint32_.Count > 0) {
        output.WriteArray(pbd::FieldType.UInt32, 33, "repeated_uint32", repeatedUint32_);
      }
      if (repeatedUint64_.Count > 0) {
        output.WriteArray(pbd::FieldType.UInt64, 34, "repeated_uint64", repeatedUint64_);
      }
      if (repeatedSint32_.Count > 0) {
        output.WriteArray(pbd::FieldType.SInt32, 35, "repeated_sint32", repeatedSint32_);
      }
      if (repeatedSint64_.Count > 0) {
        output.WriteArray(pbd::FieldType.SInt64, 36, "repeated_sint64", repeatedSint64_);
      }
      if (repeatedFixed32_.Count > 0) {
        output.WriteArray(pbd::FieldType.Fixed32, 37, "repeated_fixed32", repeatedFixed32_);
      }
      if (repeatedFixed64_.Count > 0) {
        output.WriteArray(pbd::FieldType.Fixed64, 38, "repeated_fixed64", repeatedFixed64_);
      }
      if (repeatedSfixed32_.Count > 0) {
        output.WriteArray(pbd::FieldType.SFixed32, 39, "repeated_sfixed32", repeatedSfixed32_);
      }
      if (repeatedSfixed64_.Count > 0) {
        output.WriteArray(pbd::FieldType.SFixed64, 40, "repeated_sfixed64", repeatedSfixed64_);
      }
      if (repeatedFloat_.Count > 0) {
        output.WriteArray(pbd::FieldType.Float, 41, "repeated_float", repeatedFloat_);
      }
      if (repeatedDouble_.Count > 0) {
        output.WriteArray(pbd::FieldType.Double, 42, "repeated_double", repeatedDouble_);
      }
      if (repeatedBool_.Count > 0) {
        output.WriteArray(pbd::FieldType.Bool, 43, "repeated_bool", repeatedBool_);
      }
      if (repeatedString_.Count > 0) {
        output.WriteArray(pbd::FieldType.String, 44, "repeated_string", repeatedString_);
      }
      if (repeatedBytes_.Count > 0) {
        output.WriteArray(pbd::FieldType.Bytes, 45, "repeated_bytes", repeatedBytes_);
      }
      if (repeatedGroup_.Count > 0) {
        output.WriteArray(pbd::FieldType.Group, 46, "repeatedgroup", repeatedGroup_);
      }
      if (repeatedNestedMessage_.Count > 0) {
        output.WriteArray(pbd::FieldType.Message, 48, "repeated_nested_message", repeatedNestedMessage_);
      }
      if (repeatedForeignMessage_.Count > 0) {
        output.WriteArray(pbd::FieldType.Message, 49, "repeated_foreign_message", repeatedForeignMessage_);
      }
      if (repeatedImportMessage_.Count > 0) {
        output.WriteArray(pbd::FieldType.Message, 50, "repeated_import_message", repeatedImportMessage_);
      }
      if (repeatedNestedEnum_.Count > 0) {
        output.WriteArray(pbd::FieldType.Enum, 51, "repeated_nested_enum", repeatedNestedEnum_);
      }
      if (repeatedForeignEnum_.Count > 0) {
        output.WriteArray(pbd::FieldType.Enum, 52, "repeated_foreign_enum", repeatedForeignEnum_);
      }
      if (repeatedImportEnum_.Count > 0) {
        output.WriteArray(pbd::FieldType.Enum, 53, "repeated_import_enum", repeatedImportEnum_);
      }
      if (repeatedStringPiece_.Count > 0) {
        output.WriteArray(pbd::FieldType.String, 54, "repeated_string_piece", repeatedStringPiece_);
      }
      if (repeatedCord_.Count > 0) {
        output.WriteArray(pbd::FieldType.String, 55, "repeated_cord", repeatedCord_);
      }
      if (HasDefaultInt32) {
        output.WriteInt32(61, "default_int32", DefaultInt32);
      }
      if (HasDefaultInt64) {
        output.WriteInt64(62, "default_int64", DefaultInt64);
      }
      if (HasDefaultUint32) {
        output.WriteUInt32(63, "default_uint32", DefaultUint32);
      }
      if (HasDefaultUint64) {
        output.WriteUInt64(64, "default_uint64", DefaultUint64);
      }
      if (HasDefaultSint32) {
        output.WriteSInt32(65, "default_sint32", DefaultSint32);
      }
      if (HasDefaultSint64) {
        output.WriteSInt64(66, "default_sint64", DefaultSint64);
      }
      if (HasDefaultFixed32) {
        output.WriteFixed32(67, "default_fixed32", DefaultFixed32);
      }
      if (HasDefaultFixed64) {
        output.WriteFixed64(68, "default_fixed64", DefaultFixed64);
      }
      if (HasDefaultSfixed32) {
        output.WriteSFixed32(69, "default_sfixed32", DefaultSfixed32);
      }
      if (HasDefaultSfixed64) {
        output.WriteSFixed64(70, "default_sfixed64", DefaultSfixed64);
      }
      if (HasDefaultFloat) {
        output.WriteFloat(71, "default_float", DefaultFloat);
      }
      if (HasDefaultDouble) {
        output.WriteDouble(72, "default_double", DefaultDouble);
      }
      if (HasDefaultBool) {
        output.WriteBool(73, "default_bool", DefaultBool);
      }
      if (HasDefaultString) {
        output.WriteString(74, "default_string", DefaultString);
      }
      if (HasDefaultBytes) {
        output.WriteBytes(75, "default_bytes", DefaultBytes);
      }
      if (HasDefaultNestedEnum) {
        output.WriteEnum(81, "default_nested_enum", (int) DefaultNestedEnum, DefaultNestedEnum.ToString());
      }
      if (HasDefaultForeignEnum) {
        output.WriteEnum(82, "default_foreign_enum", (int) DefaultForeignEnum, DefaultForeignEnum.ToString());
      }
      if (HasDefaultImportEnum) {
        output.WriteEnum(83, "default_import_enum", (int) DefaultImportEnum, DefaultImportEnum.ToString());
      }
      if (HasDefaultStringPiece) {
        output.WriteString(84, "default_string_piece", DefaultStringPiece);
      }
      if (HasDefaultCord) {
        output.WriteString(85, "default_cord", DefaultCord);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasOptionalInt32) {
          size += pb::CodedOutputStream.ComputeInt32Size(1, OptionalInt32);
        }
        if (HasOptionalInt64) {
          size += pb::CodedOutputStream.ComputeInt64Size(2, OptionalInt64);
        }
        if (HasOptionalUint32) {
          size += pb::CodedOutputStream.ComputeUInt32Size(3, OptionalUint32);
        }
        if (HasOptionalUint64) {
          size += pb::CodedOutputStream.ComputeUInt64Size(4, OptionalUint64);
        }
        if (HasOptionalSint32) {
          size += pb::CodedOutputStream.ComputeSInt32Size(5, OptionalSint32);
        }
        if (HasOptionalSint64) {
          size += pb::CodedOutputStream.ComputeSInt64Size(6, OptionalSint64);
        }
        if (HasOptionalFixed32) {
          size += pb::CodedOutputStream.ComputeFixed32Size(7, OptionalFixed32);
        }
        if (HasOptionalFixed64) {
          size += pb::CodedOutputStream.ComputeFixed64Size(8, OptionalFixed64);
        }
        if (HasOptionalSfixed32) {
          size += pb::CodedOutputStream.ComputeSFixed32Size(9, OptionalSfixed32);
        }
        if (HasOptionalSfixed64) {
          size += pb::CodedOutputStream.ComputeSFixed64Size(10, OptionalSfixed64);
        }
        if (HasOptionalFloat) {
          size += pb::CodedOutputStream.ComputeFloatSize(11, OptionalFloat);
        }
        if (HasOptionalDouble) {
          size += pb::CodedOutputStream.ComputeDoubleSize(12, OptionalDouble);
        }
        if (HasOptionalBool) {
          size += pb::CodedOutputStream.ComputeBoolSize(13, OptionalBool);
        }
        if (HasOptionalString) {
          size += pb::CodedOutputStream.ComputeStringSize(14, OptionalString);
        }
        if (HasOptionalBytes) {
          size += pb::CodedOutputStream.ComputeBytesSize(15, OptionalBytes);
        }
        if (HasOptionalGroup) {
          size += pb::CodedOutputStream.ComputeGroupSize(16, OptionalGroup);
        }
        if (HasOptionalNestedMessage) {
          size += pb::CodedOutputStream.ComputeMessageSize(18, OptionalNestedMessage);
        }
        if (HasOptionalForeignMessage) {
          size += pb::CodedOutputStream.ComputeMessageSize(19, OptionalForeignMessage);
        }
        if (HasOptionalImportMessage) {
          size += pb::CodedOutputStream.ComputeMessageSize(20, OptionalImportMessage);
        }
        if (HasOptionalNestedEnum) {
          size += pb::CodedOutputStream.ComputeEnumSize(21, (int) OptionalNestedEnum);
        }
        if (HasOptionalForeignEnum) {
          size += pb::CodedOutputStream.ComputeEnumSize(22, (int) OptionalForeignEnum);
        }
        if (HasOptionalImportEnum) {
          size += pb::CodedOutputStream.ComputeEnumSize(23, (int) OptionalImportEnum);
        }
        if (HasOptionalStringPiece) {
          size += pb::CodedOutputStream.ComputeStringSize(24, OptionalStringPiece);
        }
        if (HasOptionalCord) {
          size += pb::CodedOutputStream.ComputeStringSize(25, OptionalCord);
        }
        {
          int dataSize = 0;
          foreach (int element in RepeatedInt32List) {
            dataSize += pb::CodedOutputStream.ComputeInt32SizeNoTag(element);
          }
          size += dataSize;
          size += 2 * repeatedInt32_.Count;
        }
        {
          int dataSize = 0;
          foreach (long element in RepeatedInt64List) {
            dataSize += pb::CodedOutputStream.ComputeInt64SizeNoTag(element);
          }
          size += dataSize;
          size += 2 * repeatedInt64_.Count;
        }
        {
          int dataSize = 0;
          foreach (uint element in RepeatedUint32List) {
            dataSize += pb::CodedOutputStream.ComputeUInt32SizeNoTag(element);
          }
          size += dataSize;
          size += 2 * repeatedUint32_.Count;
        }
        {
          int dataSize = 0;
          foreach (ulong element in RepeatedUint64List) {
            dataSize += pb::CodedOutputStream.ComputeUInt64SizeNoTag(element);
          }
          size += dataSize;
          size += 2 * repeatedUint64_.Count;
        }
        {
          int dataSize = 0;
          foreach (int element in RepeatedSint32List) {
            dataSize += pb::CodedOutputStream.ComputeSInt32SizeNoTag(element);
          }
          size += dataSize;
          size += 2 * repeatedSint32_.Count;
        }
        {
          int dataSize = 0;
          foreach (long element in RepeatedSint64List) {
            dataSize += pb::CodedOutputStream.ComputeSInt64SizeNoTag(element);
          }
          size += dataSize;
          size += 2 * repeatedSint64_.Count;
        }
        {
          int dataSize = 0;
          dataSize = 4 * repeatedFixed32_.Count;
          size += dataSize;
          size += 2 * repeatedFixed32_.Count;
        }
        {
          int dataSize = 0;
          dataSize = 8 * repeatedFixed64_.Count;
          size += dataSize;
          size += 2 * repeatedFixed64_.Count;
        }
        {
          int dataSize = 0;
          dataSize = 4 * repeatedSfixed32_.Count;
          size += dataSize;
          size += 2 * repeatedSfixed32_.Count;
        }
        {
          int dataSize = 0;
          dataSize = 8 * repeatedSfixed64_.Count;
          size += dataSize;
          size += 2 * repeatedSfixed64_.Count;
        }
        {
          int dataSize = 0;
          dataSize = 4 * repeatedFloat_.Count;
          size += dataSize;
          size += 2 * repeatedFloat_.Count;
        }
        {
          int dataSize = 0;
          dataSize = 8 * repeatedDouble_.Count;
          size += dataSize;
          size += 2 * repeatedDouble_.Count;
        }
        {
          int dataSize = 0;
          dataSize = 1 * repeatedBool_.Count;
          size += dataSize;
          size += 2 * repeatedBool_.Count;
        }
        {
          int dataSize = 0;
          foreach (string element in RepeatedStringList) {
            dataSize += pb::CodedOutputStream.ComputeStringSizeNoTag(element);
          }
          size += dataSize;
          size += 2 * repeatedString_.Count;
        }
        {
          int dataSize = 0;
          foreach (pb::ByteString element in RepeatedBytesList) {
            dataSize += pb::CodedOutputStream.ComputeBytesSizeNoTag(element);
          }
          size += dataSize;
          size += 2 * repeatedBytes_.Count;
        }
        foreach (global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup element in RepeatedGroupList) {
          size += pb::CodedOutputStream.ComputeGroupSize(46, element);
        }
        foreach (global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage element in RepeatedNestedMessageList) {
          size += pb::CodedOutputStream.ComputeMessageSize(48, element);
        }
        foreach (global::Google.ProtocolBuffers.TestProtos.ForeignMessage element in RepeatedForeignMessageList) {
          size += pb::CodedOutputStream.ComputeMessageSize(49, element);
        }
        foreach (global::Google.ProtocolBuffers.TestProtos.ImportMessage element in RepeatedImportMessageList) {
          size += pb::CodedOutputStream.ComputeMessageSize(50, element);
        }
        {
          int dataSize = 0;
          if (repeatedNestedEnum_.Count > 0) {
            foreach (global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum element in repeatedNestedEnum_) {
              dataSize += pb::CodedOutputStream.ComputeEnumSizeNoTag((int) element);
            }
            size += dataSize;
            size += 2 * repeatedNestedEnum_.Count;
          }
        }
        {
          int dataSize = 0;
          if (repeatedForeignEnum_.Count > 0) {
            foreach (global::Google.ProtocolBuffers.TestProtos.ForeignEnum element in repeatedForeignEnum_) {
              dataSize += pb::CodedOutputStream.ComputeEnumSizeNoTag((int) element);
            }
            size += dataSize;
            size += 2 * repeatedForeignEnum_.Count;
          }
        }
        {
          int dataSize = 0;
          if (repeatedImportEnum_.Count > 0) {
            foreach (global::Google.ProtocolBuffers.TestProtos.ImportEnum element in repeatedImportEnum_) {
              dataSize += pb::CodedOutputStream.ComputeEnumSizeNoTag((int) element);
            }
            size += dataSize;
            size += 2 * repeatedImportEnum_.Count;
          }
        }
        {
          int dataSize = 0;
          foreach (string element in RepeatedStringPieceList) {
            dataSize += pb::CodedOutputStream.ComputeStringSizeNoTag(element);
          }
          size += dataSize;
          size += 2 * repeatedStringPiece_.Count;
        }
        {
          int dataSize = 0;
          foreach (string element in RepeatedCordList) {
            dataSize += pb::CodedOutputStream.ComputeStringSizeNoTag(element);
          }
          size += dataSize;
          size += 2 * repeatedCord_.Count;
        }
        if (HasDefaultInt32) {
          size += pb::CodedOutputStream.ComputeInt32Size(61, DefaultInt32);
        }
        if (HasDefaultInt64) {
          size += pb::CodedOutputStream.ComputeInt64Size(62, DefaultInt64);
        }
        if (HasDefaultUint32) {
          size += pb::CodedOutputStream.ComputeUInt32Size(63, DefaultUint32);
        }
        if (HasDefaultUint64) {
          size += pb::CodedOutputStream.ComputeUInt64Size(64, DefaultUint64);
        }
        if (HasDefaultSint32) {
          size += pb::CodedOutputStream.ComputeSInt32Size(65, DefaultSint32);
        }
        if (HasDefaultSint64) {
          size += pb::CodedOutputStream.ComputeSInt64Size(66, DefaultSint64);
        }
        if (HasDefaultFixed32) {
          size += pb::CodedOutputStream.ComputeFixed32Size(67, DefaultFixed32);
        }
        if (HasDefaultFixed64) {
          size += pb::CodedOutputStream.ComputeFixed64Size(68, DefaultFixed64);
        }
        if (HasDefaultSfixed32) {
          size += pb::CodedOutputStream.ComputeSFixed32Size(69, DefaultSfixed32);
        }
        if (HasDefaultSfixed64) {
          size += pb::CodedOutputStream.ComputeSFixed64Size(70, DefaultSfixed64);
        }
        if (HasDefaultFloat) {
          size += pb::CodedOutputStream.ComputeFloatSize(71, DefaultFloat);
        }
        if (HasDefaultDouble) {
          size += pb::CodedOutputStream.ComputeDoubleSize(72, DefaultDouble);
        }
        if (HasDefaultBool) {
          size += pb::CodedOutputStream.ComputeBoolSize(73, DefaultBool);
        }
        if (HasDefaultString) {
          size += pb::CodedOutputStream.ComputeStringSize(74, DefaultString);
        }
        if (HasDefaultBytes) {
          size += pb::CodedOutputStream.ComputeBytesSize(75, DefaultBytes);
        }
        if (HasDefaultNestedEnum) {
          size += pb::CodedOutputStream.ComputeEnumSize(81, (int) DefaultNestedEnum);
        }
        if (HasDefaultForeignEnum) {
          size += pb::CodedOutputStream.ComputeEnumSize(82, (int) DefaultForeignEnum);
        }
        if (HasDefaultImportEnum) {
          size += pb::CodedOutputStream.ComputeEnumSize(83, (int) DefaultImportEnum);
        }
        if (HasDefaultStringPiece) {
          size += pb::CodedOutputStream.ComputeStringSize(84, DefaultStringPiece);
        }
        if (HasDefaultCord) {
          size += pb::CodedOutputStream.ComputeStringSize(85, DefaultCord);
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static TestAllTypes ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestAllTypes ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestAllTypes ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestAllTypes ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestAllTypes ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestAllTypes ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestAllTypes ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestAllTypes ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestAllTypes ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestAllTypes 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(TestAllTypes 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<TestAllTypes, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestAllTypes result = new TestAllTypes();
      
      protected override TestAllTypes MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestAllTypes();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Descriptor; }
      }
      
      public override TestAllTypes DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance; }
      }
      
      public override TestAllTypes BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        result.repeatedInt32_.MakeReadOnly();
        result.repeatedInt64_.MakeReadOnly();
        result.repeatedUint32_.MakeReadOnly();
        result.repeatedUint64_.MakeReadOnly();
        result.repeatedSint32_.MakeReadOnly();
        result.repeatedSint64_.MakeReadOnly();
        result.repeatedFixed32_.MakeReadOnly();
        result.repeatedFixed64_.MakeReadOnly();
        result.repeatedSfixed32_.MakeReadOnly();
        result.repeatedSfixed64_.MakeReadOnly();
        result.repeatedFloat_.MakeReadOnly();
        result.repeatedDouble_.MakeReadOnly();
        result.repeatedBool_.MakeReadOnly();
        result.repeatedString_.MakeReadOnly();
        result.repeatedBytes_.MakeReadOnly();
        result.repeatedGroup_.MakeReadOnly();
        result.repeatedNestedMessage_.MakeReadOnly();
        result.repeatedForeignMessage_.MakeReadOnly();
        result.repeatedImportMessage_.MakeReadOnly();
        result.repeatedNestedEnum_.MakeReadOnly();
        result.repeatedForeignEnum_.MakeReadOnly();
        result.repeatedImportEnum_.MakeReadOnly();
        result.repeatedStringPiece_.MakeReadOnly();
        result.repeatedCord_.MakeReadOnly();
        TestAllTypes returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestAllTypes) {
          return MergeFrom((TestAllTypes) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestAllTypes other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance) return this;
        if (other.HasOptionalInt32) {
          OptionalInt32 = other.OptionalInt32;
        }
        if (other.HasOptionalInt64) {
          OptionalInt64 = other.OptionalInt64;
        }
        if (other.HasOptionalUint32) {
          OptionalUint32 = other.OptionalUint32;
        }
        if (other.HasOptionalUint64) {
          OptionalUint64 = other.OptionalUint64;
        }
        if (other.HasOptionalSint32) {
          OptionalSint32 = other.OptionalSint32;
        }
        if (other.HasOptionalSint64) {
          OptionalSint64 = other.OptionalSint64;
        }
        if (other.HasOptionalFixed32) {
          OptionalFixed32 = other.OptionalFixed32;
        }
        if (other.HasOptionalFixed64) {
          OptionalFixed64 = other.OptionalFixed64;
        }
        if (other.HasOptionalSfixed32) {
          OptionalSfixed32 = other.OptionalSfixed32;
        }
        if (other.HasOptionalSfixed64) {
          OptionalSfixed64 = other.OptionalSfixed64;
        }
        if (other.HasOptionalFloat) {
          OptionalFloat = other.OptionalFloat;
        }
        if (other.HasOptionalDouble) {
          OptionalDouble = other.OptionalDouble;
        }
        if (other.HasOptionalBool) {
          OptionalBool = other.OptionalBool;
        }
        if (other.HasOptionalString) {
          OptionalString = other.OptionalString;
        }
        if (other.HasOptionalBytes) {
          OptionalBytes = other.OptionalBytes;
        }
        if (other.HasOptionalGroup) {
          MergeOptionalGroup(other.OptionalGroup);
        }
        if (other.HasOptionalNestedMessage) {
          MergeOptionalNestedMessage(other.OptionalNestedMessage);
        }
        if (other.HasOptionalForeignMessage) {
          MergeOptionalForeignMessage(other.OptionalForeignMessage);
        }
        if (other.HasOptionalImportMessage) {
          MergeOptionalImportMessage(other.OptionalImportMessage);
        }
        if (other.HasOptionalNestedEnum) {
          OptionalNestedEnum = other.OptionalNestedEnum;
        }
        if (other.HasOptionalForeignEnum) {
          OptionalForeignEnum = other.OptionalForeignEnum;
        }
        if (other.HasOptionalImportEnum) {
          OptionalImportEnum = other.OptionalImportEnum;
        }
        if (other.HasOptionalStringPiece) {
          OptionalStringPiece = other.OptionalStringPiece;
        }
        if (other.HasOptionalCord) {
          OptionalCord = other.OptionalCord;
        }
        if (other.repeatedInt32_.Count != 0) {
          base.AddRange(other.repeatedInt32_, result.repeatedInt32_);
        }
        if (other.repeatedInt64_.Count != 0) {
          base.AddRange(other.repeatedInt64_, result.repeatedInt64_);
        }
        if (other.repeatedUint32_.Count != 0) {
          base.AddRange(other.repeatedUint32_, result.repeatedUint32_);
        }
        if (other.repeatedUint64_.Count != 0) {
          base.AddRange(other.repeatedUint64_, result.repeatedUint64_);
        }
        if (other.repeatedSint32_.Count != 0) {
          base.AddRange(other.repeatedSint32_, result.repeatedSint32_);
        }
        if (other.repeatedSint64_.Count != 0) {
          base.AddRange(other.repeatedSint64_, result.repeatedSint64_);
        }
        if (other.repeatedFixed32_.Count != 0) {
          base.AddRange(other.repeatedFixed32_, result.repeatedFixed32_);
        }
        if (other.repeatedFixed64_.Count != 0) {
          base.AddRange(other.repeatedFixed64_, result.repeatedFixed64_);
        }
        if (other.repeatedSfixed32_.Count != 0) {
          base.AddRange(other.repeatedSfixed32_, result.repeatedSfixed32_);
        }
        if (other.repeatedSfixed64_.Count != 0) {
          base.AddRange(other.repeatedSfixed64_, result.repeatedSfixed64_);
        }
        if (other.repeatedFloat_.Count != 0) {
          base.AddRange(other.repeatedFloat_, result.repeatedFloat_);
        }
        if (other.repeatedDouble_.Count != 0) {
          base.AddRange(other.repeatedDouble_, result.repeatedDouble_);
        }
        if (other.repeatedBool_.Count != 0) {
          base.AddRange(other.repeatedBool_, result.repeatedBool_);
        }
        if (other.repeatedString_.Count != 0) {
          base.AddRange(other.repeatedString_, result.repeatedString_);
        }
        if (other.repeatedBytes_.Count != 0) {
          base.AddRange(other.repeatedBytes_, result.repeatedBytes_);
        }
        if (other.repeatedGroup_.Count != 0) {
          base.AddRange(other.repeatedGroup_, result.repeatedGroup_);
        }
        if (other.repeatedNestedMessage_.Count != 0) {
          base.AddRange(other.repeatedNestedMessage_, result.repeatedNestedMessage_);
        }
        if (other.repeatedForeignMessage_.Count != 0) {
          base.AddRange(other.repeatedForeignMessage_, result.repeatedForeignMessage_);
        }
        if (other.repeatedImportMessage_.Count != 0) {
          base.AddRange(other.repeatedImportMessage_, result.repeatedImportMessage_);
        }
        if (other.repeatedNestedEnum_.Count != 0) {
          base.AddRange(other.repeatedNestedEnum_, result.repeatedNestedEnum_);
        }
        if (other.repeatedForeignEnum_.Count != 0) {
          base.AddRange(other.repeatedForeignEnum_, result.repeatedForeignEnum_);
        }
        if (other.repeatedImportEnum_.Count != 0) {
          base.AddRange(other.repeatedImportEnum_, result.repeatedImportEnum_);
        }
        if (other.repeatedStringPiece_.Count != 0) {
          base.AddRange(other.repeatedStringPiece_, result.repeatedStringPiece_);
        }
        if (other.repeatedCord_.Count != 0) {
          base.AddRange(other.repeatedCord_, result.repeatedCord_);
        }
        if (other.HasDefaultInt32) {
          DefaultInt32 = other.DefaultInt32;
        }
        if (other.HasDefaultInt64) {
          DefaultInt64 = other.DefaultInt64;
        }
        if (other.HasDefaultUint32) {
          DefaultUint32 = other.DefaultUint32;
        }
        if (other.HasDefaultUint64) {
          DefaultUint64 = other.DefaultUint64;
        }
        if (other.HasDefaultSint32) {
          DefaultSint32 = other.DefaultSint32;
        }
        if (other.HasDefaultSint64) {
          DefaultSint64 = other.DefaultSint64;
        }
        if (other.HasDefaultFixed32) {
          DefaultFixed32 = other.DefaultFixed32;
        }
        if (other.HasDefaultFixed64) {
          DefaultFixed64 = other.DefaultFixed64;
        }
        if (other.HasDefaultSfixed32) {
          DefaultSfixed32 = other.DefaultSfixed32;
        }
        if (other.HasDefaultSfixed64) {
          DefaultSfixed64 = other.DefaultSfixed64;
        }
        if (other.HasDefaultFloat) {
          DefaultFloat = other.DefaultFloat;
        }
        if (other.HasDefaultDouble) {
          DefaultDouble = other.DefaultDouble;
        }
        if (other.HasDefaultBool) {
          DefaultBool = other.DefaultBool;
        }
        if (other.HasDefaultString) {
          DefaultString = other.DefaultString;
        }
        if (other.HasDefaultBytes) {
          DefaultBytes = other.DefaultBytes;
        }
        if (other.HasDefaultNestedEnum) {
          DefaultNestedEnum = other.DefaultNestedEnum;
        }
        if (other.HasDefaultForeignEnum) {
          DefaultForeignEnum = other.DefaultForeignEnum;
        }
        if (other.HasDefaultImportEnum) {
          DefaultImportEnum = other.DefaultImportEnum;
        }
        if (other.HasDefaultStringPiece) {
          DefaultStringPiece = other.DefaultStringPiece;
        }
        if (other.HasDefaultCord) {
          DefaultCord = other.DefaultCord;
        }
        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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
            case 8: {
              result.hasOptionalInt32 |= input.ReadInt32(ref result.optionalInt32_);
              break;
            }
            case 16: {
              result.hasOptionalInt64 |= input.ReadInt64(ref result.optionalInt64_);
              break;
            }
            case 24: {
              result.hasOptionalUint32 |= input.ReadUInt32(ref result.optionalUint32_);
              break;
            }
            case 32: {
              result.hasOptionalUint64 |= input.ReadUInt64(ref result.optionalUint64_);
              break;
            }
            case 40: {
              result.hasOptionalSint32 |= input.ReadSInt32(ref result.optionalSint32_);
              break;
            }
            case 48: {
              result.hasOptionalSint64 |= input.ReadSInt64(ref result.optionalSint64_);
              break;
            }
            case 61: {
              result.hasOptionalFixed32 |= input.ReadFixed32(ref result.optionalFixed32_);
              break;
            }
            case 65: {
              result.hasOptionalFixed64 |= input.ReadFixed64(ref result.optionalFixed64_);
              break;
            }
            case 77: {
              result.hasOptionalSfixed32 |= input.ReadSFixed32(ref result.optionalSfixed32_);
              break;
            }
            case 81: {
              result.hasOptionalSfixed64 |= input.ReadSFixed64(ref result.optionalSfixed64_);
              break;
            }
            case 93: {
              result.hasOptionalFloat |= input.ReadFloat(ref result.optionalFloat_);
              break;
            }
            case 97: {
              result.hasOptionalDouble |= input.ReadDouble(ref result.optionalDouble_);
              break;
            }
            case 104: {
              result.hasOptionalBool |= input.ReadBool(ref result.optionalBool_);
              break;
            }
            case 114: {
              result.hasOptionalString |= input.ReadString(ref result.optionalString_);
              break;
            }
            case 122: {
              result.hasOptionalBytes |= input.ReadBytes(ref result.optionalBytes_);
              break;
            }
            case 131: {
              global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.OptionalGroup.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.OptionalGroup.CreateBuilder();
              if (HasOptionalGroup) {
                subBuilder.MergeFrom(OptionalGroup);
              }
              input.ReadGroup(16, subBuilder, extensionRegistry);
              OptionalGroup = subBuilder.BuildPartial();
              break;
            }
            case 146: {
              global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.CreateBuilder();
              if (HasOptionalNestedMessage) {
                subBuilder.MergeFrom(OptionalNestedMessage);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              OptionalNestedMessage = subBuilder.BuildPartial();
              break;
            }
            case 154: {
              global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.ForeignMessage.CreateBuilder();
              if (HasOptionalForeignMessage) {
                subBuilder.MergeFrom(OptionalForeignMessage);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              OptionalForeignMessage = subBuilder.BuildPartial();
              break;
            }
            case 162: {
              global::Google.ProtocolBuffers.TestProtos.ImportMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.ImportMessage.CreateBuilder();
              if (HasOptionalImportMessage) {
                subBuilder.MergeFrom(OptionalImportMessage);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              OptionalImportMessage = subBuilder.BuildPartial();
              break;
            }
            case 168: {
              object unknown;
              if(input.ReadEnum(ref result.optionalNestedEnum_, out unknown)) {
                result.hasOptionalNestedEnum = true;
              } else if(unknown is int) {
                if (unknownFields == null) {
                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                }
                unknownFields.MergeVarintField(21, (ulong)(int)unknown);
              }
              break;
            }
            case 176: {
              object unknown;
              if(input.ReadEnum(ref result.optionalForeignEnum_, out unknown)) {
                result.hasOptionalForeignEnum = true;
              } else if(unknown is int) {
                if (unknownFields == null) {
                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                }
                unknownFields.MergeVarintField(22, (ulong)(int)unknown);
              }
              break;
            }
            case 184: {
              object unknown;
              if(input.ReadEnum(ref result.optionalImportEnum_, out unknown)) {
                result.hasOptionalImportEnum = true;
              } else if(unknown is int) {
                if (unknownFields == null) {
                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                }
                unknownFields.MergeVarintField(23, (ulong)(int)unknown);
              }
              break;
            }
            case 194: {
              result.hasOptionalStringPiece |= input.ReadString(ref result.optionalStringPiece_);
              break;
            }
            case 202: {
              result.hasOptionalCord |= input.ReadString(ref result.optionalCord_);
              break;
            }
            case 248: {
              input.ReadPrimitiveArray(pbd::FieldType.Int32, tag, field_name, result.repeatedInt32_);
              break;
            }
            case 256: {
              input.ReadPrimitiveArray(pbd::FieldType.Int64, tag, field_name, result.repeatedInt64_);
              break;
            }
            case 264: {
              input.ReadPrimitiveArray(pbd::FieldType.UInt32, tag, field_name, result.repeatedUint32_);
              break;
            }
            case 272: {
              input.ReadPrimitiveArray(pbd::FieldType.UInt64, tag, field_name, result.repeatedUint64_);
              break;
            }
            case 280: {
              input.ReadPrimitiveArray(pbd::FieldType.SInt32, tag, field_name, result.repeatedSint32_);
              break;
            }
            case 288: {
              input.ReadPrimitiveArray(pbd::FieldType.SInt64, tag, field_name, result.repeatedSint64_);
              break;
            }
            case 301: {
              input.ReadPrimitiveArray(pbd::FieldType.Fixed32, tag, field_name, result.repeatedFixed32_);
              break;
            }
            case 305: {
              input.ReadPrimitiveArray(pbd::FieldType.Fixed64, tag, field_name, result.repeatedFixed64_);
              break;
            }
            case 317: {
              input.ReadPrimitiveArray(pbd::FieldType.SFixed32, tag, field_name, result.repeatedSfixed32_);
              break;
            }
            case 321: {
              input.ReadPrimitiveArray(pbd::FieldType.SFixed64, tag, field_name, result.repeatedSfixed64_);
              break;
            }
            case 333: {
              input.ReadPrimitiveArray(pbd::FieldType.Float, tag, field_name, result.repeatedFloat_);
              break;
            }
            case 337: {
              input.ReadPrimitiveArray(pbd::FieldType.Double, tag, field_name, result.repeatedDouble_);
              break;
            }
            case 344: {
              input.ReadPrimitiveArray(pbd::FieldType.Bool, tag, field_name, result.repeatedBool_);
              break;
            }
            case 354: {
              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedString_);
              break;
            }
            case 362: {
              input.ReadPrimitiveArray(pbd::FieldType.Bytes, tag, field_name, result.repeatedBytes_);
              break;
            }
            case 371: {
              input.ReadGroupArray(tag, field_name, result.repeatedGroup_, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup.DefaultInstance, extensionRegistry);
              break;
            }
            case 386: {
              input.ReadMessageArray(tag, field_name, result.repeatedNestedMessage_, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.DefaultInstance, extensionRegistry);
              break;
            }
            case 394: {
              input.ReadMessageArray(tag, field_name, result.repeatedForeignMessage_, global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance, extensionRegistry);
              break;
            }
            case 402: {
              input.ReadMessageArray(tag, field_name, result.repeatedImportMessage_, global::Google.ProtocolBuffers.TestProtos.ImportMessage.DefaultInstance, extensionRegistry);
              break;
            }
            case 408: {
              scg::ICollection<object> unknownItems;
              input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum>(tag, field_name, result.repeatedNestedEnum_, out unknownItems);
              if (unknownItems != null) {
                if (unknownFields == null) {
                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                }
                foreach (object rawValue in unknownItems)
                  if (rawValue is int)
                    unknownFields.MergeVarintField(51, (ulong)(int)rawValue);
              }
              break;
            }
            case 416: {
              scg::ICollection<object> unknownItems;
              input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>(tag, field_name, result.repeatedForeignEnum_, out unknownItems);
              if (unknownItems != null) {
                if (unknownFields == null) {
                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                }
                foreach (object rawValue in unknownItems)
                  if (rawValue is int)
                    unknownFields.MergeVarintField(52, (ulong)(int)rawValue);
              }
              break;
            }
            case 424: {
              scg::ICollection<object> unknownItems;
              input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.ImportEnum>(tag, field_name, result.repeatedImportEnum_, out unknownItems);
              if (unknownItems != null) {
                if (unknownFields == null) {
                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                }
                foreach (object rawValue in unknownItems)
                  if (rawValue is int)
                    unknownFields.MergeVarintField(53, (ulong)(int)rawValue);
              }
              break;
            }
            case 434: {
              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedStringPiece_);
              break;
            }
            case 442: {
              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedCord_);
              break;
            }
            case 488: {
              result.hasDefaultInt32 |= input.ReadInt32(ref result.defaultInt32_);
              break;
            }
            case 496: {
              result.hasDefaultInt64 |= input.ReadInt64(ref result.defaultInt64_);
              break;
            }
            case 504: {
              result.hasDefaultUint32 |= input.ReadUInt32(ref result.defaultUint32_);
              break;
            }
            case 512: {
              result.hasDefaultUint64 |= input.ReadUInt64(ref result.defaultUint64_);
              break;
            }
            case 520: {
              result.hasDefaultSint32 |= input.ReadSInt32(ref result.defaultSint32_);
              break;
            }
            case 528: {
              result.hasDefaultSint64 |= input.ReadSInt64(ref result.defaultSint64_);
              break;
            }
            case 541: {
              result.hasDefaultFixed32 |= input.ReadFixed32(ref result.defaultFixed32_);
              break;
            }
            case 545: {
              result.hasDefaultFixed64 |= input.ReadFixed64(ref result.defaultFixed64_);
              break;
            }
            case 557: {
              result.hasDefaultSfixed32 |= input.ReadSFixed32(ref result.defaultSfixed32_);
              break;
            }
            case 561: {
              result.hasDefaultSfixed64 |= input.ReadSFixed64(ref result.defaultSfixed64_);
              break;
            }
            case 573: {
              result.hasDefaultFloat |= input.ReadFloat(ref result.defaultFloat_);
              break;
            }
            case 577: {
              result.hasDefaultDouble |= input.ReadDouble(ref result.defaultDouble_);
              break;
            }
            case 584: {
              result.hasDefaultBool |= input.ReadBool(ref result.defaultBool_);
              break;
            }
            case 594: {
              result.hasDefaultString |= input.ReadString(ref result.defaultString_);
              break;
            }
            case 602: {
              result.hasDefaultBytes |= input.ReadBytes(ref result.defaultBytes_);
              break;
            }
            case 648: {
              object unknown;
              if(input.ReadEnum(ref result.defaultNestedEnum_, out unknown)) {
                result.hasDefaultNestedEnum = true;
              } else if(unknown is int) {
                if (unknownFields == null) {
                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                }
                unknownFields.MergeVarintField(81, (ulong)(int)unknown);
              }
              break;
            }
            case 656: {
              object unknown;
              if(input.ReadEnum(ref result.defaultForeignEnum_, out unknown)) {
                result.hasDefaultForeignEnum = true;
              } else if(unknown is int) {
                if (unknownFields == null) {
                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                }
                unknownFields.MergeVarintField(82, (ulong)(int)unknown);
              }
              break;
            }
            case 664: {
              object unknown;
              if(input.ReadEnum(ref result.defaultImportEnum_, out unknown)) {
                result.hasDefaultImportEnum = true;
              } else if(unknown is int) {
                if (unknownFields == null) {
                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                }
                unknownFields.MergeVarintField(83, (ulong)(int)unknown);
              }
              break;
            }
            case 674: {
              result.hasDefaultStringPiece |= input.ReadString(ref result.defaultStringPiece_);
              break;
            }
            case 682: {
              result.hasDefaultCord |= input.ReadString(ref result.defaultCord_);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      public bool HasOptionalInt32 {
        get { return result.HasOptionalInt32; }
      }
      public int OptionalInt32 {
        get { return result.OptionalInt32; }
        set { SetOptionalInt32(value); }
      }
      public Builder SetOptionalInt32(int value) {
        result.hasOptionalInt32 = true;
        result.optionalInt32_ = value;
        return this;
      }
      public Builder ClearOptionalInt32() {
        result.hasOptionalInt32 = false;
        result.optionalInt32_ = 0;
        return this;
      }
      
      public bool HasOptionalInt64 {
        get { return result.HasOptionalInt64; }
      }
      public long OptionalInt64 {
        get { return result.OptionalInt64; }
        set { SetOptionalInt64(value); }
      }
      public Builder SetOptionalInt64(long value) {
        result.hasOptionalInt64 = true;
        result.optionalInt64_ = value;
        return this;
      }
      public Builder ClearOptionalInt64() {
        result.hasOptionalInt64 = false;
        result.optionalInt64_ = 0L;
        return this;
      }
      
      public bool HasOptionalUint32 {
        get { return result.HasOptionalUint32; }
      }
      [global::System.CLSCompliant(false)]
      public uint OptionalUint32 {
        get { return result.OptionalUint32; }
        set { SetOptionalUint32(value); }
      }
      [global::System.CLSCompliant(false)]
      public Builder SetOptionalUint32(uint value) {
        result.hasOptionalUint32 = true;
        result.optionalUint32_ = value;
        return this;
      }
      public Builder ClearOptionalUint32() {
        result.hasOptionalUint32 = false;
        result.optionalUint32_ = 0;
        return this;
      }
      
      public bool HasOptionalUint64 {
        get { return result.HasOptionalUint64; }
      }
      [global::System.CLSCompliant(false)]
      public ulong OptionalUint64 {
        get { return result.OptionalUint64; }
        set { SetOptionalUint64(value); }
      }
      [global::System.CLSCompliant(false)]
      public Builder SetOptionalUint64(ulong value) {
        result.hasOptionalUint64 = true;
        result.optionalUint64_ = value;
        return this;
      }
      public Builder ClearOptionalUint64() {
        result.hasOptionalUint64 = false;
        result.optionalUint64_ = 0UL;
        return this;
      }
      
      public bool HasOptionalSint32 {
        get { return result.HasOptionalSint32; }
      }
      public int OptionalSint32 {
        get { return result.OptionalSint32; }
        set { SetOptionalSint32(value); }
      }
      public Builder SetOptionalSint32(int value) {
        result.hasOptionalSint32 = true;
        result.optionalSint32_ = value;
        return this;
      }
      public Builder ClearOptionalSint32() {
        result.hasOptionalSint32 = false;
        result.optionalSint32_ = 0;
        return this;
      }
      
      public bool HasOptionalSint64 {
        get { return result.HasOptionalSint64; }
      }
      public long OptionalSint64 {
        get { return result.OptionalSint64; }
        set { SetOptionalSint64(value); }
      }
      public Builder SetOptionalSint64(long value) {
        result.hasOptionalSint64 = true;
        result.optionalSint64_ = value;
        return this;
      }
      public Builder ClearOptionalSint64() {
        result.hasOptionalSint64 = false;
        result.optionalSint64_ = 0;
        return this;
      }
      
      public bool HasOptionalFixed32 {
        get { return result.HasOptionalFixed32; }
      }
      [global::System.CLSCompliant(false)]
      public uint OptionalFixed32 {
        get { return result.OptionalFixed32; }
        set { SetOptionalFixed32(value); }
      }
      [global::System.CLSCompliant(false)]
      public Builder SetOptionalFixed32(uint value) {
        result.hasOptionalFixed32 = true;
        result.optionalFixed32_ = value;
        return this;
      }
      public Builder ClearOptionalFixed32() {
        result.hasOptionalFixed32 = false;
        result.optionalFixed32_ = 0;
        return this;
      }
      
      public bool HasOptionalFixed64 {
        get { return result.HasOptionalFixed64; }
      }
      [global::System.CLSCompliant(false)]
      public ulong OptionalFixed64 {
        get { return result.OptionalFixed64; }
        set { SetOptionalFixed64(value); }
      }
      [global::System.CLSCompliant(false)]
      public Builder SetOptionalFixed64(ulong value) {
        result.hasOptionalFixed64 = true;
        result.optionalFixed64_ = value;
        return this;
      }
      public Builder ClearOptionalFixed64() {
        result.hasOptionalFixed64 = false;
        result.optionalFixed64_ = 0;
        return this;
      }
      
      public bool HasOptionalSfixed32 {
        get { return result.HasOptionalSfixed32; }
      }
      public int OptionalSfixed32 {
        get { return result.OptionalSfixed32; }
        set { SetOptionalSfixed32(value); }
      }
      public Builder SetOptionalSfixed32(int value) {
        result.hasOptionalSfixed32 = true;
        result.optionalSfixed32_ = value;
        return this;
      }
      public Builder ClearOptionalSfixed32() {
        result.hasOptionalSfixed32 = false;
        result.optionalSfixed32_ = 0;
        return this;
      }
      
      public bool HasOptionalSfixed64 {
        get { return result.HasOptionalSfixed64; }
      }
      public long OptionalSfixed64 {
        get { return result.OptionalSfixed64; }
        set { SetOptionalSfixed64(value); }
      }
      public Builder SetOptionalSfixed64(long value) {
        result.hasOptionalSfixed64 = true;
        result.optionalSfixed64_ = value;
        return this;
      }
      public Builder ClearOptionalSfixed64() {
        result.hasOptionalSfixed64 = false;
        result.optionalSfixed64_ = 0;
        return this;
      }
      
      public bool HasOptionalFloat {
        get { return result.HasOptionalFloat; }
      }
      public float OptionalFloat {
        get { return result.OptionalFloat; }
        set { SetOptionalFloat(value); }
      }
      public Builder SetOptionalFloat(float value) {
        result.hasOptionalFloat = true;
        result.optionalFloat_ = value;
        return this;
      }
      public Builder ClearOptionalFloat() {
        result.hasOptionalFloat = false;
        result.optionalFloat_ = 0F;
        return this;
      }
      
      public bool HasOptionalDouble {
        get { return result.HasOptionalDouble; }
      }
      public double OptionalDouble {
        get { return result.OptionalDouble; }
        set { SetOptionalDouble(value); }
      }
      public Builder SetOptionalDouble(double value) {
        result.hasOptionalDouble = true;
        result.optionalDouble_ = value;
        return this;
      }
      public Builder ClearOptionalDouble() {
        result.hasOptionalDouble = false;
        result.optionalDouble_ = 0D;
        return this;
      }
      
      public bool HasOptionalBool {
        get { return result.HasOptionalBool; }
      }
      public bool OptionalBool {
        get { return result.OptionalBool; }
        set { SetOptionalBool(value); }
      }
      public Builder SetOptionalBool(bool value) {
        result.hasOptionalBool = true;
        result.optionalBool_ = value;
        return this;
      }
      public Builder ClearOptionalBool() {
        result.hasOptionalBool = false;
        result.optionalBool_ = false;
        return this;
      }
      
      public bool HasOptionalString {
        get { return result.HasOptionalString; }
      }
      public string OptionalString {
        get { return result.OptionalString; }
        set { SetOptionalString(value); }
      }
      public Builder SetOptionalString(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasOptionalString = true;
        result.optionalString_ = value;
        return this;
      }
      public Builder ClearOptionalString() {
        result.hasOptionalString = false;
        result.optionalString_ = "";
        return this;
      }
      
      public bool HasOptionalBytes {
        get { return result.HasOptionalBytes; }
      }
      public pb::ByteString OptionalBytes {
        get { return result.OptionalBytes; }
        set { SetOptionalBytes(value); }
      }
      public Builder SetOptionalBytes(pb::ByteString value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasOptionalBytes = true;
        result.optionalBytes_ = value;
        return this;
      }
      public Builder ClearOptionalBytes() {
        result.hasOptionalBytes = false;
        result.optionalBytes_ = pb::ByteString.Empty;
        return this;
      }
      
      public bool HasOptionalGroup {
       get { return result.HasOptionalGroup; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.OptionalGroup OptionalGroup {
        get { return result.OptionalGroup; }
        set { SetOptionalGroup(value); }
      }
      public Builder SetOptionalGroup(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.OptionalGroup value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasOptionalGroup = true;
        result.optionalGroup_ = value;
        return this;
      }
      public Builder SetOptionalGroup(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.OptionalGroup.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.hasOptionalGroup = true;
        result.optionalGroup_ = builderForValue.Build();
        return this;
      }
      public Builder MergeOptionalGroup(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.OptionalGroup value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        if (result.HasOptionalGroup &&
            result.optionalGroup_ != global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.OptionalGroup.DefaultInstance) {
            result.optionalGroup_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.OptionalGroup.CreateBuilder(result.optionalGroup_).MergeFrom(value).BuildPartial();
        } else {
          result.optionalGroup_ = value;
        }
        result.hasOptionalGroup = true;
        return this;
      }
      public Builder ClearOptionalGroup() {
        result.hasOptionalGroup = false;
        result.optionalGroup_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.OptionalGroup.DefaultInstance;
        return this;
      }
      
      public bool HasOptionalNestedMessage {
       get { return result.HasOptionalNestedMessage; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage OptionalNestedMessage {
        get { return result.OptionalNestedMessage; }
        set { SetOptionalNestedMessage(value); }
      }
      public Builder SetOptionalNestedMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasOptionalNestedMessage = true;
        result.optionalNestedMessage_ = value;
        return this;
      }
      public Builder SetOptionalNestedMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.hasOptionalNestedMessage = true;
        result.optionalNestedMessage_ = builderForValue.Build();
        return this;
      }
      public Builder MergeOptionalNestedMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        if (result.HasOptionalNestedMessage &&
            result.optionalNestedMessage_ != global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.DefaultInstance) {
            result.optionalNestedMessage_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.CreateBuilder(result.optionalNestedMessage_).MergeFrom(value).BuildPartial();
        } else {
          result.optionalNestedMessage_ = value;
        }
        result.hasOptionalNestedMessage = true;
        return this;
      }
      public Builder ClearOptionalNestedMessage() {
        result.hasOptionalNestedMessage = false;
        result.optionalNestedMessage_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.DefaultInstance;
        return this;
      }
      
      public bool HasOptionalForeignMessage {
       get { return result.HasOptionalForeignMessage; }
      }
      public global::Google.ProtocolBuffers.TestProtos.ForeignMessage OptionalForeignMessage {
        get { return result.OptionalForeignMessage; }
        set { SetOptionalForeignMessage(value); }
      }
      public Builder SetOptionalForeignMessage(global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasOptionalForeignMessage = true;
        result.optionalForeignMessage_ = value;
        return this;
      }
      public Builder SetOptionalForeignMessage(global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.hasOptionalForeignMessage = true;
        result.optionalForeignMessage_ = builderForValue.Build();
        return this;
      }
      public Builder MergeOptionalForeignMessage(global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        if (result.HasOptionalForeignMessage &&
            result.optionalForeignMessage_ != global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance) {
            result.optionalForeignMessage_ = global::Google.ProtocolBuffers.TestProtos.ForeignMessage.CreateBuilder(result.optionalForeignMessage_).MergeFrom(value).BuildPartial();
        } else {
          result.optionalForeignMessage_ = value;
        }
        result.hasOptionalForeignMessage = true;
        return this;
      }
      public Builder ClearOptionalForeignMessage() {
        result.hasOptionalForeignMessage = false;
        result.optionalForeignMessage_ = global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance;
        return this;
      }
      
      public bool HasOptionalImportMessage {
       get { return result.HasOptionalImportMessage; }
      }
      public global::Google.ProtocolBuffers.TestProtos.ImportMessage OptionalImportMessage {
        get { return result.OptionalImportMessage; }
        set { SetOptionalImportMessage(value); }
      }
      public Builder SetOptionalImportMessage(global::Google.ProtocolBuffers.TestProtos.ImportMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasOptionalImportMessage = true;
        result.optionalImportMessage_ = value;
        return this;
      }
      public Builder SetOptionalImportMessage(global::Google.ProtocolBuffers.TestProtos.ImportMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.hasOptionalImportMessage = true;
        result.optionalImportMessage_ = builderForValue.Build();
        return this;
      }
      public Builder MergeOptionalImportMessage(global::Google.ProtocolBuffers.TestProtos.ImportMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        if (result.HasOptionalImportMessage &&
            result.optionalImportMessage_ != global::Google.ProtocolBuffers.TestProtos.ImportMessage.DefaultInstance) {
            result.optionalImportMessage_ = global::Google.ProtocolBuffers.TestProtos.ImportMessage.CreateBuilder(result.optionalImportMessage_).MergeFrom(value).BuildPartial();
        } else {
          result.optionalImportMessage_ = value;
        }
        result.hasOptionalImportMessage = true;
        return this;
      }
      public Builder ClearOptionalImportMessage() {
        result.hasOptionalImportMessage = false;
        result.optionalImportMessage_ = global::Google.ProtocolBuffers.TestProtos.ImportMessage.DefaultInstance;
        return this;
      }
      
      public bool HasOptionalNestedEnum {
       get { return result.HasOptionalNestedEnum; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum OptionalNestedEnum {
        get { return result.OptionalNestedEnum; }
        set { SetOptionalNestedEnum(value); }
      }
      public Builder SetOptionalNestedEnum(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum value) {
        result.hasOptionalNestedEnum = true;
        result.optionalNestedEnum_ = value;
        return this;
      }
      public Builder ClearOptionalNestedEnum() {
        result.hasOptionalNestedEnum = false;
        result.optionalNestedEnum_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum.FOO;
        return this;
      }
      
      public bool HasOptionalForeignEnum {
       get { return result.HasOptionalForeignEnum; }
      }
      public global::Google.ProtocolBuffers.TestProtos.ForeignEnum OptionalForeignEnum {
        get { return result.OptionalForeignEnum; }
        set { SetOptionalForeignEnum(value); }
      }
      public Builder SetOptionalForeignEnum(global::Google.ProtocolBuffers.TestProtos.ForeignEnum value) {
        result.hasOptionalForeignEnum = true;
        result.optionalForeignEnum_ = value;
        return this;
      }
      public Builder ClearOptionalForeignEnum() {
        result.hasOptionalForeignEnum = false;
        result.optionalForeignEnum_ = global::Google.ProtocolBuffers.TestProtos.ForeignEnum.FOREIGN_FOO;
        return this;
      }
      
      public bool HasOptionalImportEnum {
       get { return result.HasOptionalImportEnum; }
      }
      public global::Google.ProtocolBuffers.TestProtos.ImportEnum OptionalImportEnum {
        get { return result.OptionalImportEnum; }
        set { SetOptionalImportEnum(value); }
      }
      public Builder SetOptionalImportEnum(global::Google.ProtocolBuffers.TestProtos.ImportEnum value) {
        result.hasOptionalImportEnum = true;
        result.optionalImportEnum_ = value;
        return this;
      }
      public Builder ClearOptionalImportEnum() {
        result.hasOptionalImportEnum = false;
        result.optionalImportEnum_ = global::Google.ProtocolBuffers.TestProtos.ImportEnum.IMPORT_FOO;
        return this;
      }
      
      public bool HasOptionalStringPiece {
        get { return result.HasOptionalStringPiece; }
      }
      public string OptionalStringPiece {
        get { return result.OptionalStringPiece; }
        set { SetOptionalStringPiece(value); }
      }
      public Builder SetOptionalStringPiece(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasOptionalStringPiece = true;
        result.optionalStringPiece_ = value;
        return this;
      }
      public Builder ClearOptionalStringPiece() {
        result.hasOptionalStringPiece = false;
        result.optionalStringPiece_ = "";
        return this;
      }
      
      public bool HasOptionalCord {
        get { return result.HasOptionalCord; }
      }
      public string OptionalCord {
        get { return result.OptionalCord; }
        set { SetOptionalCord(value); }
      }
      public Builder SetOptionalCord(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasOptionalCord = true;
        result.optionalCord_ = value;
        return this;
      }
      public Builder ClearOptionalCord() {
        result.hasOptionalCord = false;
        result.optionalCord_ = "";
        return this;
      }
      
      public pbc::IPopsicleList<int> RepeatedInt32List {
        get { return result.repeatedInt32_; }
      }
      public int RepeatedInt32Count {
        get { return result.RepeatedInt32Count; }
      }
      public int GetRepeatedInt32(int index) {
        return result.GetRepeatedInt32(index);
      }
      public Builder SetRepeatedInt32(int index, int value) {
        result.repeatedInt32_[index] = value;
        return this;
      }
      public Builder AddRepeatedInt32(int value) {
        result.repeatedInt32_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedInt32(scg::IEnumerable<int> values) {
        base.AddRange(values, result.repeatedInt32_);
        return this;
      }
      public Builder ClearRepeatedInt32() {
        result.repeatedInt32_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<long> RepeatedInt64List {
        get { return result.repeatedInt64_; }
      }
      public int RepeatedInt64Count {
        get { return result.RepeatedInt64Count; }
      }
      public long GetRepeatedInt64(int index) {
        return result.GetRepeatedInt64(index);
      }
      public Builder SetRepeatedInt64(int index, long value) {
        result.repeatedInt64_[index] = value;
        return this;
      }
      public Builder AddRepeatedInt64(long value) {
        result.repeatedInt64_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedInt64(scg::IEnumerable<long> values) {
        base.AddRange(values, result.repeatedInt64_);
        return this;
      }
      public Builder ClearRepeatedInt64() {
        result.repeatedInt64_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<uint> RepeatedUint32List {
        get { return result.repeatedUint32_; }
      }
      public int RepeatedUint32Count {
        get { return result.RepeatedUint32Count; }
      }
      [global::System.CLSCompliant(false)]
      public uint GetRepeatedUint32(int index) {
        return result.GetRepeatedUint32(index);
      }
      [global::System.CLSCompliant(false)]
      public Builder SetRepeatedUint32(int index, uint value) {
        result.repeatedUint32_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRepeatedUint32(uint value) {
        result.repeatedUint32_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangeRepeatedUint32(scg::IEnumerable<uint> values) {
        base.AddRange(values, result.repeatedUint32_);
        return this;
      }
      public Builder ClearRepeatedUint32() {
        result.repeatedUint32_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<ulong> RepeatedUint64List {
        get { return result.repeatedUint64_; }
      }
      public int RepeatedUint64Count {
        get { return result.RepeatedUint64Count; }
      }
      [global::System.CLSCompliant(false)]
      public ulong GetRepeatedUint64(int index) {
        return result.GetRepeatedUint64(index);
      }
      [global::System.CLSCompliant(false)]
      public Builder SetRepeatedUint64(int index, ulong value) {
        result.repeatedUint64_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRepeatedUint64(ulong value) {
        result.repeatedUint64_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangeRepeatedUint64(scg::IEnumerable<ulong> values) {
        base.AddRange(values, result.repeatedUint64_);
        return this;
      }
      public Builder ClearRepeatedUint64() {
        result.repeatedUint64_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<int> RepeatedSint32List {
        get { return result.repeatedSint32_; }
      }
      public int RepeatedSint32Count {
        get { return result.RepeatedSint32Count; }
      }
      public int GetRepeatedSint32(int index) {
        return result.GetRepeatedSint32(index);
      }
      public Builder SetRepeatedSint32(int index, int value) {
        result.repeatedSint32_[index] = value;
        return this;
      }
      public Builder AddRepeatedSint32(int value) {
        result.repeatedSint32_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedSint32(scg::IEnumerable<int> values) {
        base.AddRange(values, result.repeatedSint32_);
        return this;
      }
      public Builder ClearRepeatedSint32() {
        result.repeatedSint32_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<long> RepeatedSint64List {
        get { return result.repeatedSint64_; }
      }
      public int RepeatedSint64Count {
        get { return result.RepeatedSint64Count; }
      }
      public long GetRepeatedSint64(int index) {
        return result.GetRepeatedSint64(index);
      }
      public Builder SetRepeatedSint64(int index, long value) {
        result.repeatedSint64_[index] = value;
        return this;
      }
      public Builder AddRepeatedSint64(long value) {
        result.repeatedSint64_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedSint64(scg::IEnumerable<long> values) {
        base.AddRange(values, result.repeatedSint64_);
        return this;
      }
      public Builder ClearRepeatedSint64() {
        result.repeatedSint64_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<uint> RepeatedFixed32List {
        get { return result.repeatedFixed32_; }
      }
      public int RepeatedFixed32Count {
        get { return result.RepeatedFixed32Count; }
      }
      [global::System.CLSCompliant(false)]
      public uint GetRepeatedFixed32(int index) {
        return result.GetRepeatedFixed32(index);
      }
      [global::System.CLSCompliant(false)]
      public Builder SetRepeatedFixed32(int index, uint value) {
        result.repeatedFixed32_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRepeatedFixed32(uint value) {
        result.repeatedFixed32_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangeRepeatedFixed32(scg::IEnumerable<uint> values) {
        base.AddRange(values, result.repeatedFixed32_);
        return this;
      }
      public Builder ClearRepeatedFixed32() {
        result.repeatedFixed32_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<ulong> RepeatedFixed64List {
        get { return result.repeatedFixed64_; }
      }
      public int RepeatedFixed64Count {
        get { return result.RepeatedFixed64Count; }
      }
      [global::System.CLSCompliant(false)]
      public ulong GetRepeatedFixed64(int index) {
        return result.GetRepeatedFixed64(index);
      }
      [global::System.CLSCompliant(false)]
      public Builder SetRepeatedFixed64(int index, ulong value) {
        result.repeatedFixed64_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRepeatedFixed64(ulong value) {
        result.repeatedFixed64_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangeRepeatedFixed64(scg::IEnumerable<ulong> values) {
        base.AddRange(values, result.repeatedFixed64_);
        return this;
      }
      public Builder ClearRepeatedFixed64() {
        result.repeatedFixed64_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<int> RepeatedSfixed32List {
        get { return result.repeatedSfixed32_; }
      }
      public int RepeatedSfixed32Count {
        get { return result.RepeatedSfixed32Count; }
      }
      public int GetRepeatedSfixed32(int index) {
        return result.GetRepeatedSfixed32(index);
      }
      public Builder SetRepeatedSfixed32(int index, int value) {
        result.repeatedSfixed32_[index] = value;
        return this;
      }
      public Builder AddRepeatedSfixed32(int value) {
        result.repeatedSfixed32_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedSfixed32(scg::IEnumerable<int> values) {
        base.AddRange(values, result.repeatedSfixed32_);
        return this;
      }
      public Builder ClearRepeatedSfixed32() {
        result.repeatedSfixed32_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<long> RepeatedSfixed64List {
        get { return result.repeatedSfixed64_; }
      }
      public int RepeatedSfixed64Count {
        get { return result.RepeatedSfixed64Count; }
      }
      public long GetRepeatedSfixed64(int index) {
        return result.GetRepeatedSfixed64(index);
      }
      public Builder SetRepeatedSfixed64(int index, long value) {
        result.repeatedSfixed64_[index] = value;
        return this;
      }
      public Builder AddRepeatedSfixed64(long value) {
        result.repeatedSfixed64_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedSfixed64(scg::IEnumerable<long> values) {
        base.AddRange(values, result.repeatedSfixed64_);
        return this;
      }
      public Builder ClearRepeatedSfixed64() {
        result.repeatedSfixed64_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<float> RepeatedFloatList {
        get { return result.repeatedFloat_; }
      }
      public int RepeatedFloatCount {
        get { return result.RepeatedFloatCount; }
      }
      public float GetRepeatedFloat(int index) {
        return result.GetRepeatedFloat(index);
      }
      public Builder SetRepeatedFloat(int index, float value) {
        result.repeatedFloat_[index] = value;
        return this;
      }
      public Builder AddRepeatedFloat(float value) {
        result.repeatedFloat_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedFloat(scg::IEnumerable<float> values) {
        base.AddRange(values, result.repeatedFloat_);
        return this;
      }
      public Builder ClearRepeatedFloat() {
        result.repeatedFloat_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<double> RepeatedDoubleList {
        get { return result.repeatedDouble_; }
      }
      public int RepeatedDoubleCount {
        get { return result.RepeatedDoubleCount; }
      }
      public double GetRepeatedDouble(int index) {
        return result.GetRepeatedDouble(index);
      }
      public Builder SetRepeatedDouble(int index, double value) {
        result.repeatedDouble_[index] = value;
        return this;
      }
      public Builder AddRepeatedDouble(double value) {
        result.repeatedDouble_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedDouble(scg::IEnumerable<double> values) {
        base.AddRange(values, result.repeatedDouble_);
        return this;
      }
      public Builder ClearRepeatedDouble() {
        result.repeatedDouble_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<bool> RepeatedBoolList {
        get { return result.repeatedBool_; }
      }
      public int RepeatedBoolCount {
        get { return result.RepeatedBoolCount; }
      }
      public bool GetRepeatedBool(int index) {
        return result.GetRepeatedBool(index);
      }
      public Builder SetRepeatedBool(int index, bool value) {
        result.repeatedBool_[index] = value;
        return this;
      }
      public Builder AddRepeatedBool(bool value) {
        result.repeatedBool_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedBool(scg::IEnumerable<bool> values) {
        base.AddRange(values, result.repeatedBool_);
        return this;
      }
      public Builder ClearRepeatedBool() {
        result.repeatedBool_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<string> RepeatedStringList {
        get { return result.repeatedString_; }
      }
      public int RepeatedStringCount {
        get { return result.RepeatedStringCount; }
      }
      public string GetRepeatedString(int index) {
        return result.GetRepeatedString(index);
      }
      public Builder SetRepeatedString(int index, string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedString_[index] = value;
        return this;
      }
      public Builder AddRepeatedString(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedString_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedString(scg::IEnumerable<string> values) {
        base.AddRange(values, result.repeatedString_);
        return this;
      }
      public Builder ClearRepeatedString() {
        result.repeatedString_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<pb::ByteString> RepeatedBytesList {
        get { return result.repeatedBytes_; }
      }
      public int RepeatedBytesCount {
        get { return result.RepeatedBytesCount; }
      }
      public pb::ByteString GetRepeatedBytes(int index) {
        return result.GetRepeatedBytes(index);
      }
      public Builder SetRepeatedBytes(int index, pb::ByteString value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedBytes_[index] = value;
        return this;
      }
      public Builder AddRepeatedBytes(pb::ByteString value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedBytes_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedBytes(scg::IEnumerable<pb::ByteString> values) {
        base.AddRange(values, result.repeatedBytes_);
        return this;
      }
      public Builder ClearRepeatedBytes() {
        result.repeatedBytes_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup> RepeatedGroupList {
        get { return result.repeatedGroup_; }
      }
      public int RepeatedGroupCount {
        get { return result.RepeatedGroupCount; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup GetRepeatedGroup(int index) {
        return result.GetRepeatedGroup(index);
      }
      public Builder SetRepeatedGroup(int index, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedGroup_[index] = value;
        return this;
      }
      public Builder SetRepeatedGroup(int index, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.repeatedGroup_[index] = builderForValue.Build();
        return this;
      }
      public Builder AddRepeatedGroup(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedGroup_.Add(value);
        return this;
      }
      public Builder AddRepeatedGroup(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.repeatedGroup_.Add(builderForValue.Build());
        return this;
      }
      public Builder AddRangeRepeatedGroup(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup> values) {
        base.AddRange(values, result.repeatedGroup_);
        return this;
      }
      public Builder ClearRepeatedGroup() {
        result.repeatedGroup_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage> RepeatedNestedMessageList {
        get { return result.repeatedNestedMessage_; }
      }
      public int RepeatedNestedMessageCount {
        get { return result.RepeatedNestedMessageCount; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage GetRepeatedNestedMessage(int index) {
        return result.GetRepeatedNestedMessage(index);
      }
      public Builder SetRepeatedNestedMessage(int index, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedNestedMessage_[index] = value;
        return this;
      }
      public Builder SetRepeatedNestedMessage(int index, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.repeatedNestedMessage_[index] = builderForValue.Build();
        return this;
      }
      public Builder AddRepeatedNestedMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedNestedMessage_.Add(value);
        return this;
      }
      public Builder AddRepeatedNestedMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.repeatedNestedMessage_.Add(builderForValue.Build());
        return this;
      }
      public Builder AddRangeRepeatedNestedMessage(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage> values) {
        base.AddRange(values, result.repeatedNestedMessage_);
        return this;
      }
      public Builder ClearRepeatedNestedMessage() {
        result.repeatedNestedMessage_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignMessage> RepeatedForeignMessageList {
        get { return result.repeatedForeignMessage_; }
      }
      public int RepeatedForeignMessageCount {
        get { return result.RepeatedForeignMessageCount; }
      }
      public global::Google.ProtocolBuffers.TestProtos.ForeignMessage GetRepeatedForeignMessage(int index) {
        return result.GetRepeatedForeignMessage(index);
      }
      public Builder SetRepeatedForeignMessage(int index, global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedForeignMessage_[index] = value;
        return this;
      }
      public Builder SetRepeatedForeignMessage(int index, global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.repeatedForeignMessage_[index] = builderForValue.Build();
        return this;
      }
      public Builder AddRepeatedForeignMessage(global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedForeignMessage_.Add(value);
        return this;
      }
      public Builder AddRepeatedForeignMessage(global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.repeatedForeignMessage_.Add(builderForValue.Build());
        return this;
      }
      public Builder AddRangeRepeatedForeignMessage(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.ForeignMessage> values) {
        base.AddRange(values, result.repeatedForeignMessage_);
        return this;
      }
      public Builder ClearRepeatedForeignMessage() {
        result.repeatedForeignMessage_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.ImportMessage> RepeatedImportMessageList {
        get { return result.repeatedImportMessage_; }
      }
      public int RepeatedImportMessageCount {
        get { return result.RepeatedImportMessageCount; }
      }
      public global::Google.ProtocolBuffers.TestProtos.ImportMessage GetRepeatedImportMessage(int index) {
        return result.GetRepeatedImportMessage(index);
      }
      public Builder SetRepeatedImportMessage(int index, global::Google.ProtocolBuffers.TestProtos.ImportMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedImportMessage_[index] = value;
        return this;
      }
      public Builder SetRepeatedImportMessage(int index, global::Google.ProtocolBuffers.TestProtos.ImportMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.repeatedImportMessage_[index] = builderForValue.Build();
        return this;
      }
      public Builder AddRepeatedImportMessage(global::Google.ProtocolBuffers.TestProtos.ImportMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedImportMessage_.Add(value);
        return this;
      }
      public Builder AddRepeatedImportMessage(global::Google.ProtocolBuffers.TestProtos.ImportMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.repeatedImportMessage_.Add(builderForValue.Build());
        return this;
      }
      public Builder AddRangeRepeatedImportMessage(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.ImportMessage> values) {
        base.AddRange(values, result.repeatedImportMessage_);
        return this;
      }
      public Builder ClearRepeatedImportMessage() {
        result.repeatedImportMessage_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum> RepeatedNestedEnumList {
        get { return result.repeatedNestedEnum_; }
      }
      public int RepeatedNestedEnumCount {
        get { return result.RepeatedNestedEnumCount; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum GetRepeatedNestedEnum(int index) {
        return result.GetRepeatedNestedEnum(index);
      }
      public Builder SetRepeatedNestedEnum(int index, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum value) {
        result.repeatedNestedEnum_[index] = value;
        return this;
      }
      public Builder AddRepeatedNestedEnum(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum value) {
        result.repeatedNestedEnum_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedNestedEnum(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum> values) {
        base.AddRange(values, result.repeatedNestedEnum_);
        return this;
      }
      public Builder ClearRepeatedNestedEnum() {
        result.repeatedNestedEnum_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> RepeatedForeignEnumList {
        get { return result.repeatedForeignEnum_; }
      }
      public int RepeatedForeignEnumCount {
        get { return result.RepeatedForeignEnumCount; }
      }
      public global::Google.ProtocolBuffers.TestProtos.ForeignEnum GetRepeatedForeignEnum(int index) {
        return result.GetRepeatedForeignEnum(index);
      }
      public Builder SetRepeatedForeignEnum(int index, global::Google.ProtocolBuffers.TestProtos.ForeignEnum value) {
        result.repeatedForeignEnum_[index] = value;
        return this;
      }
      public Builder AddRepeatedForeignEnum(global::Google.ProtocolBuffers.TestProtos.ForeignEnum value) {
        result.repeatedForeignEnum_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedForeignEnum(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> values) {
        base.AddRange(values, result.repeatedForeignEnum_);
        return this;
      }
      public Builder ClearRepeatedForeignEnum() {
        result.repeatedForeignEnum_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.ImportEnum> RepeatedImportEnumList {
        get { return result.repeatedImportEnum_; }
      }
      public int RepeatedImportEnumCount {
        get { return result.RepeatedImportEnumCount; }
      }
      public global::Google.ProtocolBuffers.TestProtos.ImportEnum GetRepeatedImportEnum(int index) {
        return result.GetRepeatedImportEnum(index);
      }
      public Builder SetRepeatedImportEnum(int index, global::Google.ProtocolBuffers.TestProtos.ImportEnum value) {
        result.repeatedImportEnum_[index] = value;
        return this;
      }
      public Builder AddRepeatedImportEnum(global::Google.ProtocolBuffers.TestProtos.ImportEnum value) {
        result.repeatedImportEnum_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedImportEnum(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.ImportEnum> values) {
        base.AddRange(values, result.repeatedImportEnum_);
        return this;
      }
      public Builder ClearRepeatedImportEnum() {
        result.repeatedImportEnum_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<string> RepeatedStringPieceList {
        get { return result.repeatedStringPiece_; }
      }
      public int RepeatedStringPieceCount {
        get { return result.RepeatedStringPieceCount; }
      }
      public string GetRepeatedStringPiece(int index) {
        return result.GetRepeatedStringPiece(index);
      }
      public Builder SetRepeatedStringPiece(int index, string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedStringPiece_[index] = value;
        return this;
      }
      public Builder AddRepeatedStringPiece(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedStringPiece_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedStringPiece(scg::IEnumerable<string> values) {
        base.AddRange(values, result.repeatedStringPiece_);
        return this;
      }
      public Builder ClearRepeatedStringPiece() {
        result.repeatedStringPiece_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<string> RepeatedCordList {
        get { return result.repeatedCord_; }
      }
      public int RepeatedCordCount {
        get { return result.RepeatedCordCount; }
      }
      public string GetRepeatedCord(int index) {
        return result.GetRepeatedCord(index);
      }
      public Builder SetRepeatedCord(int index, string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedCord_[index] = value;
        return this;
      }
      public Builder AddRepeatedCord(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedCord_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedCord(scg::IEnumerable<string> values) {
        base.AddRange(values, result.repeatedCord_);
        return this;
      }
      public Builder ClearRepeatedCord() {
        result.repeatedCord_.Clear();
        return this;
      }
      
      public bool HasDefaultInt32 {
        get { return result.HasDefaultInt32; }
      }
      public int DefaultInt32 {
        get { return result.DefaultInt32; }
        set { SetDefaultInt32(value); }
      }
      public Builder SetDefaultInt32(int value) {
        result.hasDefaultInt32 = true;
        result.defaultInt32_ = value;
        return this;
      }
      public Builder ClearDefaultInt32() {
        result.hasDefaultInt32 = false;
        result.defaultInt32_ = 41;
        return this;
      }
      
      public bool HasDefaultInt64 {
        get { return result.HasDefaultInt64; }
      }
      public long DefaultInt64 {
        get { return result.DefaultInt64; }
        set { SetDefaultInt64(value); }
      }
      public Builder SetDefaultInt64(long value) {
        result.hasDefaultInt64 = true;
        result.defaultInt64_ = value;
        return this;
      }
      public Builder ClearDefaultInt64() {
        result.hasDefaultInt64 = false;
        result.defaultInt64_ = 42L;
        return this;
      }
      
      public bool HasDefaultUint32 {
        get { return result.HasDefaultUint32; }
      }
      [global::System.CLSCompliant(false)]
      public uint DefaultUint32 {
        get { return result.DefaultUint32; }
        set { SetDefaultUint32(value); }
      }
      [global::System.CLSCompliant(false)]
      public Builder SetDefaultUint32(uint value) {
        result.hasDefaultUint32 = true;
        result.defaultUint32_ = value;
        return this;
      }
      public Builder ClearDefaultUint32() {
        result.hasDefaultUint32 = false;
        result.defaultUint32_ = 43;
        return this;
      }
      
      public bool HasDefaultUint64 {
        get { return result.HasDefaultUint64; }
      }
      [global::System.CLSCompliant(false)]
      public ulong DefaultUint64 {
        get { return result.DefaultUint64; }
        set { SetDefaultUint64(value); }
      }
      [global::System.CLSCompliant(false)]
      public Builder SetDefaultUint64(ulong value) {
        result.hasDefaultUint64 = true;
        result.defaultUint64_ = value;
        return this;
      }
      public Builder ClearDefaultUint64() {
        result.hasDefaultUint64 = false;
        result.defaultUint64_ = 44UL;
        return this;
      }
      
      public bool HasDefaultSint32 {
        get { return result.HasDefaultSint32; }
      }
      public int DefaultSint32 {
        get { return result.DefaultSint32; }
        set { SetDefaultSint32(value); }
      }
      public Builder SetDefaultSint32(int value) {
        result.hasDefaultSint32 = true;
        result.defaultSint32_ = value;
        return this;
      }
      public Builder ClearDefaultSint32() {
        result.hasDefaultSint32 = false;
        result.defaultSint32_ = -45;
        return this;
      }
      
      public bool HasDefaultSint64 {
        get { return result.HasDefaultSint64; }
      }
      public long DefaultSint64 {
        get { return result.DefaultSint64; }
        set { SetDefaultSint64(value); }
      }
      public Builder SetDefaultSint64(long value) {
        result.hasDefaultSint64 = true;
        result.defaultSint64_ = value;
        return this;
      }
      public Builder ClearDefaultSint64() {
        result.hasDefaultSint64 = false;
        result.defaultSint64_ = 46;
        return this;
      }
      
      public bool HasDefaultFixed32 {
        get { return result.HasDefaultFixed32; }
      }
      [global::System.CLSCompliant(false)]
      public uint DefaultFixed32 {
        get { return result.DefaultFixed32; }
        set { SetDefaultFixed32(value); }
      }
      [global::System.CLSCompliant(false)]
      public Builder SetDefaultFixed32(uint value) {
        result.hasDefaultFixed32 = true;
        result.defaultFixed32_ = value;
        return this;
      }
      public Builder ClearDefaultFixed32() {
        result.hasDefaultFixed32 = false;
        result.defaultFixed32_ = 47;
        return this;
      }
      
      public bool HasDefaultFixed64 {
        get { return result.HasDefaultFixed64; }
      }
      [global::System.CLSCompliant(false)]
      public ulong DefaultFixed64 {
        get { return result.DefaultFixed64; }
        set { SetDefaultFixed64(value); }
      }
      [global::System.CLSCompliant(false)]
      public Builder SetDefaultFixed64(ulong value) {
        result.hasDefaultFixed64 = true;
        result.defaultFixed64_ = value;
        return this;
      }
      public Builder ClearDefaultFixed64() {
        result.hasDefaultFixed64 = false;
        result.defaultFixed64_ = 48;
        return this;
      }
      
      public bool HasDefaultSfixed32 {
        get { return result.HasDefaultSfixed32; }
      }
      public int DefaultSfixed32 {
        get { return result.DefaultSfixed32; }
        set { SetDefaultSfixed32(value); }
      }
      public Builder SetDefaultSfixed32(int value) {
        result.hasDefaultSfixed32 = true;
        result.defaultSfixed32_ = value;
        return this;
      }
      public Builder ClearDefaultSfixed32() {
        result.hasDefaultSfixed32 = false;
        result.defaultSfixed32_ = 49;
        return this;
      }
      
      public bool HasDefaultSfixed64 {
        get { return result.HasDefaultSfixed64; }
      }
      public long DefaultSfixed64 {
        get { return result.DefaultSfixed64; }
        set { SetDefaultSfixed64(value); }
      }
      public Builder SetDefaultSfixed64(long value) {
        result.hasDefaultSfixed64 = true;
        result.defaultSfixed64_ = value;
        return this;
      }
      public Builder ClearDefaultSfixed64() {
        result.hasDefaultSfixed64 = false;
        result.defaultSfixed64_ = -50;
        return this;
      }
      
      public bool HasDefaultFloat {
        get { return result.HasDefaultFloat; }
      }
      public float DefaultFloat {
        get { return result.DefaultFloat; }
        set { SetDefaultFloat(value); }
      }
      public Builder SetDefaultFloat(float value) {
        result.hasDefaultFloat = true;
        result.defaultFloat_ = value;
        return this;
      }
      public Builder ClearDefaultFloat() {
        result.hasDefaultFloat = false;
        result.defaultFloat_ = 51.5F;
        return this;
      }
      
      public bool HasDefaultDouble {
        get { return result.HasDefaultDouble; }
      }
      public double DefaultDouble {
        get { return result.DefaultDouble; }
        set { SetDefaultDouble(value); }
      }
      public Builder SetDefaultDouble(double value) {
        result.hasDefaultDouble = true;
        result.defaultDouble_ = value;
        return this;
      }
      public Builder ClearDefaultDouble() {
        result.hasDefaultDouble = false;
        result.defaultDouble_ = 52000D;
        return this;
      }
      
      public bool HasDefaultBool {
        get { return result.HasDefaultBool; }
      }
      public bool DefaultBool {
        get { return result.DefaultBool; }
        set { SetDefaultBool(value); }
      }
      public Builder SetDefaultBool(bool value) {
        result.hasDefaultBool = true;
        result.defaultBool_ = value;
        return this;
      }
      public Builder ClearDefaultBool() {
        result.hasDefaultBool = false;
        result.defaultBool_ = true;
        return this;
      }
      
      public bool HasDefaultString {
        get { return result.HasDefaultString; }
      }
      public string DefaultString {
        get { return result.DefaultString; }
        set { SetDefaultString(value); }
      }
      public Builder SetDefaultString(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasDefaultString = true;
        result.defaultString_ = value;
        return this;
      }
      public Builder ClearDefaultString() {
        result.hasDefaultString = false;
        result.defaultString_ = "hello";
        return this;
      }
      
      public bool HasDefaultBytes {
        get { return result.HasDefaultBytes; }
      }
      public pb::ByteString DefaultBytes {
        get { return result.DefaultBytes; }
        set { SetDefaultBytes(value); }
      }
      public Builder SetDefaultBytes(pb::ByteString value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasDefaultBytes = true;
        result.defaultBytes_ = value;
        return this;
      }
      public Builder ClearDefaultBytes() {
        result.hasDefaultBytes = false;
        result.defaultBytes_ = (pb::ByteString) global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Descriptor.Fields[62].DefaultValue;
        return this;
      }
      
      public bool HasDefaultNestedEnum {
       get { return result.HasDefaultNestedEnum; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum DefaultNestedEnum {
        get { return result.DefaultNestedEnum; }
        set { SetDefaultNestedEnum(value); }
      }
      public Builder SetDefaultNestedEnum(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum value) {
        result.hasDefaultNestedEnum = true;
        result.defaultNestedEnum_ = value;
        return this;
      }
      public Builder ClearDefaultNestedEnum() {
        result.hasDefaultNestedEnum = false;
        result.defaultNestedEnum_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum.BAR;
        return this;
      }
      
      public bool HasDefaultForeignEnum {
       get { return result.HasDefaultForeignEnum; }
      }
      public global::Google.ProtocolBuffers.TestProtos.ForeignEnum DefaultForeignEnum {
        get { return result.DefaultForeignEnum; }
        set { SetDefaultForeignEnum(value); }
      }
      public Builder SetDefaultForeignEnum(global::Google.ProtocolBuffers.TestProtos.ForeignEnum value) {
        result.hasDefaultForeignEnum = true;
        result.defaultForeignEnum_ = value;
        return this;
      }
      public Builder ClearDefaultForeignEnum() {
        result.hasDefaultForeignEnum = false;
        result.defaultForeignEnum_ = global::Google.ProtocolBuffers.TestProtos.ForeignEnum.FOREIGN_BAR;
        return this;
      }
      
      public bool HasDefaultImportEnum {
       get { return result.HasDefaultImportEnum; }
      }
      public global::Google.ProtocolBuffers.TestProtos.ImportEnum DefaultImportEnum {
        get { return result.DefaultImportEnum; }
        set { SetDefaultImportEnum(value); }
      }
      public Builder SetDefaultImportEnum(global::Google.ProtocolBuffers.TestProtos.ImportEnum value) {
        result.hasDefaultImportEnum = true;
        result.defaultImportEnum_ = value;
        return this;
      }
      public Builder ClearDefaultImportEnum() {
        result.hasDefaultImportEnum = false;
        result.defaultImportEnum_ = global::Google.ProtocolBuffers.TestProtos.ImportEnum.IMPORT_BAR;
        return this;
      }
      
      public bool HasDefaultStringPiece {
        get { return result.HasDefaultStringPiece; }
      }
      public string DefaultStringPiece {
        get { return result.DefaultStringPiece; }
        set { SetDefaultStringPiece(value); }
      }
      public Builder SetDefaultStringPiece(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasDefaultStringPiece = true;
        result.defaultStringPiece_ = value;
        return this;
      }
      public Builder ClearDefaultStringPiece() {
        result.hasDefaultStringPiece = false;
        result.defaultStringPiece_ = "abc";
        return this;
      }
      
      public bool HasDefaultCord {
        get { return result.HasDefaultCord; }
      }
      public string DefaultCord {
        get { return result.DefaultCord; }
        set { SetDefaultCord(value); }
      }
      public Builder SetDefaultCord(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasDefaultCord = true;
        result.defaultCord_ = value;
        return this;
      }
      public Builder ClearDefaultCord() {
        result.hasDefaultCord = false;
        result.defaultCord_ = "123";
        return this;
      }
    }
    static TestAllTypes() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 TestDeprecatedFields : pb::GeneratedMessage<TestDeprecatedFields, TestDeprecatedFields.Builder> {
    private static readonly TestDeprecatedFields defaultInstance = new Builder().BuildPartial();
    public static TestDeprecatedFields DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestDeprecatedFields DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestDeprecatedFields ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestDeprecatedFields__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestDeprecatedFields, TestDeprecatedFields.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestDeprecatedFields__FieldAccessorTable; }
    }
    
    public const int DeprecatedInt32FieldNumber = 1;
    private bool hasDeprecatedInt32;
    private int deprecatedInt32_ = 0;
    public bool HasDeprecatedInt32 {
      get { return hasDeprecatedInt32; }
    }
    public int DeprecatedInt32 {
      get { return deprecatedInt32_; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (HasDeprecatedInt32) {
        output.WriteInt32(1, "deprecated_int32", DeprecatedInt32);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasDeprecatedInt32) {
          size += pb::CodedOutputStream.ComputeInt32Size(1, DeprecatedInt32);
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static TestDeprecatedFields ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestDeprecatedFields ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestDeprecatedFields ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestDeprecatedFields ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestDeprecatedFields ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestDeprecatedFields ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestDeprecatedFields ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestDeprecatedFields ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestDeprecatedFields ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestDeprecatedFields 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(TestDeprecatedFields 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<TestDeprecatedFields, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestDeprecatedFields result = new TestDeprecatedFields();
      
      protected override TestDeprecatedFields MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestDeprecatedFields();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestDeprecatedFields.Descriptor; }
      }
      
      public override TestDeprecatedFields DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestDeprecatedFields.DefaultInstance; }
      }
      
      public override TestDeprecatedFields BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        TestDeprecatedFields returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestDeprecatedFields) {
          return MergeFrom((TestDeprecatedFields) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestDeprecatedFields other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestDeprecatedFields.DefaultInstance) return this;
        if (other.HasDeprecatedInt32) {
          DeprecatedInt32 = other.DeprecatedInt32;
        }
        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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
            case 8: {
              result.hasDeprecatedInt32 |= input.ReadInt32(ref result.deprecatedInt32_);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      public bool HasDeprecatedInt32 {
        get { return result.HasDeprecatedInt32; }
      }
      public int DeprecatedInt32 {
        get { return result.DeprecatedInt32; }
        set { SetDeprecatedInt32(value); }
      }
      public Builder SetDeprecatedInt32(int value) {
        result.hasDeprecatedInt32 = true;
        result.deprecatedInt32_ = value;
        return this;
      }
      public Builder ClearDeprecatedInt32() {
        result.hasDeprecatedInt32 = false;
        result.deprecatedInt32_ = 0;
        return this;
      }
    }
    static TestDeprecatedFields() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 ForeignMessage : pb::GeneratedMessage<ForeignMessage, ForeignMessage.Builder> {
    private static readonly ForeignMessage defaultInstance = new Builder().BuildPartial();
    public static ForeignMessage DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override ForeignMessage DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override ForeignMessage ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_ForeignMessage__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<ForeignMessage, ForeignMessage.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_ForeignMessage__FieldAccessorTable; }
    }
    
    public const int CFieldNumber = 1;
    private bool hasC;
    private int c_ = 0;
    public bool HasC {
      get { return hasC; }
    }
    public int C {
      get { return c_; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (HasC) {
        output.WriteInt32(1, "c", C);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasC) {
          size += pb::CodedOutputStream.ComputeInt32Size(1, C);
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static ForeignMessage ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static ForeignMessage ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static ForeignMessage ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static ForeignMessage ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static ForeignMessage ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static ForeignMessage ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static ForeignMessage ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static ForeignMessage ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static ForeignMessage ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static ForeignMessage 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(ForeignMessage 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<ForeignMessage, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      ForeignMessage result = new ForeignMessage();
      
      protected override ForeignMessage MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new ForeignMessage();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Descriptor; }
      }
      
      public override ForeignMessage DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance; }
      }
      
      public override ForeignMessage BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        ForeignMessage returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is ForeignMessage) {
          return MergeFrom((ForeignMessage) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(ForeignMessage other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance) return this;
        if (other.HasC) {
          C = other.C;
        }
        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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
            case 8: {
              result.hasC |= input.ReadInt32(ref result.c_);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      public bool HasC {
        get { return result.HasC; }
      }
      public int C {
        get { return result.C; }
        set { SetC(value); }
      }
      public Builder SetC(int value) {
        result.hasC = true;
        result.c_ = value;
        return this;
      }
      public Builder ClearC() {
        result.hasC = false;
        result.c_ = 0;
        return this;
      }
    }
    static ForeignMessage() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 TestAllExtensions : pb::ExtendableMessage<TestAllExtensions, TestAllExtensions.Builder> {
    private static readonly TestAllExtensions defaultInstance = new Builder().BuildPartial();
    public static TestAllExtensions DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestAllExtensions DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestAllExtensions ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestAllExtensions__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestAllExtensions, TestAllExtensions.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestAllExtensions__FieldAccessorTable; }
    }
    
    public override bool IsInitialized {
      get {
        if (!ExtensionsAreInitialized) return false;
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      pb::ExtendableMessage<TestAllExtensions, TestAllExtensions.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
      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;
        size += ExtensionsSerializedSize;
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static TestAllExtensions ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestAllExtensions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestAllExtensions ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestAllExtensions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestAllExtensions ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestAllExtensions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestAllExtensions ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestAllExtensions ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestAllExtensions ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestAllExtensions 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(TestAllExtensions 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<TestAllExtensions, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestAllExtensions result = new TestAllExtensions();
      
      protected override TestAllExtensions MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestAllExtensions();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestAllExtensions.Descriptor; }
      }
      
      public override TestAllExtensions DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestAllExtensions.DefaultInstance; }
      }
      
      public override TestAllExtensions BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        TestAllExtensions returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestAllExtensions) {
          return MergeFrom((TestAllExtensions) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestAllExtensions other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestAllExtensions.DefaultInstance) return this;
          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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
    }
    static TestAllExtensions() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 OptionalGroup_extension : pb::GeneratedMessage<OptionalGroup_extension, OptionalGroup_extension.Builder> {
    private static readonly OptionalGroup_extension defaultInstance = new Builder().BuildPartial();
    public static OptionalGroup_extension DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override OptionalGroup_extension DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override OptionalGroup_extension ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_OptionalGroup_extension__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<OptionalGroup_extension, OptionalGroup_extension.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_OptionalGroup_extension__FieldAccessorTable; }
    }
    
    public const int AFieldNumber = 17;
    private bool hasA;
    private int a_ = 0;
    public bool HasA {
      get { return hasA; }
    }
    public int A {
      get { return a_; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (HasA) {
        output.WriteInt32(17, "a", A);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasA) {
          size += pb::CodedOutputStream.ComputeInt32Size(17, A);
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static OptionalGroup_extension ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static OptionalGroup_extension ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static OptionalGroup_extension ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static OptionalGroup_extension ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static OptionalGroup_extension ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static OptionalGroup_extension ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static OptionalGroup_extension ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static OptionalGroup_extension ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static OptionalGroup_extension ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static OptionalGroup_extension 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(OptionalGroup_extension 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<OptionalGroup_extension, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      OptionalGroup_extension result = new OptionalGroup_extension();
      
      protected override OptionalGroup_extension MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new OptionalGroup_extension();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.OptionalGroup_extension.Descriptor; }
      }
      
      public override OptionalGroup_extension DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.OptionalGroup_extension.DefaultInstance; }
      }
      
      public override OptionalGroup_extension BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        OptionalGroup_extension returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is OptionalGroup_extension) {
          return MergeFrom((OptionalGroup_extension) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(OptionalGroup_extension other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.OptionalGroup_extension.DefaultInstance) return this;
        if (other.HasA) {
          A = other.A;
        }
        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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
            case 136: {
              result.hasA |= input.ReadInt32(ref result.a_);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      public bool HasA {
        get { return result.HasA; }
      }
      public int A {
        get { return result.A; }
        set { SetA(value); }
      }
      public Builder SetA(int value) {
        result.hasA = true;
        result.a_ = value;
        return this;
      }
      public Builder ClearA() {
        result.hasA = false;
        result.a_ = 0;
        return this;
      }
    }
    static OptionalGroup_extension() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 RepeatedGroup_extension : pb::GeneratedMessage<RepeatedGroup_extension, RepeatedGroup_extension.Builder> {
    private static readonly RepeatedGroup_extension defaultInstance = new Builder().BuildPartial();
    public static RepeatedGroup_extension DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override RepeatedGroup_extension DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override RepeatedGroup_extension ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_RepeatedGroup_extension__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<RepeatedGroup_extension, RepeatedGroup_extension.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_RepeatedGroup_extension__FieldAccessorTable; }
    }
    
    public const int AFieldNumber = 47;
    private bool hasA;
    private int a_ = 0;
    public bool HasA {
      get { return hasA; }
    }
    public int A {
      get { return a_; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (HasA) {
        output.WriteInt32(47, "a", A);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasA) {
          size += pb::CodedOutputStream.ComputeInt32Size(47, A);
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static RepeatedGroup_extension ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static RepeatedGroup_extension ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static RepeatedGroup_extension ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static RepeatedGroup_extension ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static RepeatedGroup_extension ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static RepeatedGroup_extension ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static RepeatedGroup_extension ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static RepeatedGroup_extension ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static RepeatedGroup_extension ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static RepeatedGroup_extension 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(RepeatedGroup_extension 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<RepeatedGroup_extension, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      RepeatedGroup_extension result = new RepeatedGroup_extension();
      
      protected override RepeatedGroup_extension MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new RepeatedGroup_extension();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.RepeatedGroup_extension.Descriptor; }
      }
      
      public override RepeatedGroup_extension DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.RepeatedGroup_extension.DefaultInstance; }
      }
      
      public override RepeatedGroup_extension BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        RepeatedGroup_extension returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is RepeatedGroup_extension) {
          return MergeFrom((RepeatedGroup_extension) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(RepeatedGroup_extension other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.RepeatedGroup_extension.DefaultInstance) return this;
        if (other.HasA) {
          A = other.A;
        }
        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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
            case 376: {
              result.hasA |= input.ReadInt32(ref result.a_);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      public bool HasA {
        get { return result.HasA; }
      }
      public int A {
        get { return result.A; }
        set { SetA(value); }
      }
      public Builder SetA(int value) {
        result.hasA = true;
        result.a_ = value;
        return this;
      }
      public Builder ClearA() {
        result.hasA = false;
        result.a_ = 0;
        return this;
      }
    }
    static RepeatedGroup_extension() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 TestNestedExtension : pb::GeneratedMessage<TestNestedExtension, TestNestedExtension.Builder> {
    private static readonly TestNestedExtension defaultInstance = new Builder().BuildPartial();
    public static TestNestedExtension DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestNestedExtension DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestNestedExtension ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestNestedExtension__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestNestedExtension, TestNestedExtension.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestNestedExtension__FieldAccessorTable; }
    }
    
    public const int TestFieldNumber = 1002;
    public static pb::GeneratedExtensionBase<string> Test;
    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 TestNestedExtension ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestNestedExtension ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestNestedExtension ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestNestedExtension ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestNestedExtension ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestNestedExtension ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestNestedExtension ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestNestedExtension ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestNestedExtension ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestNestedExtension 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(TestNestedExtension 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<TestNestedExtension, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestNestedExtension result = new TestNestedExtension();
      
      protected override TestNestedExtension MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestNestedExtension();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestNestedExtension.Descriptor; }
      }
      
      public override TestNestedExtension DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestNestedExtension.DefaultInstance; }
      }
      
      public override TestNestedExtension BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        TestNestedExtension returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestNestedExtension) {
          return MergeFrom((TestNestedExtension) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestNestedExtension other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestNestedExtension.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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
    }
    static TestNestedExtension() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 TestRequired : pb::GeneratedMessage<TestRequired, TestRequired.Builder> {
    private static readonly TestRequired defaultInstance = new Builder().BuildPartial();
    public static TestRequired DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestRequired DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestRequired ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestRequired__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestRequired, TestRequired.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestRequired__FieldAccessorTable; }
    }
    
    public const int SingleFieldNumber = 1000;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.TestRequired> Single;
    public const int MultiFieldNumber = 1001;
    public static pb::GeneratedExtensionBase<scg::IList<global::Google.ProtocolBuffers.TestProtos.TestRequired>> Multi;
    public const int AFieldNumber = 1;
    private bool hasA;
    private int a_ = 0;
    public bool HasA {
      get { return hasA; }
    }
    public int A {
      get { return a_; }
    }
    
    public const int Dummy2FieldNumber = 2;
    private bool hasDummy2;
    private int dummy2_ = 0;
    public bool HasDummy2 {
      get { return hasDummy2; }
    }
    public int Dummy2 {
      get { return dummy2_; }
    }
    
    public const int BFieldNumber = 3;
    private bool hasB;
    private int b_ = 0;
    public bool HasB {
      get { return hasB; }
    }
    public int B {
      get { return b_; }
    }
    
    public const int Dummy4FieldNumber = 4;
    private bool hasDummy4;
    private int dummy4_ = 0;
    public bool HasDummy4 {
      get { return hasDummy4; }
    }
    public int Dummy4 {
      get { return dummy4_; }
    }
    
    public const int Dummy5FieldNumber = 5;
    private bool hasDummy5;
    private int dummy5_ = 0;
    public bool HasDummy5 {
      get { return hasDummy5; }
    }
    public int Dummy5 {
      get { return dummy5_; }
    }
    
    public const int Dummy6FieldNumber = 6;
    private bool hasDummy6;
    private int dummy6_ = 0;
    public bool HasDummy6 {
      get { return hasDummy6; }
    }
    public int Dummy6 {
      get { return dummy6_; }
    }
    
    public const int Dummy7FieldNumber = 7;
    private bool hasDummy7;
    private int dummy7_ = 0;
    public bool HasDummy7 {
      get { return hasDummy7; }
    }
    public int Dummy7 {
      get { return dummy7_; }
    }
    
    public const int Dummy8FieldNumber = 8;
    private bool hasDummy8;
    private int dummy8_ = 0;
    public bool HasDummy8 {
      get { return hasDummy8; }
    }
    public int Dummy8 {
      get { return dummy8_; }
    }
    
    public const int Dummy9FieldNumber = 9;
    private bool hasDummy9;
    private int dummy9_ = 0;
    public bool HasDummy9 {
      get { return hasDummy9; }
    }
    public int Dummy9 {
      get { return dummy9_; }
    }
    
    public const int Dummy10FieldNumber = 10;
    private bool hasDummy10;
    private int dummy10_ = 0;
    public bool HasDummy10 {
      get { return hasDummy10; }
    }
    public int Dummy10 {
      get { return dummy10_; }
    }
    
    public const int Dummy11FieldNumber = 11;
    private bool hasDummy11;
    private int dummy11_ = 0;
    public bool HasDummy11 {
      get { return hasDummy11; }
    }
    public int Dummy11 {
      get { return dummy11_; }
    }
    
    public const int Dummy12FieldNumber = 12;
    private bool hasDummy12;
    private int dummy12_ = 0;
    public bool HasDummy12 {
      get { return hasDummy12; }
    }
    public int Dummy12 {
      get { return dummy12_; }
    }
    
    public const int Dummy13FieldNumber = 13;
    private bool hasDummy13;
    private int dummy13_ = 0;
    public bool HasDummy13 {
      get { return hasDummy13; }
    }
    public int Dummy13 {
      get { return dummy13_; }
    }
    
    public const int Dummy14FieldNumber = 14;
    private bool hasDummy14;
    private int dummy14_ = 0;
    public bool HasDummy14 {
      get { return hasDummy14; }
    }
    public int Dummy14 {
      get { return dummy14_; }
    }
    
    public const int Dummy15FieldNumber = 15;
    private bool hasDummy15;
    private int dummy15_ = 0;
    public bool HasDummy15 {
      get { return hasDummy15; }
    }
    public int Dummy15 {
      get { return dummy15_; }
    }
    
    public const int Dummy16FieldNumber = 16;
    private bool hasDummy16;
    private int dummy16_ = 0;
    public bool HasDummy16 {
      get { return hasDummy16; }
    }
    public int Dummy16 {
      get { return dummy16_; }
    }
    
    public const int Dummy17FieldNumber = 17;
    private bool hasDummy17;
    private int dummy17_ = 0;
    public bool HasDummy17 {
      get { return hasDummy17; }
    }
    public int Dummy17 {
      get { return dummy17_; }
    }
    
    public const int Dummy18FieldNumber = 18;
    private bool hasDummy18;
    private int dummy18_ = 0;
    public bool HasDummy18 {
      get { return hasDummy18; }
    }
    public int Dummy18 {
      get { return dummy18_; }
    }
    
    public const int Dummy19FieldNumber = 19;
    private bool hasDummy19;
    private int dummy19_ = 0;
    public bool HasDummy19 {
      get { return hasDummy19; }
    }
    public int Dummy19 {
      get { return dummy19_; }
    }
    
    public const int Dummy20FieldNumber = 20;
    private bool hasDummy20;
    private int dummy20_ = 0;
    public bool HasDummy20 {
      get { return hasDummy20; }
    }
    public int Dummy20 {
      get { return dummy20_; }
    }
    
    public const int Dummy21FieldNumber = 21;
    private bool hasDummy21;
    private int dummy21_ = 0;
    public bool HasDummy21 {
      get { return hasDummy21; }
    }
    public int Dummy21 {
      get { return dummy21_; }
    }
    
    public const int Dummy22FieldNumber = 22;
    private bool hasDummy22;
    private int dummy22_ = 0;
    public bool HasDummy22 {
      get { return hasDummy22; }
    }
    public int Dummy22 {
      get { return dummy22_; }
    }
    
    public const int Dummy23FieldNumber = 23;
    private bool hasDummy23;
    private int dummy23_ = 0;
    public bool HasDummy23 {
      get { return hasDummy23; }
    }
    public int Dummy23 {
      get { return dummy23_; }
    }
    
    public const int Dummy24FieldNumber = 24;
    private bool hasDummy24;
    private int dummy24_ = 0;
    public bool HasDummy24 {
      get { return hasDummy24; }
    }
    public int Dummy24 {
      get { return dummy24_; }
    }
    
    public const int Dummy25FieldNumber = 25;
    private bool hasDummy25;
    private int dummy25_ = 0;
    public bool HasDummy25 {
      get { return hasDummy25; }
    }
    public int Dummy25 {
      get { return dummy25_; }
    }
    
    public const int Dummy26FieldNumber = 26;
    private bool hasDummy26;
    private int dummy26_ = 0;
    public bool HasDummy26 {
      get { return hasDummy26; }
    }
    public int Dummy26 {
      get { return dummy26_; }
    }
    
    public const int Dummy27FieldNumber = 27;
    private bool hasDummy27;
    private int dummy27_ = 0;
    public bool HasDummy27 {
      get { return hasDummy27; }
    }
    public int Dummy27 {
      get { return dummy27_; }
    }
    
    public const int Dummy28FieldNumber = 28;
    private bool hasDummy28;
    private int dummy28_ = 0;
    public bool HasDummy28 {
      get { return hasDummy28; }
    }
    public int Dummy28 {
      get { return dummy28_; }
    }
    
    public const int Dummy29FieldNumber = 29;
    private bool hasDummy29;
    private int dummy29_ = 0;
    public bool HasDummy29 {
      get { return hasDummy29; }
    }
    public int Dummy29 {
      get { return dummy29_; }
    }
    
    public const int Dummy30FieldNumber = 30;
    private bool hasDummy30;
    private int dummy30_ = 0;
    public bool HasDummy30 {
      get { return hasDummy30; }
    }
    public int Dummy30 {
      get { return dummy30_; }
    }
    
    public const int Dummy31FieldNumber = 31;
    private bool hasDummy31;
    private int dummy31_ = 0;
    public bool HasDummy31 {
      get { return hasDummy31; }
    }
    public int Dummy31 {
      get { return dummy31_; }
    }
    
    public const int Dummy32FieldNumber = 32;
    private bool hasDummy32;
    private int dummy32_ = 0;
    public bool HasDummy32 {
      get { return hasDummy32; }
    }
    public int Dummy32 {
      get { return dummy32_; }
    }
    
    public const int CFieldNumber = 33;
    private bool hasC;
    private int c_ = 0;
    public bool HasC {
      get { return hasC; }
    }
    public int C {
      get { return c_; }
    }
    
    public override bool IsInitialized {
      get {
        if (!hasA) return false;
        if (!hasB) return false;
        if (!hasC) return false;
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (HasA) {
        output.WriteInt32(1, "a", A);
      }
      if (HasDummy2) {
        output.WriteInt32(2, "dummy2", Dummy2);
      }
      if (HasB) {
        output.WriteInt32(3, "b", B);
      }
      if (HasDummy4) {
        output.WriteInt32(4, "dummy4", Dummy4);
      }
      if (HasDummy5) {
        output.WriteInt32(5, "dummy5", Dummy5);
      }
      if (HasDummy6) {
        output.WriteInt32(6, "dummy6", Dummy6);
      }
      if (HasDummy7) {
        output.WriteInt32(7, "dummy7", Dummy7);
      }
      if (HasDummy8) {
        output.WriteInt32(8, "dummy8", Dummy8);
      }
      if (HasDummy9) {
        output.WriteInt32(9, "dummy9", Dummy9);
      }
      if (HasDummy10) {
        output.WriteInt32(10, "dummy10", Dummy10);
      }
      if (HasDummy11) {
        output.WriteInt32(11, "dummy11", Dummy11);
      }
      if (HasDummy12) {
        output.WriteInt32(12, "dummy12", Dummy12);
      }
      if (HasDummy13) {
        output.WriteInt32(13, "dummy13", Dummy13);
      }
      if (HasDummy14) {
        output.WriteInt32(14, "dummy14", Dummy14);
      }
      if (HasDummy15) {
        output.WriteInt32(15, "dummy15", Dummy15);
      }
      if (HasDummy16) {
        output.WriteInt32(16, "dummy16", Dummy16);
      }
      if (HasDummy17) {
        output.WriteInt32(17, "dummy17", Dummy17);
      }
      if (HasDummy18) {
        output.WriteInt32(18, "dummy18", Dummy18);
      }
      if (HasDummy19) {
        output.WriteInt32(19, "dummy19", Dummy19);
      }
      if (HasDummy20) {
        output.WriteInt32(20, "dummy20", Dummy20);
      }
      if (HasDummy21) {
        output.WriteInt32(21, "dummy21", Dummy21);
      }
      if (HasDummy22) {
        output.WriteInt32(22, "dummy22", Dummy22);
      }
      if (HasDummy23) {
        output.WriteInt32(23, "dummy23", Dummy23);
      }
      if (HasDummy24) {
        output.WriteInt32(24, "dummy24", Dummy24);
      }
      if (HasDummy25) {
        output.WriteInt32(25, "dummy25", Dummy25);
      }
      if (HasDummy26) {
        output.WriteInt32(26, "dummy26", Dummy26);
      }
      if (HasDummy27) {
        output.WriteInt32(27, "dummy27", Dummy27);
      }
      if (HasDummy28) {
        output.WriteInt32(28, "dummy28", Dummy28);
      }
      if (HasDummy29) {
        output.WriteInt32(29, "dummy29", Dummy29);
      }
      if (HasDummy30) {
        output.WriteInt32(30, "dummy30", Dummy30);
      }
      if (HasDummy31) {
        output.WriteInt32(31, "dummy31", Dummy31);
      }
      if (HasDummy32) {
        output.WriteInt32(32, "dummy32", Dummy32);
      }
      if (HasC) {
        output.WriteInt32(33, "c", C);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasA) {
          size += pb::CodedOutputStream.ComputeInt32Size(1, A);
        }
        if (HasDummy2) {
          size += pb::CodedOutputStream.ComputeInt32Size(2, Dummy2);
        }
        if (HasB) {
          size += pb::CodedOutputStream.ComputeInt32Size(3, B);
        }
        if (HasDummy4) {
          size += pb::CodedOutputStream.ComputeInt32Size(4, Dummy4);
        }
        if (HasDummy5) {
          size += pb::CodedOutputStream.ComputeInt32Size(5, Dummy5);
        }
        if (HasDummy6) {
          size += pb::CodedOutputStream.ComputeInt32Size(6, Dummy6);
        }
        if (HasDummy7) {
          size += pb::CodedOutputStream.ComputeInt32Size(7, Dummy7);
        }
        if (HasDummy8) {
          size += pb::CodedOutputStream.ComputeInt32Size(8, Dummy8);
        }
        if (HasDummy9) {
          size += pb::CodedOutputStream.ComputeInt32Size(9, Dummy9);
        }
        if (HasDummy10) {
          size += pb::CodedOutputStream.ComputeInt32Size(10, Dummy10);
        }
        if (HasDummy11) {
          size += pb::CodedOutputStream.ComputeInt32Size(11, Dummy11);
        }
        if (HasDummy12) {
          size += pb::CodedOutputStream.ComputeInt32Size(12, Dummy12);
        }
        if (HasDummy13) {
          size += pb::CodedOutputStream.ComputeInt32Size(13, Dummy13);
        }
        if (HasDummy14) {
          size += pb::CodedOutputStream.ComputeInt32Size(14, Dummy14);
        }
        if (HasDummy15) {
          size += pb::CodedOutputStream.ComputeInt32Size(15, Dummy15);
        }
        if (HasDummy16) {
          size += pb::CodedOutputStream.ComputeInt32Size(16, Dummy16);
        }
        if (HasDummy17) {
          size += pb::CodedOutputStream.ComputeInt32Size(17, Dummy17);
        }
        if (HasDummy18) {
          size += pb::CodedOutputStream.ComputeInt32Size(18, Dummy18);
        }
        if (HasDummy19) {
          size += pb::CodedOutputStream.ComputeInt32Size(19, Dummy19);
        }
        if (HasDummy20) {
          size += pb::CodedOutputStream.ComputeInt32Size(20, Dummy20);
        }
        if (HasDummy21) {
          size += pb::CodedOutputStream.ComputeInt32Size(21, Dummy21);
        }
        if (HasDummy22) {
          size += pb::CodedOutputStream.ComputeInt32Size(22, Dummy22);
        }
        if (HasDummy23) {
          size += pb::CodedOutputStream.ComputeInt32Size(23, Dummy23);
        }
        if (HasDummy24) {
          size += pb::CodedOutputStream.ComputeInt32Size(24, Dummy24);
        }
        if (HasDummy25) {
          size += pb::CodedOutputStream.ComputeInt32Size(25, Dummy25);
        }
        if (HasDummy26) {
          size += pb::CodedOutputStream.ComputeInt32Size(26, Dummy26);
        }
        if (HasDummy27) {
          size += pb::CodedOutputStream.ComputeInt32Size(27, Dummy27);
        }
        if (HasDummy28) {
          size += pb::CodedOutputStream.ComputeInt32Size(28, Dummy28);
        }
        if (HasDummy29) {
          size += pb::CodedOutputStream.ComputeInt32Size(29, Dummy29);
        }
        if (HasDummy30) {
          size += pb::CodedOutputStream.ComputeInt32Size(30, Dummy30);
        }
        if (HasDummy31) {
          size += pb::CodedOutputStream.ComputeInt32Size(31, Dummy31);
        }
        if (HasDummy32) {
          size += pb::CodedOutputStream.ComputeInt32Size(32, Dummy32);
        }
        if (HasC) {
          size += pb::CodedOutputStream.ComputeInt32Size(33, C);
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static TestRequired ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestRequired ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestRequired ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestRequired ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestRequired ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestRequired ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestRequired ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestRequired ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestRequired ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestRequired 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(TestRequired 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<TestRequired, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestRequired result = new TestRequired();
      
      protected override TestRequired MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestRequired();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestRequired.Descriptor; }
      }
      
      public override TestRequired DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestRequired.DefaultInstance; }
      }
      
      public override TestRequired BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        TestRequired returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestRequired) {
          return MergeFrom((TestRequired) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestRequired other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestRequired.DefaultInstance) return this;
        if (other.HasA) {
          A = other.A;
        }
        if (other.HasDummy2) {
          Dummy2 = other.Dummy2;
        }
        if (other.HasB) {
          B = other.B;
        }
        if (other.HasDummy4) {
          Dummy4 = other.Dummy4;
        }
        if (other.HasDummy5) {
          Dummy5 = other.Dummy5;
        }
        if (other.HasDummy6) {
          Dummy6 = other.Dummy6;
        }
        if (other.HasDummy7) {
          Dummy7 = other.Dummy7;
        }
        if (other.HasDummy8) {
          Dummy8 = other.Dummy8;
        }
        if (other.HasDummy9) {
          Dummy9 = other.Dummy9;
        }
        if (other.HasDummy10) {
          Dummy10 = other.Dummy10;
        }
        if (other.HasDummy11) {
          Dummy11 = other.Dummy11;
        }
        if (other.HasDummy12) {
          Dummy12 = other.Dummy12;
        }
        if (other.HasDummy13) {
          Dummy13 = other.Dummy13;
        }
        if (other.HasDummy14) {
          Dummy14 = other.Dummy14;
        }
        if (other.HasDummy15) {
          Dummy15 = other.Dummy15;
        }
        if (other.HasDummy16) {
          Dummy16 = other.Dummy16;
        }
        if (other.HasDummy17) {
          Dummy17 = other.Dummy17;
        }
        if (other.HasDummy18) {
          Dummy18 = other.Dummy18;
        }
        if (other.HasDummy19) {
          Dummy19 = other.Dummy19;
        }
        if (other.HasDummy20) {
          Dummy20 = other.Dummy20;
        }
        if (other.HasDummy21) {
          Dummy21 = other.Dummy21;
        }
        if (other.HasDummy22) {
          Dummy22 = other.Dummy22;
        }
        if (other.HasDummy23) {
          Dummy23 = other.Dummy23;
        }
        if (other.HasDummy24) {
          Dummy24 = other.Dummy24;
        }
        if (other.HasDummy25) {
          Dummy25 = other.Dummy25;
        }
        if (other.HasDummy26) {
          Dummy26 = other.Dummy26;
        }
        if (other.HasDummy27) {
          Dummy27 = other.Dummy27;
        }
        if (other.HasDummy28) {
          Dummy28 = other.Dummy28;
        }
        if (other.HasDummy29) {
          Dummy29 = other.Dummy29;
        }
        if (other.HasDummy30) {
          Dummy30 = other.Dummy30;
        }
        if (other.HasDummy31) {
          Dummy31 = other.Dummy31;
        }
        if (other.HasDummy32) {
          Dummy32 = other.Dummy32;
        }
        if (other.HasC) {
          C = other.C;
        }
        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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
            case 8: {
              result.hasA |= input.ReadInt32(ref result.a_);
              break;
            }
            case 16: {
              result.hasDummy2 |= input.ReadInt32(ref result.dummy2_);
              break;
            }
            case 24: {
              result.hasB |= input.ReadInt32(ref result.b_);
              break;
            }
            case 32: {
              result.hasDummy4 |= input.ReadInt32(ref result.dummy4_);
              break;
            }
            case 40: {
              result.hasDummy5 |= input.ReadInt32(ref result.dummy5_);
              break;
            }
            case 48: {
              result.hasDummy6 |= input.ReadInt32(ref result.dummy6_);
              break;
            }
            case 56: {
              result.hasDummy7 |= input.ReadInt32(ref result.dummy7_);
              break;
            }
            case 64: {
              result.hasDummy8 |= input.ReadInt32(ref result.dummy8_);
              break;
            }
            case 72: {
              result.hasDummy9 |= input.ReadInt32(ref result.dummy9_);
              break;
            }
            case 80: {
              result.hasDummy10 |= input.ReadInt32(ref result.dummy10_);
              break;
            }
            case 88: {
              result.hasDummy11 |= input.ReadInt32(ref result.dummy11_);
              break;
            }
            case 96: {
              result.hasDummy12 |= input.ReadInt32(ref result.dummy12_);
              break;
            }
            case 104: {
              result.hasDummy13 |= input.ReadInt32(ref result.dummy13_);
              break;
            }
            case 112: {
              result.hasDummy14 |= input.ReadInt32(ref result.dummy14_);
              break;
            }
            case 120: {
              result.hasDummy15 |= input.ReadInt32(ref result.dummy15_);
              break;
            }
            case 128: {
              result.hasDummy16 |= input.ReadInt32(ref result.dummy16_);
              break;
            }
            case 136: {
              result.hasDummy17 |= input.ReadInt32(ref result.dummy17_);
              break;
            }
            case 144: {
              result.hasDummy18 |= input.ReadInt32(ref result.dummy18_);
              break;
            }
            case 152: {
              result.hasDummy19 |= input.ReadInt32(ref result.dummy19_);
              break;
            }
            case 160: {
              result.hasDummy20 |= input.ReadInt32(ref result.dummy20_);
              break;
            }
            case 168: {
              result.hasDummy21 |= input.ReadInt32(ref result.dummy21_);
              break;
            }
            case 176: {
              result.hasDummy22 |= input.ReadInt32(ref result.dummy22_);
              break;
            }
            case 184: {
              result.hasDummy23 |= input.ReadInt32(ref result.dummy23_);
              break;
            }
            case 192: {
              result.hasDummy24 |= input.ReadInt32(ref result.dummy24_);
              break;
            }
            case 200: {
              result.hasDummy25 |= input.ReadInt32(ref result.dummy25_);
              break;
            }
            case 208: {
              result.hasDummy26 |= input.ReadInt32(ref result.dummy26_);
              break;
            }
            case 216: {
              result.hasDummy27 |= input.ReadInt32(ref result.dummy27_);
              break;
            }
            case 224: {
              result.hasDummy28 |= input.ReadInt32(ref result.dummy28_);
              break;
            }
            case 232: {
              result.hasDummy29 |= input.ReadInt32(ref result.dummy29_);
              break;
            }
            case 240: {
              result.hasDummy30 |= input.ReadInt32(ref result.dummy30_);
              break;
            }
            case 248: {
              result.hasDummy31 |= input.ReadInt32(ref result.dummy31_);
              break;
            }
            case 256: {
              result.hasDummy32 |= input.ReadInt32(ref result.dummy32_);
              break;
            }
            case 264: {
              result.hasC |= input.ReadInt32(ref result.c_);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      public bool HasA {
        get { return result.HasA; }
      }
      public int A {
        get { return result.A; }
        set { SetA(value); }
      }
      public Builder SetA(int value) {
        result.hasA = true;
        result.a_ = value;
        return this;
      }
      public Builder ClearA() {
        result.hasA = false;
        result.a_ = 0;
        return this;
      }
      
      public bool HasDummy2 {
        get { return result.HasDummy2; }
      }
      public int Dummy2 {
        get { return result.Dummy2; }
        set { SetDummy2(value); }
      }
      public Builder SetDummy2(int value) {
        result.hasDummy2 = true;
        result.dummy2_ = value;
        return this;
      }
      public Builder ClearDummy2() {
        result.hasDummy2 = false;
        result.dummy2_ = 0;
        return this;
      }
      
      public bool HasB {
        get { return result.HasB; }
      }
      public int B {
        get { return result.B; }
        set { SetB(value); }
      }
      public Builder SetB(int value) {
        result.hasB = true;
        result.b_ = value;
        return this;
      }
      public Builder ClearB() {
        result.hasB = false;
        result.b_ = 0;
        return this;
      }
      
      public bool HasDummy4 {
        get { return result.HasDummy4; }
      }
      public int Dummy4 {
        get { return result.Dummy4; }
        set { SetDummy4(value); }
      }
      public Builder SetDummy4(int value) {
        result.hasDummy4 = true;
        result.dummy4_ = value;
        return this;
      }
      public Builder ClearDummy4() {
        result.hasDummy4 = false;
        result.dummy4_ = 0;
        return this;
      }
      
      public bool HasDummy5 {
        get { return result.HasDummy5; }
      }
      public int Dummy5 {
        get { return result.Dummy5; }
        set { SetDummy5(value); }
      }
      public Builder SetDummy5(int value) {
        result.hasDummy5 = true;
        result.dummy5_ = value;
        return this;
      }
      public Builder ClearDummy5() {
        result.hasDummy5 = false;
        result.dummy5_ = 0;
        return this;
      }
      
      public bool HasDummy6 {
        get { return result.HasDummy6; }
      }
      public int Dummy6 {
        get { return result.Dummy6; }
        set { SetDummy6(value); }
      }
      public Builder SetDummy6(int value) {
        result.hasDummy6 = true;
        result.dummy6_ = value;
        return this;
      }
      public Builder ClearDummy6() {
        result.hasDummy6 = false;
        result.dummy6_ = 0;
        return this;
      }
      
      public bool HasDummy7 {
        get { return result.HasDummy7; }
      }
      public int Dummy7 {
        get { return result.Dummy7; }
        set { SetDummy7(value); }
      }
      public Builder SetDummy7(int value) {
        result.hasDummy7 = true;
        result.dummy7_ = value;
        return this;
      }
      public Builder ClearDummy7() {
        result.hasDummy7 = false;
        result.dummy7_ = 0;
        return this;
      }
      
      public bool HasDummy8 {
        get { return result.HasDummy8; }
      }
      public int Dummy8 {
        get { return result.Dummy8; }
        set { SetDummy8(value); }
      }
      public Builder SetDummy8(int value) {
        result.hasDummy8 = true;
        result.dummy8_ = value;
        return this;
      }
      public Builder ClearDummy8() {
        result.hasDummy8 = false;
        result.dummy8_ = 0;
        return this;
      }
      
      public bool HasDummy9 {
        get { return result.HasDummy9; }
      }
      public int Dummy9 {
        get { return result.Dummy9; }
        set { SetDummy9(value); }
      }
      public Builder SetDummy9(int value) {
        result.hasDummy9 = true;
        result.dummy9_ = value;
        return this;
      }
      public Builder ClearDummy9() {
        result.hasDummy9 = false;
        result.dummy9_ = 0;
        return this;
      }
      
      public bool HasDummy10 {
        get { return result.HasDummy10; }
      }
      public int Dummy10 {
        get { return result.Dummy10; }
        set { SetDummy10(value); }
      }
      public Builder SetDummy10(int value) {
        result.hasDummy10 = true;
        result.dummy10_ = value;
        return this;
      }
      public Builder ClearDummy10() {
        result.hasDummy10 = false;
        result.dummy10_ = 0;
        return this;
      }
      
      public bool HasDummy11 {
        get { return result.HasDummy11; }
      }
      public int Dummy11 {
        get { return result.Dummy11; }
        set { SetDummy11(value); }
      }
      public Builder SetDummy11(int value) {
        result.hasDummy11 = true;
        result.dummy11_ = value;
        return this;
      }
      public Builder ClearDummy11() {
        result.hasDummy11 = false;
        result.dummy11_ = 0;
        return this;
      }
      
      public bool HasDummy12 {
        get { return result.HasDummy12; }
      }
      public int Dummy12 {
        get { return result.Dummy12; }
        set { SetDummy12(value); }
      }
      public Builder SetDummy12(int value) {
        result.hasDummy12 = true;
        result.dummy12_ = value;
        return this;
      }
      public Builder ClearDummy12() {
        result.hasDummy12 = false;
        result.dummy12_ = 0;
        return this;
      }
      
      public bool HasDummy13 {
        get { return result.HasDummy13; }
      }
      public int Dummy13 {
        get { return result.Dummy13; }
        set { SetDummy13(value); }
      }
      public Builder SetDummy13(int value) {
        result.hasDummy13 = true;
        result.dummy13_ = value;
        return this;
      }
      public Builder ClearDummy13() {
        result.hasDummy13 = false;
        result.dummy13_ = 0;
        return this;
      }
      
      public bool HasDummy14 {
        get { return result.HasDummy14; }
      }
      public int Dummy14 {
        get { return result.Dummy14; }
        set { SetDummy14(value); }
      }
      public Builder SetDummy14(int value) {
        result.hasDummy14 = true;
        result.dummy14_ = value;
        return this;
      }
      public Builder ClearDummy14() {
        result.hasDummy14 = false;
        result.dummy14_ = 0;
        return this;
      }
      
      public bool HasDummy15 {
        get { return result.HasDummy15; }
      }
      public int Dummy15 {
        get { return result.Dummy15; }
        set { SetDummy15(value); }
      }
      public Builder SetDummy15(int value) {
        result.hasDummy15 = true;
        result.dummy15_ = value;
        return this;
      }
      public Builder ClearDummy15() {
        result.hasDummy15 = false;
        result.dummy15_ = 0;
        return this;
      }
      
      public bool HasDummy16 {
        get { return result.HasDummy16; }
      }
      public int Dummy16 {
        get { return result.Dummy16; }
        set { SetDummy16(value); }
      }
      public Builder SetDummy16(int value) {
        result.hasDummy16 = true;
        result.dummy16_ = value;
        return this;
      }
      public Builder ClearDummy16() {
        result.hasDummy16 = false;
        result.dummy16_ = 0;
        return this;
      }
      
      public bool HasDummy17 {
        get { return result.HasDummy17; }
      }
      public int Dummy17 {
        get { return result.Dummy17; }
        set { SetDummy17(value); }
      }
      public Builder SetDummy17(int value) {
        result.hasDummy17 = true;
        result.dummy17_ = value;
        return this;
      }
      public Builder ClearDummy17() {
        result.hasDummy17 = false;
        result.dummy17_ = 0;
        return this;
      }
      
      public bool HasDummy18 {
        get { return result.HasDummy18; }
      }
      public int Dummy18 {
        get { return result.Dummy18; }
        set { SetDummy18(value); }
      }
      public Builder SetDummy18(int value) {
        result.hasDummy18 = true;
        result.dummy18_ = value;
        return this;
      }
      public Builder ClearDummy18() {
        result.hasDummy18 = false;
        result.dummy18_ = 0;
        return this;
      }
      
      public bool HasDummy19 {
        get { return result.HasDummy19; }
      }
      public int Dummy19 {
        get { return result.Dummy19; }
        set { SetDummy19(value); }
      }
      public Builder SetDummy19(int value) {
        result.hasDummy19 = true;
        result.dummy19_ = value;
        return this;
      }
      public Builder ClearDummy19() {
        result.hasDummy19 = false;
        result.dummy19_ = 0;
        return this;
      }
      
      public bool HasDummy20 {
        get { return result.HasDummy20; }
      }
      public int Dummy20 {
        get { return result.Dummy20; }
        set { SetDummy20(value); }
      }
      public Builder SetDummy20(int value) {
        result.hasDummy20 = true;
        result.dummy20_ = value;
        return this;
      }
      public Builder ClearDummy20() {
        result.hasDummy20 = false;
        result.dummy20_ = 0;
        return this;
      }
      
      public bool HasDummy21 {
        get { return result.HasDummy21; }
      }
      public int Dummy21 {
        get { return result.Dummy21; }
        set { SetDummy21(value); }
      }
      public Builder SetDummy21(int value) {
        result.hasDummy21 = true;
        result.dummy21_ = value;
        return this;
      }
      public Builder ClearDummy21() {
        result.hasDummy21 = false;
        result.dummy21_ = 0;
        return this;
      }
      
      public bool HasDummy22 {
        get { return result.HasDummy22; }
      }
      public int Dummy22 {
        get { return result.Dummy22; }
        set { SetDummy22(value); }
      }
      public Builder SetDummy22(int value) {
        result.hasDummy22 = true;
        result.dummy22_ = value;
        return this;
      }
      public Builder ClearDummy22() {
        result.hasDummy22 = false;
        result.dummy22_ = 0;
        return this;
      }
      
      public bool HasDummy23 {
        get { return result.HasDummy23; }
      }
      public int Dummy23 {
        get { return result.Dummy23; }
        set { SetDummy23(value); }
      }
      public Builder SetDummy23(int value) {
        result.hasDummy23 = true;
        result.dummy23_ = value;
        return this;
      }
      public Builder ClearDummy23() {
        result.hasDummy23 = false;
        result.dummy23_ = 0;
        return this;
      }
      
      public bool HasDummy24 {
        get { return result.HasDummy24; }
      }
      public int Dummy24 {
        get { return result.Dummy24; }
        set { SetDummy24(value); }
      }
      public Builder SetDummy24(int value) {
        result.hasDummy24 = true;
        result.dummy24_ = value;
        return this;
      }
      public Builder ClearDummy24() {
        result.hasDummy24 = false;
        result.dummy24_ = 0;
        return this;
      }
      
      public bool HasDummy25 {
        get { return result.HasDummy25; }
      }
      public int Dummy25 {
        get { return result.Dummy25; }
        set { SetDummy25(value); }
      }
      public Builder SetDummy25(int value) {
        result.hasDummy25 = true;
        result.dummy25_ = value;
        return this;
      }
      public Builder ClearDummy25() {
        result.hasDummy25 = false;
        result.dummy25_ = 0;
        return this;
      }
      
      public bool HasDummy26 {
        get { return result.HasDummy26; }
      }
      public int Dummy26 {
        get { return result.Dummy26; }
        set { SetDummy26(value); }
      }
      public Builder SetDummy26(int value) {
        result.hasDummy26 = true;
        result.dummy26_ = value;
        return this;
      }
      public Builder ClearDummy26() {
        result.hasDummy26 = false;
        result.dummy26_ = 0;
        return this;
      }
      
      public bool HasDummy27 {
        get { return result.HasDummy27; }
      }
      public int Dummy27 {
        get { return result.Dummy27; }
        set { SetDummy27(value); }
      }
      public Builder SetDummy27(int value) {
        result.hasDummy27 = true;
        result.dummy27_ = value;
        return this;
      }
      public Builder ClearDummy27() {
        result.hasDummy27 = false;
        result.dummy27_ = 0;
        return this;
      }
      
      public bool HasDummy28 {
        get { return result.HasDummy28; }
      }
      public int Dummy28 {
        get { return result.Dummy28; }
        set { SetDummy28(value); }
      }
      public Builder SetDummy28(int value) {
        result.hasDummy28 = true;
        result.dummy28_ = value;
        return this;
      }
      public Builder ClearDummy28() {
        result.hasDummy28 = false;
        result.dummy28_ = 0;
        return this;
      }
      
      public bool HasDummy29 {
        get { return result.HasDummy29; }
      }
      public int Dummy29 {
        get { return result.Dummy29; }
        set { SetDummy29(value); }
      }
      public Builder SetDummy29(int value) {
        result.hasDummy29 = true;
        result.dummy29_ = value;
        return this;
      }
      public Builder ClearDummy29() {
        result.hasDummy29 = false;
        result.dummy29_ = 0;
        return this;
      }
      
      public bool HasDummy30 {
        get { return result.HasDummy30; }
      }
      public int Dummy30 {
        get { return result.Dummy30; }
        set { SetDummy30(value); }
      }
      public Builder SetDummy30(int value) {
        result.hasDummy30 = true;
        result.dummy30_ = value;
        return this;
      }
      public Builder ClearDummy30() {
        result.hasDummy30 = false;
        result.dummy30_ = 0;
        return this;
      }
      
      public bool HasDummy31 {
        get { return result.HasDummy31; }
      }
      public int Dummy31 {
        get { return result.Dummy31; }
        set { SetDummy31(value); }
      }
      public Builder SetDummy31(int value) {
        result.hasDummy31 = true;
        result.dummy31_ = value;
        return this;
      }
      public Builder ClearDummy31() {
        result.hasDummy31 = false;
        result.dummy31_ = 0;
        return this;
      }
      
      public bool HasDummy32 {
        get { return result.HasDummy32; }
      }
      public int Dummy32 {
        get { return result.Dummy32; }
        set { SetDummy32(value); }
      }
      public Builder SetDummy32(int value) {
        result.hasDummy32 = true;
        result.dummy32_ = value;
        return this;
      }
      public Builder ClearDummy32() {
        result.hasDummy32 = false;
        result.dummy32_ = 0;
        return this;
      }
      
      public bool HasC {
        get { return result.HasC; }
      }
      public int C {
        get { return result.C; }
        set { SetC(value); }
      }
      public Builder SetC(int value) {
        result.hasC = true;
        result.c_ = value;
        return this;
      }
      public Builder ClearC() {
        result.hasC = false;
        result.c_ = 0;
        return this;
      }
    }
    static TestRequired() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 TestRequiredForeign : pb::GeneratedMessage<TestRequiredForeign, TestRequiredForeign.Builder> {
    private static readonly TestRequiredForeign defaultInstance = new Builder().BuildPartial();
    public static TestRequiredForeign DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestRequiredForeign DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestRequiredForeign ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestRequiredForeign__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestRequiredForeign, TestRequiredForeign.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestRequiredForeign__FieldAccessorTable; }
    }
    
    public const int OptionalMessageFieldNumber = 1;
    private bool hasOptionalMessage;
    private global::Google.ProtocolBuffers.TestProtos.TestRequired optionalMessage_ = global::Google.ProtocolBuffers.TestProtos.TestRequired.DefaultInstance;
    public bool HasOptionalMessage {
      get { return hasOptionalMessage; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestRequired OptionalMessage {
      get { return optionalMessage_; }
    }
    
    public const int RepeatedMessageFieldNumber = 2;
    private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestRequired> repeatedMessage_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestRequired>();
    public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestRequired> RepeatedMessageList {
      get { return repeatedMessage_; }
    }
    public int RepeatedMessageCount {
      get { return repeatedMessage_.Count; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestRequired GetRepeatedMessage(int index) {
      return repeatedMessage_[index];
    }
    
    public const int DummyFieldNumber = 3;
    private bool hasDummy;
    private int dummy_ = 0;
    public bool HasDummy {
      get { return hasDummy; }
    }
    public int Dummy {
      get { return dummy_; }
    }
    
    public override bool IsInitialized {
      get {
        if (HasOptionalMessage) {
          if (!OptionalMessage.IsInitialized) return false;
        }
        foreach (global::Google.ProtocolBuffers.TestProtos.TestRequired element in RepeatedMessageList) {
          if (!element.IsInitialized) return false;
        }
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (HasOptionalMessage) {
        output.WriteMessage(1, "optional_message", OptionalMessage);
      }
      if (repeatedMessage_.Count > 0) {
        output.WriteArray(pbd::FieldType.Message, 2, "repeated_message", repeatedMessage_);
      }
      if (HasDummy) {
        output.WriteInt32(3, "dummy", Dummy);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasOptionalMessage) {
          size += pb::CodedOutputStream.ComputeMessageSize(1, OptionalMessage);
        }
        foreach (global::Google.ProtocolBuffers.TestProtos.TestRequired element in RepeatedMessageList) {
          size += pb::CodedOutputStream.ComputeMessageSize(2, element);
        }
        if (HasDummy) {
          size += pb::CodedOutputStream.ComputeInt32Size(3, Dummy);
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static TestRequiredForeign ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestRequiredForeign ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestRequiredForeign ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestRequiredForeign ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestRequiredForeign ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestRequiredForeign ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestRequiredForeign ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestRequiredForeign ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestRequiredForeign ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestRequiredForeign 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(TestRequiredForeign 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<TestRequiredForeign, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestRequiredForeign result = new TestRequiredForeign();
      
      protected override TestRequiredForeign MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestRequiredForeign();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestRequiredForeign.Descriptor; }
      }
      
      public override TestRequiredForeign DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestRequiredForeign.DefaultInstance; }
      }
      
      public override TestRequiredForeign BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        result.repeatedMessage_.MakeReadOnly();
        TestRequiredForeign returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestRequiredForeign) {
          return MergeFrom((TestRequiredForeign) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestRequiredForeign other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestRequiredForeign.DefaultInstance) return this;
        if (other.HasOptionalMessage) {
          MergeOptionalMessage(other.OptionalMessage);
        }
        if (other.repeatedMessage_.Count != 0) {
          base.AddRange(other.repeatedMessage_, result.repeatedMessage_);
        }
        if (other.HasDummy) {
          Dummy = other.Dummy;
        }
        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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
            case 10: {
              global::Google.ProtocolBuffers.TestProtos.TestRequired.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestRequired.CreateBuilder();
              if (HasOptionalMessage) {
                subBuilder.MergeFrom(OptionalMessage);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              OptionalMessage = subBuilder.BuildPartial();
              break;
            }
            case 18: {
              input.ReadMessageArray(tag, field_name, result.repeatedMessage_, global::Google.ProtocolBuffers.TestProtos.TestRequired.DefaultInstance, extensionRegistry);
              break;
            }
            case 24: {
              result.hasDummy |= input.ReadInt32(ref result.dummy_);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      public bool HasOptionalMessage {
       get { return result.HasOptionalMessage; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestRequired OptionalMessage {
        get { return result.OptionalMessage; }
        set { SetOptionalMessage(value); }
      }
      public Builder SetOptionalMessage(global::Google.ProtocolBuffers.TestProtos.TestRequired value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasOptionalMessage = true;
        result.optionalMessage_ = value;
        return this;
      }
      public Builder SetOptionalMessage(global::Google.ProtocolBuffers.TestProtos.TestRequired.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.hasOptionalMessage = true;
        result.optionalMessage_ = builderForValue.Build();
        return this;
      }
      public Builder MergeOptionalMessage(global::Google.ProtocolBuffers.TestProtos.TestRequired value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        if (result.HasOptionalMessage &&
            result.optionalMessage_ != global::Google.ProtocolBuffers.TestProtos.TestRequired.DefaultInstance) {
            result.optionalMessage_ = global::Google.ProtocolBuffers.TestProtos.TestRequired.CreateBuilder(result.optionalMessage_).MergeFrom(value).BuildPartial();
        } else {
          result.optionalMessage_ = value;
        }
        result.hasOptionalMessage = true;
        return this;
      }
      public Builder ClearOptionalMessage() {
        result.hasOptionalMessage = false;
        result.optionalMessage_ = global::Google.ProtocolBuffers.TestProtos.TestRequired.DefaultInstance;
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestRequired> RepeatedMessageList {
        get { return result.repeatedMessage_; }
      }
      public int RepeatedMessageCount {
        get { return result.RepeatedMessageCount; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestRequired GetRepeatedMessage(int index) {
        return result.GetRepeatedMessage(index);
      }
      public Builder SetRepeatedMessage(int index, global::Google.ProtocolBuffers.TestProtos.TestRequired value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedMessage_[index] = value;
        return this;
      }
      public Builder SetRepeatedMessage(int index, global::Google.ProtocolBuffers.TestProtos.TestRequired.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.repeatedMessage_[index] = builderForValue.Build();
        return this;
      }
      public Builder AddRepeatedMessage(global::Google.ProtocolBuffers.TestProtos.TestRequired value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedMessage_.Add(value);
        return this;
      }
      public Builder AddRepeatedMessage(global::Google.ProtocolBuffers.TestProtos.TestRequired.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.repeatedMessage_.Add(builderForValue.Build());
        return this;
      }
      public Builder AddRangeRepeatedMessage(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestRequired> values) {
        base.AddRange(values, result.repeatedMessage_);
        return this;
      }
      public Builder ClearRepeatedMessage() {
        result.repeatedMessage_.Clear();
        return this;
      }
      
      public bool HasDummy {
        get { return result.HasDummy; }
      }
      public int Dummy {
        get { return result.Dummy; }
        set { SetDummy(value); }
      }
      public Builder SetDummy(int value) {
        result.hasDummy = true;
        result.dummy_ = value;
        return this;
      }
      public Builder ClearDummy() {
        result.hasDummy = false;
        result.dummy_ = 0;
        return this;
      }
    }
    static TestRequiredForeign() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 TestForeignNested : pb::GeneratedMessage<TestForeignNested, TestForeignNested.Builder> {
    private static readonly TestForeignNested defaultInstance = new Builder().BuildPartial();
    public static TestForeignNested DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestForeignNested DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestForeignNested ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestForeignNested__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestForeignNested, TestForeignNested.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestForeignNested__FieldAccessorTable; }
    }
    
    public const int ForeignNestedFieldNumber = 1;
    private bool hasForeignNested;
    private global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage foreignNested_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.DefaultInstance;
    public bool HasForeignNested {
      get { return hasForeignNested; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage ForeignNested {
      get { return foreignNested_; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (HasForeignNested) {
        output.WriteMessage(1, "foreign_nested", ForeignNested);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasForeignNested) {
          size += pb::CodedOutputStream.ComputeMessageSize(1, ForeignNested);
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static TestForeignNested ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestForeignNested ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestForeignNested ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestForeignNested ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestForeignNested ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestForeignNested ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestForeignNested ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestForeignNested ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestForeignNested ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestForeignNested 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(TestForeignNested 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<TestForeignNested, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestForeignNested result = new TestForeignNested();
      
      protected override TestForeignNested MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestForeignNested();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestForeignNested.Descriptor; }
      }
      
      public override TestForeignNested DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestForeignNested.DefaultInstance; }
      }
      
      public override TestForeignNested BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        TestForeignNested returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestForeignNested) {
          return MergeFrom((TestForeignNested) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestForeignNested other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestForeignNested.DefaultInstance) return this;
        if (other.HasForeignNested) {
          MergeForeignNested(other.ForeignNested);
        }
        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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
            case 10: {
              global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.CreateBuilder();
              if (HasForeignNested) {
                subBuilder.MergeFrom(ForeignNested);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              ForeignNested = subBuilder.BuildPartial();
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      public bool HasForeignNested {
       get { return result.HasForeignNested; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage ForeignNested {
        get { return result.ForeignNested; }
        set { SetForeignNested(value); }
      }
      public Builder SetForeignNested(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasForeignNested = true;
        result.foreignNested_ = value;
        return this;
      }
      public Builder SetForeignNested(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.hasForeignNested = true;
        result.foreignNested_ = builderForValue.Build();
        return this;
      }
      public Builder MergeForeignNested(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        if (result.HasForeignNested &&
            result.foreignNested_ != global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.DefaultInstance) {
            result.foreignNested_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.CreateBuilder(result.foreignNested_).MergeFrom(value).BuildPartial();
        } else {
          result.foreignNested_ = value;
        }
        result.hasForeignNested = true;
        return this;
      }
      public Builder ClearForeignNested() {
        result.hasForeignNested = false;
        result.foreignNested_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.DefaultInstance;
        return this;
      }
    }
    static TestForeignNested() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 TestEmptyMessage : pb::GeneratedMessage<TestEmptyMessage, TestEmptyMessage.Builder> {
    private static readonly TestEmptyMessage defaultInstance = new Builder().BuildPartial();
    public static TestEmptyMessage DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestEmptyMessage DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestEmptyMessage ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestEmptyMessage__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestEmptyMessage, TestEmptyMessage.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestEmptyMessage__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 TestEmptyMessage ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestEmptyMessage ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestEmptyMessage ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestEmptyMessage ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestEmptyMessage ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestEmptyMessage ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestEmptyMessage ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestEmptyMessage ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestEmptyMessage ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestEmptyMessage 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(TestEmptyMessage 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<TestEmptyMessage, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestEmptyMessage result = new TestEmptyMessage();
      
      protected override TestEmptyMessage MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestEmptyMessage();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestEmptyMessage.Descriptor; }
      }
      
      public override TestEmptyMessage DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestEmptyMessage.DefaultInstance; }
      }
      
      public override TestEmptyMessage BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        TestEmptyMessage returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestEmptyMessage) {
          return MergeFrom((TestEmptyMessage) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestEmptyMessage other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestEmptyMessage.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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
    }
    static TestEmptyMessage() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 TestEmptyMessageWithExtensions : pb::ExtendableMessage<TestEmptyMessageWithExtensions, TestEmptyMessageWithExtensions.Builder> {
    private static readonly TestEmptyMessageWithExtensions defaultInstance = new Builder().BuildPartial();
    public static TestEmptyMessageWithExtensions DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestEmptyMessageWithExtensions DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestEmptyMessageWithExtensions ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestEmptyMessageWithExtensions__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestEmptyMessageWithExtensions, TestEmptyMessageWithExtensions.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestEmptyMessageWithExtensions__FieldAccessorTable; }
    }
    
    public override bool IsInitialized {
      get {
        if (!ExtensionsAreInitialized) return false;
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      pb::ExtendableMessage<TestEmptyMessageWithExtensions, TestEmptyMessageWithExtensions.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
      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;
        size += ExtensionsSerializedSize;
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static TestEmptyMessageWithExtensions ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestEmptyMessageWithExtensions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestEmptyMessageWithExtensions ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestEmptyMessageWithExtensions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestEmptyMessageWithExtensions ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestEmptyMessageWithExtensions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestEmptyMessageWithExtensions ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestEmptyMessageWithExtensions ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestEmptyMessageWithExtensions ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestEmptyMessageWithExtensions 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(TestEmptyMessageWithExtensions 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<TestEmptyMessageWithExtensions, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestEmptyMessageWithExtensions result = new TestEmptyMessageWithExtensions();
      
      protected override TestEmptyMessageWithExtensions MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestEmptyMessageWithExtensions();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestEmptyMessageWithExtensions.Descriptor; }
      }
      
      public override TestEmptyMessageWithExtensions DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestEmptyMessageWithExtensions.DefaultInstance; }
      }
      
      public override TestEmptyMessageWithExtensions BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        TestEmptyMessageWithExtensions returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestEmptyMessageWithExtensions) {
          return MergeFrom((TestEmptyMessageWithExtensions) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestEmptyMessageWithExtensions other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestEmptyMessageWithExtensions.DefaultInstance) return this;
          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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
    }
    static TestEmptyMessageWithExtensions() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 TestMultipleExtensionRanges : pb::ExtendableMessage<TestMultipleExtensionRanges, TestMultipleExtensionRanges.Builder> {
    private static readonly TestMultipleExtensionRanges defaultInstance = new Builder().BuildPartial();
    public static TestMultipleExtensionRanges DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestMultipleExtensionRanges DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestMultipleExtensionRanges ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestMultipleExtensionRanges__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestMultipleExtensionRanges, TestMultipleExtensionRanges.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestMultipleExtensionRanges__FieldAccessorTable; }
    }
    
    public override bool IsInitialized {
      get {
        if (!ExtensionsAreInitialized) return false;
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      pb::ExtendableMessage<TestMultipleExtensionRanges, TestMultipleExtensionRanges.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
      extensionWriter.WriteUntil(43, output);
      extensionWriter.WriteUntil(4244, output);
      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;
        size += ExtensionsSerializedSize;
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static TestMultipleExtensionRanges ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestMultipleExtensionRanges ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestMultipleExtensionRanges ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestMultipleExtensionRanges ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestMultipleExtensionRanges ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestMultipleExtensionRanges ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestMultipleExtensionRanges ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestMultipleExtensionRanges ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestMultipleExtensionRanges ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestMultipleExtensionRanges 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(TestMultipleExtensionRanges 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<TestMultipleExtensionRanges, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestMultipleExtensionRanges result = new TestMultipleExtensionRanges();
      
      protected override TestMultipleExtensionRanges MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestMultipleExtensionRanges();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestMultipleExtensionRanges.Descriptor; }
      }
      
      public override TestMultipleExtensionRanges DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestMultipleExtensionRanges.DefaultInstance; }
      }
      
      public override TestMultipleExtensionRanges BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        TestMultipleExtensionRanges returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestMultipleExtensionRanges) {
          return MergeFrom((TestMultipleExtensionRanges) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestMultipleExtensionRanges other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestMultipleExtensionRanges.DefaultInstance) return this;
          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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
    }
    static TestMultipleExtensionRanges() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 TestReallyLargeTagNumber : pb::GeneratedMessage<TestReallyLargeTagNumber, TestReallyLargeTagNumber.Builder> {
    private static readonly TestReallyLargeTagNumber defaultInstance = new Builder().BuildPartial();
    public static TestReallyLargeTagNumber DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestReallyLargeTagNumber DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestReallyLargeTagNumber ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestReallyLargeTagNumber__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestReallyLargeTagNumber, TestReallyLargeTagNumber.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestReallyLargeTagNumber__FieldAccessorTable; }
    }
    
    public const int AFieldNumber = 1;
    private bool hasA;
    private int a_ = 0;
    public bool HasA {
      get { return hasA; }
    }
    public int A {
      get { return a_; }
    }
    
    public const int BbFieldNumber = 268435455;
    private bool hasBb;
    private int bb_ = 0;
    public bool HasBb {
      get { return hasBb; }
    }
    public int Bb {
      get { return bb_; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (HasA) {
        output.WriteInt32(1, "a", A);
      }
      if (HasBb) {
        output.WriteInt32(268435455, "bb", Bb);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasA) {
          size += pb::CodedOutputStream.ComputeInt32Size(1, A);
        }
        if (HasBb) {
          size += pb::CodedOutputStream.ComputeInt32Size(268435455, Bb);
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static TestReallyLargeTagNumber ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestReallyLargeTagNumber ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestReallyLargeTagNumber ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestReallyLargeTagNumber ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestReallyLargeTagNumber ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestReallyLargeTagNumber ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestReallyLargeTagNumber ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestReallyLargeTagNumber ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestReallyLargeTagNumber ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestReallyLargeTagNumber 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(TestReallyLargeTagNumber 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<TestReallyLargeTagNumber, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestReallyLargeTagNumber result = new TestReallyLargeTagNumber();
      
      protected override TestReallyLargeTagNumber MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestReallyLargeTagNumber();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestReallyLargeTagNumber.Descriptor; }
      }
      
      public override TestReallyLargeTagNumber DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestReallyLargeTagNumber.DefaultInstance; }
      }
      
      public override TestReallyLargeTagNumber BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        TestReallyLargeTagNumber returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestReallyLargeTagNumber) {
          return MergeFrom((TestReallyLargeTagNumber) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestReallyLargeTagNumber other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestReallyLargeTagNumber.DefaultInstance) return this;
        if (other.HasA) {
          A = other.A;
        }
        if (other.HasBb) {
          Bb = other.Bb;
        }
        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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
            case 8: {
              result.hasA |= input.ReadInt32(ref result.a_);
              break;
            }
            case 2147483640: {
              result.hasBb |= input.ReadInt32(ref result.bb_);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      public bool HasA {
        get { return result.HasA; }
      }
      public int A {
        get { return result.A; }
        set { SetA(value); }
      }
      public Builder SetA(int value) {
        result.hasA = true;
        result.a_ = value;
        return this;
      }
      public Builder ClearA() {
        result.hasA = false;
        result.a_ = 0;
        return this;
      }
      
      public bool HasBb {
        get { return result.HasBb; }
      }
      public int Bb {
        get { return result.Bb; }
        set { SetBb(value); }
      }
      public Builder SetBb(int value) {
        result.hasBb = true;
        result.bb_ = value;
        return this;
      }
      public Builder ClearBb() {
        result.hasBb = false;
        result.bb_ = 0;
        return this;
      }
    }
    static TestReallyLargeTagNumber() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 TestRecursiveMessage : pb::GeneratedMessage<TestRecursiveMessage, TestRecursiveMessage.Builder> {
    private static readonly TestRecursiveMessage defaultInstance = new Builder().BuildPartial();
    public static TestRecursiveMessage DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestRecursiveMessage DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestRecursiveMessage ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestRecursiveMessage__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestRecursiveMessage, TestRecursiveMessage.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestRecursiveMessage__FieldAccessorTable; }
    }
    
    public const int AFieldNumber = 1;
    private bool hasA;
    private global::Google.ProtocolBuffers.TestProtos.TestRecursiveMessage a_ = global::Google.ProtocolBuffers.TestProtos.TestRecursiveMessage.DefaultInstance;
    public bool HasA {
      get { return hasA; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestRecursiveMessage A {
      get { return a_; }
    }
    
    public const int IFieldNumber = 2;
    private bool hasI;
    private int i_ = 0;
    public bool HasI {
      get { return hasI; }
    }
    public int I {
      get { return i_; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (HasA) {
        output.WriteMessage(1, "a", A);
      }
      if (HasI) {
        output.WriteInt32(2, "i", I);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasA) {
          size += pb::CodedOutputStream.ComputeMessageSize(1, A);
        }
        if (HasI) {
          size += pb::CodedOutputStream.ComputeInt32Size(2, I);
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static TestRecursiveMessage ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestRecursiveMessage ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestRecursiveMessage ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestRecursiveMessage ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestRecursiveMessage ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestRecursiveMessage ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestRecursiveMessage ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestRecursiveMessage ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestRecursiveMessage ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestRecursiveMessage 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(TestRecursiveMessage 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<TestRecursiveMessage, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestRecursiveMessage result = new TestRecursiveMessage();
      
      protected override TestRecursiveMessage MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestRecursiveMessage();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestRecursiveMessage.Descriptor; }
      }
      
      public override TestRecursiveMessage DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestRecursiveMessage.DefaultInstance; }
      }
      
      public override TestRecursiveMessage BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        TestRecursiveMessage returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestRecursiveMessage) {
          return MergeFrom((TestRecursiveMessage) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestRecursiveMessage other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestRecursiveMessage.DefaultInstance) return this;
        if (other.HasA) {
          MergeA(other.A);
        }
        if (other.HasI) {
          I = other.I;
        }
        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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
            case 10: {
              global::Google.ProtocolBuffers.TestProtos.TestRecursiveMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestRecursiveMessage.CreateBuilder();
              if (HasA) {
                subBuilder.MergeFrom(A);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              A = subBuilder.BuildPartial();
              break;
            }
            case 16: {
              result.hasI |= input.ReadInt32(ref result.i_);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      public bool HasA {
       get { return result.HasA; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestRecursiveMessage A {
        get { return result.A; }
        set { SetA(value); }
      }
      public Builder SetA(global::Google.ProtocolBuffers.TestProtos.TestRecursiveMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasA = true;
        result.a_ = value;
        return this;
      }
      public Builder SetA(global::Google.ProtocolBuffers.TestProtos.TestRecursiveMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.hasA = true;
        result.a_ = builderForValue.Build();
        return this;
      }
      public Builder MergeA(global::Google.ProtocolBuffers.TestProtos.TestRecursiveMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        if (result.HasA &&
            result.a_ != global::Google.ProtocolBuffers.TestProtos.TestRecursiveMessage.DefaultInstance) {
            result.a_ = global::Google.ProtocolBuffers.TestProtos.TestRecursiveMessage.CreateBuilder(result.a_).MergeFrom(value).BuildPartial();
        } else {
          result.a_ = value;
        }
        result.hasA = true;
        return this;
      }
      public Builder ClearA() {
        result.hasA = false;
        result.a_ = global::Google.ProtocolBuffers.TestProtos.TestRecursiveMessage.DefaultInstance;
        return this;
      }
      
      public bool HasI {
        get { return result.HasI; }
      }
      public int I {
        get { return result.I; }
        set { SetI(value); }
      }
      public Builder SetI(int value) {
        result.hasI = true;
        result.i_ = value;
        return this;
      }
      public Builder ClearI() {
        result.hasI = false;
        result.i_ = 0;
        return this;
      }
    }
    static TestRecursiveMessage() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 TestMutualRecursionA : pb::GeneratedMessage<TestMutualRecursionA, TestMutualRecursionA.Builder> {
    private static readonly TestMutualRecursionA defaultInstance = new Builder().BuildPartial();
    public static TestMutualRecursionA DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestMutualRecursionA DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestMutualRecursionA ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestMutualRecursionA__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestMutualRecursionA, TestMutualRecursionA.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestMutualRecursionA__FieldAccessorTable; }
    }
    
    public const int BbFieldNumber = 1;
    private bool hasBb;
    private global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionB bb_ = global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionB.DefaultInstance;
    public bool HasBb {
      get { return hasBb; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionB Bb {
      get { return bb_; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (HasBb) {
        output.WriteMessage(1, "bb", Bb);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasBb) {
          size += pb::CodedOutputStream.ComputeMessageSize(1, Bb);
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static TestMutualRecursionA ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestMutualRecursionA ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestMutualRecursionA ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestMutualRecursionA ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestMutualRecursionA ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestMutualRecursionA ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestMutualRecursionA ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestMutualRecursionA ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestMutualRecursionA ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestMutualRecursionA 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(TestMutualRecursionA 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<TestMutualRecursionA, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestMutualRecursionA result = new TestMutualRecursionA();
      
      protected override TestMutualRecursionA MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestMutualRecursionA();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionA.Descriptor; }
      }
      
      public override TestMutualRecursionA DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionA.DefaultInstance; }
      }
      
      public override TestMutualRecursionA BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        TestMutualRecursionA returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestMutualRecursionA) {
          return MergeFrom((TestMutualRecursionA) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestMutualRecursionA other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionA.DefaultInstance) return this;
        if (other.HasBb) {
          MergeBb(other.Bb);
        }
        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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
            case 10: {
              global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionB.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionB.CreateBuilder();
              if (HasBb) {
                subBuilder.MergeFrom(Bb);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              Bb = subBuilder.BuildPartial();
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      public bool HasBb {
       get { return result.HasBb; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionB Bb {
        get { return result.Bb; }
        set { SetBb(value); }
      }
      public Builder SetBb(global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionB value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasBb = true;
        result.bb_ = value;
        return this;
      }
      public Builder SetBb(global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionB.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.hasBb = true;
        result.bb_ = builderForValue.Build();
        return this;
      }
      public Builder MergeBb(global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionB value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        if (result.HasBb &&
            result.bb_ != global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionB.DefaultInstance) {
            result.bb_ = global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionB.CreateBuilder(result.bb_).MergeFrom(value).BuildPartial();
        } else {
          result.bb_ = value;
        }
        result.hasBb = true;
        return this;
      }
      public Builder ClearBb() {
        result.hasBb = false;
        result.bb_ = global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionB.DefaultInstance;
        return this;
      }
    }
    static TestMutualRecursionA() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 TestMutualRecursionB : pb::GeneratedMessage<TestMutualRecursionB, TestMutualRecursionB.Builder> {
    private static readonly TestMutualRecursionB defaultInstance = new Builder().BuildPartial();
    public static TestMutualRecursionB DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestMutualRecursionB DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestMutualRecursionB ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestMutualRecursionB__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestMutualRecursionB, TestMutualRecursionB.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestMutualRecursionB__FieldAccessorTable; }
    }
    
    public const int AFieldNumber = 1;
    private bool hasA;
    private global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionA a_ = global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionA.DefaultInstance;
    public bool HasA {
      get { return hasA; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionA A {
      get { return a_; }
    }
    
    public const int OptionalInt32FieldNumber = 2;
    private bool hasOptionalInt32;
    private int optionalInt32_ = 0;
    public bool HasOptionalInt32 {
      get { return hasOptionalInt32; }
    }
    public int OptionalInt32 {
      get { return optionalInt32_; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (HasA) {
        output.WriteMessage(1, "a", A);
      }
      if (HasOptionalInt32) {
        output.WriteInt32(2, "optional_int32", OptionalInt32);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasA) {
          size += pb::CodedOutputStream.ComputeMessageSize(1, A);
        }
        if (HasOptionalInt32) {
          size += pb::CodedOutputStream.ComputeInt32Size(2, OptionalInt32);
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static TestMutualRecursionB ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestMutualRecursionB ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestMutualRecursionB ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestMutualRecursionB ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestMutualRecursionB ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestMutualRecursionB ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestMutualRecursionB ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestMutualRecursionB ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestMutualRecursionB ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestMutualRecursionB 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(TestMutualRecursionB 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<TestMutualRecursionB, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestMutualRecursionB result = new TestMutualRecursionB();
      
      protected override TestMutualRecursionB MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestMutualRecursionB();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionB.Descriptor; }
      }
      
      public override TestMutualRecursionB DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionB.DefaultInstance; }
      }
      
      public override TestMutualRecursionB BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        TestMutualRecursionB returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestMutualRecursionB) {
          return MergeFrom((TestMutualRecursionB) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestMutualRecursionB other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionB.DefaultInstance) return this;
        if (other.HasA) {
          MergeA(other.A);
        }
        if (other.HasOptionalInt32) {
          OptionalInt32 = other.OptionalInt32;
        }
        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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
            case 10: {
              global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionA.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionA.CreateBuilder();
              if (HasA) {
                subBuilder.MergeFrom(A);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              A = subBuilder.BuildPartial();
              break;
            }
            case 16: {
              result.hasOptionalInt32 |= input.ReadInt32(ref result.optionalInt32_);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      public bool HasA {
       get { return result.HasA; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionA A {
        get { return result.A; }
        set { SetA(value); }
      }
      public Builder SetA(global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionA value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasA = true;
        result.a_ = value;
        return this;
      }
      public Builder SetA(global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionA.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.hasA = true;
        result.a_ = builderForValue.Build();
        return this;
      }
      public Builder MergeA(global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionA value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        if (result.HasA &&
            result.a_ != global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionA.DefaultInstance) {
            result.a_ = global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionA.CreateBuilder(result.a_).MergeFrom(value).BuildPartial();
        } else {
          result.a_ = value;
        }
        result.hasA = true;
        return this;
      }
      public Builder ClearA() {
        result.hasA = false;
        result.a_ = global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionA.DefaultInstance;
        return this;
      }
      
      public bool HasOptionalInt32 {
        get { return result.HasOptionalInt32; }
      }
      public int OptionalInt32 {
        get { return result.OptionalInt32; }
        set { SetOptionalInt32(value); }
      }
      public Builder SetOptionalInt32(int value) {
        result.hasOptionalInt32 = true;
        result.optionalInt32_ = value;
        return this;
      }
      public Builder ClearOptionalInt32() {
        result.hasOptionalInt32 = false;
        result.optionalInt32_ = 0;
        return this;
      }
    }
    static TestMutualRecursionB() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 TestDupFieldNumber : pb::GeneratedMessage<TestDupFieldNumber, TestDupFieldNumber.Builder> {
    private static readonly TestDupFieldNumber defaultInstance = new Builder().BuildPartial();
    public static TestDupFieldNumber DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestDupFieldNumber DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestDupFieldNumber ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestDupFieldNumber__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestDupFieldNumber, TestDupFieldNumber.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestDupFieldNumber__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 Foo : pb::GeneratedMessage<Foo, Foo.Builder> {
        private static readonly Foo defaultInstance = new Builder().BuildPartial();
        public static Foo DefaultInstance {
          get { return defaultInstance; }
        }
        
        public override Foo DefaultInstanceForType {
          get { return defaultInstance; }
        }
        
        protected override Foo ThisMessage {
          get { return this; }
        }
        
        public static pbd::MessageDescriptor Descriptor {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestDupFieldNumber_Foo__Descriptor; }
        }
        
        protected override pb::FieldAccess.FieldAccessorTable<Foo, Foo.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestDupFieldNumber_Foo__FieldAccessorTable; }
        }
        
        public const int AFieldNumber = 1;
        private bool hasA;
        private int a_ = 0;
        public bool HasA {
          get { return hasA; }
        }
        public int A {
          get { return a_; }
        }
        
        public override bool IsInitialized {
          get {
            return true;
          }
        }
        
        public override void WriteTo(pb::ICodedOutputStream output) {
          int size = SerializedSize;
          if (HasA) {
            output.WriteInt32(1, "a", A);
          }
          UnknownFields.WriteTo(output);
        }
        
        private int memoizedSerializedSize = -1;
        public override int SerializedSize {
          get {
            int size = memoizedSerializedSize;
            if (size != -1) return size;
            
            size = 0;
            if (HasA) {
              size += pb::CodedOutputStream.ComputeInt32Size(1, A);
            }
            size += UnknownFields.SerializedSize;
            memoizedSerializedSize = size;
            return size;
          }
        }
        
        public static Foo ParseFrom(pb::ByteString data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static Foo ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static Foo ParseFrom(byte[] data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static Foo ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static Foo ParseFrom(global::System.IO.Stream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static Foo ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static Foo ParseDelimitedFrom(global::System.IO.Stream input) {
          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
        }
        public static Foo ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
        }
        public static Foo ParseFrom(pb::CodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static Foo 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(Foo 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<Foo, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {}
          
          Foo result = new Foo();
          
          protected override Foo MessageBeingBuilt {
            get { return result; }
          }
          
          public override Builder Clear() {
            result = new Foo();
            return this;
          }
          
          public override Builder Clone() {
            return new Builder().MergeFrom(result);
          }
          
          public override pbd::MessageDescriptor DescriptorForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Foo.Descriptor; }
          }
          
          public override Foo DefaultInstanceForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Foo.DefaultInstance; }
          }
          
          public override Foo BuildPartial() {
            if (result == null) {
              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
            }
            Foo returnMe = result;
            result = null;
            return returnMe;
          }
          
          public override Builder MergeFrom(pb::IMessage other) {
            if (other is Foo) {
              return MergeFrom((Foo) other);
            } else {
              base.MergeFrom(other);
              return this;
            }
          }
          
          public override Builder MergeFrom(Foo other) {
            if (other == global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Foo.DefaultInstance) return this;
            if (other.HasA) {
              A = other.A;
            }
            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;
            uint tag;
            string field_name;
            while (input.ReadTag(out tag, out field_name)) {
              switch (tag) {
                case 0: {
                  throw pb::InvalidProtocolBufferException.InvalidTag();
                }
                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, field_name);
                  break;
                }
                case 8: {
                  result.hasA |= input.ReadInt32(ref result.a_);
                  break;
                }
              }
            }
            
            if (unknownFields != null) {
              this.UnknownFields = unknownFields.Build();
            }
            return this;
          }
          
          
          public bool HasA {
            get { return result.HasA; }
          }
          public int A {
            get { return result.A; }
            set { SetA(value); }
          }
          public Builder SetA(int value) {
            result.hasA = true;
            result.a_ = value;
            return this;
          }
          public Builder ClearA() {
            result.hasA = false;
            result.a_ = 0;
            return this;
          }
        }
        static Foo() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 Bar : pb::GeneratedMessage<Bar, Bar.Builder> {
        private static readonly Bar defaultInstance = new Builder().BuildPartial();
        public static Bar DefaultInstance {
          get { return defaultInstance; }
        }
        
        public override Bar DefaultInstanceForType {
          get { return defaultInstance; }
        }
        
        protected override Bar ThisMessage {
          get { return this; }
        }
        
        public static pbd::MessageDescriptor Descriptor {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestDupFieldNumber_Bar__Descriptor; }
        }
        
        protected override pb::FieldAccess.FieldAccessorTable<Bar, Bar.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestDupFieldNumber_Bar__FieldAccessorTable; }
        }
        
        public const int AFieldNumber = 1;
        private bool hasA;
        private int a_ = 0;
        public bool HasA {
          get { return hasA; }
        }
        public int A {
          get { return a_; }
        }
        
        public override bool IsInitialized {
          get {
            return true;
          }
        }
        
        public override void WriteTo(pb::ICodedOutputStream output) {
          int size = SerializedSize;
          if (HasA) {
            output.WriteInt32(1, "a", A);
          }
          UnknownFields.WriteTo(output);
        }
        
        private int memoizedSerializedSize = -1;
        public override int SerializedSize {
          get {
            int size = memoizedSerializedSize;
            if (size != -1) return size;
            
            size = 0;
            if (HasA) {
              size += pb::CodedOutputStream.ComputeInt32Size(1, A);
            }
            size += UnknownFields.SerializedSize;
            memoizedSerializedSize = size;
            return size;
          }
        }
        
        public static Bar ParseFrom(pb::ByteString data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static Bar ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static Bar ParseFrom(byte[] data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static Bar ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static Bar ParseFrom(global::System.IO.Stream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static Bar ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static Bar ParseDelimitedFrom(global::System.IO.Stream input) {
          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
        }
        public static Bar ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
        }
        public static Bar ParseFrom(pb::CodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static Bar 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(Bar 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<Bar, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {}
          
          Bar result = new Bar();
          
          protected override Bar MessageBeingBuilt {
            get { return result; }
          }
          
          public override Builder Clear() {
            result = new Bar();
            return this;
          }
          
          public override Builder Clone() {
            return new Builder().MergeFrom(result);
          }
          
          public override pbd::MessageDescriptor DescriptorForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Bar.Descriptor; }
          }
          
          public override Bar DefaultInstanceForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Bar.DefaultInstance; }
          }
          
          public override Bar BuildPartial() {
            if (result == null) {
              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
            }
            Bar returnMe = result;
            result = null;
            return returnMe;
          }
          
          public override Builder MergeFrom(pb::IMessage other) {
            if (other is Bar) {
              return MergeFrom((Bar) other);
            } else {
              base.MergeFrom(other);
              return this;
            }
          }
          
          public override Builder MergeFrom(Bar other) {
            if (other == global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Bar.DefaultInstance) return this;
            if (other.HasA) {
              A = other.A;
            }
            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;
            uint tag;
            string field_name;
            while (input.ReadTag(out tag, out field_name)) {
              switch (tag) {
                case 0: {
                  throw pb::InvalidProtocolBufferException.InvalidTag();
                }
                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, field_name);
                  break;
                }
                case 8: {
                  result.hasA |= input.ReadInt32(ref result.a_);
                  break;
                }
              }
            }
            
            if (unknownFields != null) {
              this.UnknownFields = unknownFields.Build();
            }
            return this;
          }
          
          
          public bool HasA {
            get { return result.HasA; }
          }
          public int A {
            get { return result.A; }
            set { SetA(value); }
          }
          public Builder SetA(int value) {
            result.hasA = true;
            result.a_ = value;
            return this;
          }
          public Builder ClearA() {
            result.hasA = false;
            result.a_ = 0;
            return this;
          }
        }
        static Bar() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
        }
      }
      
    }
    #endregion
    
    public const int AFieldNumber = 1;
    private bool hasA;
    private int a_ = 0;
    public bool HasA {
      get { return hasA; }
    }
    public int A {
      get { return a_; }
    }
    
    public const int FooFieldNumber = 2;
    private bool hasFoo;
    private global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Foo foo_ = global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Foo.DefaultInstance;
    public bool HasFoo {
      get { return hasFoo; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Foo Foo {
      get { return foo_; }
    }
    
    public const int BarFieldNumber = 3;
    private bool hasBar;
    private global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Bar bar_ = global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Bar.DefaultInstance;
    public bool HasBar {
      get { return hasBar; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Bar Bar {
      get { return bar_; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (HasA) {
        output.WriteInt32(1, "a", A);
      }
      if (HasFoo) {
        output.WriteGroup(2, "foo", Foo);
      }
      if (HasBar) {
        output.WriteGroup(3, "bar", Bar);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasA) {
          size += pb::CodedOutputStream.ComputeInt32Size(1, A);
        }
        if (HasFoo) {
          size += pb::CodedOutputStream.ComputeGroupSize(2, Foo);
        }
        if (HasBar) {
          size += pb::CodedOutputStream.ComputeGroupSize(3, Bar);
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static TestDupFieldNumber ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestDupFieldNumber ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestDupFieldNumber ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestDupFieldNumber ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestDupFieldNumber ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestDupFieldNumber ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestDupFieldNumber ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestDupFieldNumber ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestDupFieldNumber ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestDupFieldNumber 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(TestDupFieldNumber 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<TestDupFieldNumber, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestDupFieldNumber result = new TestDupFieldNumber();
      
      protected override TestDupFieldNumber MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestDupFieldNumber();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Descriptor; }
      }
      
      public override TestDupFieldNumber DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.DefaultInstance; }
      }
      
      public override TestDupFieldNumber BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        TestDupFieldNumber returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestDupFieldNumber) {
          return MergeFrom((TestDupFieldNumber) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestDupFieldNumber other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.DefaultInstance) return this;
        if (other.HasA) {
          A = other.A;
        }
        if (other.HasFoo) {
          MergeFoo(other.Foo);
        }
        if (other.HasBar) {
          MergeBar(other.Bar);
        }
        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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
            case 8: {
              result.hasA |= input.ReadInt32(ref result.a_);
              break;
            }
            case 19: {
              global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Foo.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Foo.CreateBuilder();
              if (HasFoo) {
                subBuilder.MergeFrom(Foo);
              }
              input.ReadGroup(2, subBuilder, extensionRegistry);
              Foo = subBuilder.BuildPartial();
              break;
            }
            case 27: {
              global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Bar.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Bar.CreateBuilder();
              if (HasBar) {
                subBuilder.MergeFrom(Bar);
              }
              input.ReadGroup(3, subBuilder, extensionRegistry);
              Bar = subBuilder.BuildPartial();
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      public bool HasA {
        get { return result.HasA; }
      }
      public int A {
        get { return result.A; }
        set { SetA(value); }
      }
      public Builder SetA(int value) {
        result.hasA = true;
        result.a_ = value;
        return this;
      }
      public Builder ClearA() {
        result.hasA = false;
        result.a_ = 0;
        return this;
      }
      
      public bool HasFoo {
       get { return result.HasFoo; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Foo Foo {
        get { return result.Foo; }
        set { SetFoo(value); }
      }
      public Builder SetFoo(global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Foo value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasFoo = true;
        result.foo_ = value;
        return this;
      }
      public Builder SetFoo(global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Foo.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.hasFoo = true;
        result.foo_ = builderForValue.Build();
        return this;
      }
      public Builder MergeFoo(global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Foo value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        if (result.HasFoo &&
            result.foo_ != global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Foo.DefaultInstance) {
            result.foo_ = global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Foo.CreateBuilder(result.foo_).MergeFrom(value).BuildPartial();
        } else {
          result.foo_ = value;
        }
        result.hasFoo = true;
        return this;
      }
      public Builder ClearFoo() {
        result.hasFoo = false;
        result.foo_ = global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Foo.DefaultInstance;
        return this;
      }
      
      public bool HasBar {
       get { return result.HasBar; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Bar Bar {
        get { return result.Bar; }
        set { SetBar(value); }
      }
      public Builder SetBar(global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Bar value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasBar = true;
        result.bar_ = value;
        return this;
      }
      public Builder SetBar(global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Bar.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.hasBar = true;
        result.bar_ = builderForValue.Build();
        return this;
      }
      public Builder MergeBar(global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Bar value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        if (result.HasBar &&
            result.bar_ != global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Bar.DefaultInstance) {
            result.bar_ = global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Bar.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.TestDupFieldNumber.Types.Bar.DefaultInstance;
        return this;
      }
    }
    static TestDupFieldNumber() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 TestNestedMessageHasBits : pb::GeneratedMessage<TestNestedMessageHasBits, TestNestedMessageHasBits.Builder> {
    private static readonly TestNestedMessageHasBits defaultInstance = new Builder().BuildPartial();
    public static TestNestedMessageHasBits DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestNestedMessageHasBits DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestNestedMessageHasBits ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestNestedMessageHasBits__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestNestedMessageHasBits, TestNestedMessageHasBits.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestNestedMessageHasBits__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 NestedMessage : pb::GeneratedMessage<NestedMessage, NestedMessage.Builder> {
        private static readonly NestedMessage defaultInstance = new Builder().BuildPartial();
        public static NestedMessage DefaultInstance {
          get { return defaultInstance; }
        }
        
        public override NestedMessage DefaultInstanceForType {
          get { return defaultInstance; }
        }
        
        protected override NestedMessage ThisMessage {
          get { return this; }
        }
        
        public static pbd::MessageDescriptor Descriptor {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestNestedMessageHasBits_NestedMessage__Descriptor; }
        }
        
        protected override pb::FieldAccess.FieldAccessorTable<NestedMessage, NestedMessage.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestNestedMessageHasBits_NestedMessage__FieldAccessorTable; }
        }
        
        public const int NestedmessageRepeatedInt32FieldNumber = 1;
        private pbc::PopsicleList<int> nestedmessageRepeatedInt32_ = new pbc::PopsicleList<int>();
        public scg::IList<int> NestedmessageRepeatedInt32List {
          get { return pbc::Lists.AsReadOnly(nestedmessageRepeatedInt32_); }
        }
        public int NestedmessageRepeatedInt32Count {
          get { return nestedmessageRepeatedInt32_.Count; }
        }
        public int GetNestedmessageRepeatedInt32(int index) {
          return nestedmessageRepeatedInt32_[index];
        }
        
        public const int NestedmessageRepeatedForeignmessageFieldNumber = 2;
        private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignMessage> nestedmessageRepeatedForeignmessage_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignMessage>();
        public scg::IList<global::Google.ProtocolBuffers.TestProtos.ForeignMessage> NestedmessageRepeatedForeignmessageList {
          get { return nestedmessageRepeatedForeignmessage_; }
        }
        public int NestedmessageRepeatedForeignmessageCount {
          get { return nestedmessageRepeatedForeignmessage_.Count; }
        }
        public global::Google.ProtocolBuffers.TestProtos.ForeignMessage GetNestedmessageRepeatedForeignmessage(int index) {
          return nestedmessageRepeatedForeignmessage_[index];
        }
        
        public override bool IsInitialized {
          get {
            return true;
          }
        }
        
        public override void WriteTo(pb::ICodedOutputStream output) {
          int size = SerializedSize;
          if (nestedmessageRepeatedInt32_.Count > 0) {
            output.WriteArray(pbd::FieldType.Int32, 1, "nestedmessage_repeated_int32", nestedmessageRepeatedInt32_);
          }
          if (nestedmessageRepeatedForeignmessage_.Count > 0) {
            output.WriteArray(pbd::FieldType.Message, 2, "nestedmessage_repeated_foreignmessage", nestedmessageRepeatedForeignmessage_);
          }
          UnknownFields.WriteTo(output);
        }
        
        private int memoizedSerializedSize = -1;
        public override int SerializedSize {
          get {
            int size = memoizedSerializedSize;
            if (size != -1) return size;
            
            size = 0;
            {
              int dataSize = 0;
              foreach (int element in NestedmessageRepeatedInt32List) {
                dataSize += pb::CodedOutputStream.ComputeInt32SizeNoTag(element);
              }
              size += dataSize;
              size += 1 * nestedmessageRepeatedInt32_.Count;
            }
            foreach (global::Google.ProtocolBuffers.TestProtos.ForeignMessage element in NestedmessageRepeatedForeignmessageList) {
              size += pb::CodedOutputStream.ComputeMessageSize(2, element);
            }
            size += UnknownFields.SerializedSize;
            memoizedSerializedSize = size;
            return size;
          }
        }
        
        public static NestedMessage ParseFrom(pb::ByteString data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static NestedMessage ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static NestedMessage ParseFrom(byte[] data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static NestedMessage ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static NestedMessage ParseFrom(global::System.IO.Stream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static NestedMessage ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static NestedMessage ParseDelimitedFrom(global::System.IO.Stream input) {
          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
        }
        public static NestedMessage ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
        }
        public static NestedMessage ParseFrom(pb::CodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static NestedMessage 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(NestedMessage 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<NestedMessage, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {}
          
          NestedMessage result = new NestedMessage();
          
          protected override NestedMessage MessageBeingBuilt {
            get { return result; }
          }
          
          public override Builder Clear() {
            result = new NestedMessage();
            return this;
          }
          
          public override Builder Clone() {
            return new Builder().MergeFrom(result);
          }
          
          public override pbd::MessageDescriptor DescriptorForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Types.NestedMessage.Descriptor; }
          }
          
          public override NestedMessage DefaultInstanceForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Types.NestedMessage.DefaultInstance; }
          }
          
          public override NestedMessage BuildPartial() {
            if (result == null) {
              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
            }
            result.nestedmessageRepeatedInt32_.MakeReadOnly();
            result.nestedmessageRepeatedForeignmessage_.MakeReadOnly();
            NestedMessage returnMe = result;
            result = null;
            return returnMe;
          }
          
          public override Builder MergeFrom(pb::IMessage other) {
            if (other is NestedMessage) {
              return MergeFrom((NestedMessage) other);
            } else {
              base.MergeFrom(other);
              return this;
            }
          }
          
          public override Builder MergeFrom(NestedMessage other) {
            if (other == global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Types.NestedMessage.DefaultInstance) return this;
            if (other.nestedmessageRepeatedInt32_.Count != 0) {
              base.AddRange(other.nestedmessageRepeatedInt32_, result.nestedmessageRepeatedInt32_);
            }
            if (other.nestedmessageRepeatedForeignmessage_.Count != 0) {
              base.AddRange(other.nestedmessageRepeatedForeignmessage_, result.nestedmessageRepeatedForeignmessage_);
            }
            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;
            uint tag;
            string field_name;
            while (input.ReadTag(out tag, out field_name)) {
              switch (tag) {
                case 0: {
                  throw pb::InvalidProtocolBufferException.InvalidTag();
                }
                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, field_name);
                  break;
                }
                case 8: {
                  input.ReadPrimitiveArray(pbd::FieldType.Int32, tag, field_name, result.nestedmessageRepeatedInt32_);
                  break;
                }
                case 18: {
                  input.ReadMessageArray(tag, field_name, result.nestedmessageRepeatedForeignmessage_, global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance, extensionRegistry);
                  break;
                }
              }
            }
            
            if (unknownFields != null) {
              this.UnknownFields = unknownFields.Build();
            }
            return this;
          }
          
          
          public pbc::IPopsicleList<int> NestedmessageRepeatedInt32List {
            get { return result.nestedmessageRepeatedInt32_; }
          }
          public int NestedmessageRepeatedInt32Count {
            get { return result.NestedmessageRepeatedInt32Count; }
          }
          public int GetNestedmessageRepeatedInt32(int index) {
            return result.GetNestedmessageRepeatedInt32(index);
          }
          public Builder SetNestedmessageRepeatedInt32(int index, int value) {
            result.nestedmessageRepeatedInt32_[index] = value;
            return this;
          }
          public Builder AddNestedmessageRepeatedInt32(int value) {
            result.nestedmessageRepeatedInt32_.Add(value);
            return this;
          }
          public Builder AddRangeNestedmessageRepeatedInt32(scg::IEnumerable<int> values) {
            base.AddRange(values, result.nestedmessageRepeatedInt32_);
            return this;
          }
          public Builder ClearNestedmessageRepeatedInt32() {
            result.nestedmessageRepeatedInt32_.Clear();
            return this;
          }
          
          public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignMessage> NestedmessageRepeatedForeignmessageList {
            get { return result.nestedmessageRepeatedForeignmessage_; }
          }
          public int NestedmessageRepeatedForeignmessageCount {
            get { return result.NestedmessageRepeatedForeignmessageCount; }
          }
          public global::Google.ProtocolBuffers.TestProtos.ForeignMessage GetNestedmessageRepeatedForeignmessage(int index) {
            return result.GetNestedmessageRepeatedForeignmessage(index);
          }
          public Builder SetNestedmessageRepeatedForeignmessage(int index, global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            result.nestedmessageRepeatedForeignmessage_[index] = value;
            return this;
          }
          public Builder SetNestedmessageRepeatedForeignmessage(int index, global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder builderForValue) {
            pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
            result.nestedmessageRepeatedForeignmessage_[index] = builderForValue.Build();
            return this;
          }
          public Builder AddNestedmessageRepeatedForeignmessage(global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            result.nestedmessageRepeatedForeignmessage_.Add(value);
            return this;
          }
          public Builder AddNestedmessageRepeatedForeignmessage(global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder builderForValue) {
            pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
            result.nestedmessageRepeatedForeignmessage_.Add(builderForValue.Build());
            return this;
          }
          public Builder AddRangeNestedmessageRepeatedForeignmessage(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.ForeignMessage> values) {
            base.AddRange(values, result.nestedmessageRepeatedForeignmessage_);
            return this;
          }
          public Builder ClearNestedmessageRepeatedForeignmessage() {
            result.nestedmessageRepeatedForeignmessage_.Clear();
            return this;
          }
        }
        static NestedMessage() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
        }
      }
      
    }
    #endregion
    
    public const int OptionalNestedMessageFieldNumber = 1;
    private bool hasOptionalNestedMessage;
    private global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Types.NestedMessage optionalNestedMessage_ = global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Types.NestedMessage.DefaultInstance;
    public bool HasOptionalNestedMessage {
      get { return hasOptionalNestedMessage; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Types.NestedMessage OptionalNestedMessage {
      get { return optionalNestedMessage_; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (HasOptionalNestedMessage) {
        output.WriteMessage(1, "optional_nested_message", OptionalNestedMessage);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasOptionalNestedMessage) {
          size += pb::CodedOutputStream.ComputeMessageSize(1, OptionalNestedMessage);
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static TestNestedMessageHasBits ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestNestedMessageHasBits ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestNestedMessageHasBits ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestNestedMessageHasBits ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestNestedMessageHasBits ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestNestedMessageHasBits ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestNestedMessageHasBits ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestNestedMessageHasBits ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestNestedMessageHasBits ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestNestedMessageHasBits 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(TestNestedMessageHasBits 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<TestNestedMessageHasBits, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestNestedMessageHasBits result = new TestNestedMessageHasBits();
      
      protected override TestNestedMessageHasBits MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestNestedMessageHasBits();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Descriptor; }
      }
      
      public override TestNestedMessageHasBits DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.DefaultInstance; }
      }
      
      public override TestNestedMessageHasBits BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        TestNestedMessageHasBits returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestNestedMessageHasBits) {
          return MergeFrom((TestNestedMessageHasBits) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestNestedMessageHasBits other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.DefaultInstance) return this;
        if (other.HasOptionalNestedMessage) {
          MergeOptionalNestedMessage(other.OptionalNestedMessage);
        }
        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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
            case 10: {
              global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Types.NestedMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Types.NestedMessage.CreateBuilder();
              if (HasOptionalNestedMessage) {
                subBuilder.MergeFrom(OptionalNestedMessage);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              OptionalNestedMessage = subBuilder.BuildPartial();
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      public bool HasOptionalNestedMessage {
       get { return result.HasOptionalNestedMessage; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Types.NestedMessage OptionalNestedMessage {
        get { return result.OptionalNestedMessage; }
        set { SetOptionalNestedMessage(value); }
      }
      public Builder SetOptionalNestedMessage(global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Types.NestedMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasOptionalNestedMessage = true;
        result.optionalNestedMessage_ = value;
        return this;
      }
      public Builder SetOptionalNestedMessage(global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Types.NestedMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.hasOptionalNestedMessage = true;
        result.optionalNestedMessage_ = builderForValue.Build();
        return this;
      }
      public Builder MergeOptionalNestedMessage(global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Types.NestedMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        if (result.HasOptionalNestedMessage &&
            result.optionalNestedMessage_ != global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Types.NestedMessage.DefaultInstance) {
            result.optionalNestedMessage_ = global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Types.NestedMessage.CreateBuilder(result.optionalNestedMessage_).MergeFrom(value).BuildPartial();
        } else {
          result.optionalNestedMessage_ = value;
        }
        result.hasOptionalNestedMessage = true;
        return this;
      }
      public Builder ClearOptionalNestedMessage() {
        result.hasOptionalNestedMessage = false;
        result.optionalNestedMessage_ = global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Types.NestedMessage.DefaultInstance;
        return this;
      }
    }
    static TestNestedMessageHasBits() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 TestCamelCaseFieldNames : pb::GeneratedMessage<TestCamelCaseFieldNames, TestCamelCaseFieldNames.Builder> {
    private static readonly TestCamelCaseFieldNames defaultInstance = new Builder().BuildPartial();
    public static TestCamelCaseFieldNames DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestCamelCaseFieldNames DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestCamelCaseFieldNames ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestCamelCaseFieldNames__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestCamelCaseFieldNames, TestCamelCaseFieldNames.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestCamelCaseFieldNames__FieldAccessorTable; }
    }
    
    public const int PrimitiveFieldFieldNumber = 1;
    private bool hasPrimitiveField;
    private int primitiveField_ = 0;
    public bool HasPrimitiveField {
      get { return hasPrimitiveField; }
    }
    public int PrimitiveField {
      get { return primitiveField_; }
    }
    
    public const int StringFieldFieldNumber = 2;
    private bool hasStringField;
    private string stringField_ = "";
    public bool HasStringField {
      get { return hasStringField; }
    }
    public string StringField {
      get { return stringField_; }
    }
    
    public const int EnumFieldFieldNumber = 3;
    private bool hasEnumField;
    private global::Google.ProtocolBuffers.TestProtos.ForeignEnum enumField_ = global::Google.ProtocolBuffers.TestProtos.ForeignEnum.FOREIGN_FOO;
    public bool HasEnumField {
      get { return hasEnumField; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ForeignEnum EnumField {
      get { return enumField_; }
    }
    
    public const int MessageFieldFieldNumber = 4;
    private bool hasMessageField;
    private global::Google.ProtocolBuffers.TestProtos.ForeignMessage messageField_ = global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance;
    public bool HasMessageField {
      get { return hasMessageField; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ForeignMessage MessageField {
      get { return messageField_; }
    }
    
    public const int StringPieceFieldFieldNumber = 5;
    private bool hasStringPieceField;
    private string stringPieceField_ = "";
    public bool HasStringPieceField {
      get { return hasStringPieceField; }
    }
    public string StringPieceField {
      get { return stringPieceField_; }
    }
    
    public const int CordFieldFieldNumber = 6;
    private bool hasCordField;
    private string cordField_ = "";
    public bool HasCordField {
      get { return hasCordField; }
    }
    public string CordField {
      get { return cordField_; }
    }
    
    public const int RepeatedPrimitiveFieldFieldNumber = 7;
    private pbc::PopsicleList<int> repeatedPrimitiveField_ = new pbc::PopsicleList<int>();
    public scg::IList<int> RepeatedPrimitiveFieldList {
      get { return pbc::Lists.AsReadOnly(repeatedPrimitiveField_); }
    }
    public int RepeatedPrimitiveFieldCount {
      get { return repeatedPrimitiveField_.Count; }
    }
    public int GetRepeatedPrimitiveField(int index) {
      return repeatedPrimitiveField_[index];
    }
    
    public const int RepeatedStringFieldFieldNumber = 8;
    private pbc::PopsicleList<string> repeatedStringField_ = new pbc::PopsicleList<string>();
    public scg::IList<string> RepeatedStringFieldList {
      get { return pbc::Lists.AsReadOnly(repeatedStringField_); }
    }
    public int RepeatedStringFieldCount {
      get { return repeatedStringField_.Count; }
    }
    public string GetRepeatedStringField(int index) {
      return repeatedStringField_[index];
    }
    
    public const int RepeatedEnumFieldFieldNumber = 9;
    private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> repeatedEnumField_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>();
    public scg::IList<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> RepeatedEnumFieldList {
      get { return pbc::Lists.AsReadOnly(repeatedEnumField_); }
    }
    public int RepeatedEnumFieldCount {
      get { return repeatedEnumField_.Count; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ForeignEnum GetRepeatedEnumField(int index) {
      return repeatedEnumField_[index];
    }
    
    public const int RepeatedMessageFieldFieldNumber = 10;
    private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignMessage> repeatedMessageField_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignMessage>();
    public scg::IList<global::Google.ProtocolBuffers.TestProtos.ForeignMessage> RepeatedMessageFieldList {
      get { return repeatedMessageField_; }
    }
    public int RepeatedMessageFieldCount {
      get { return repeatedMessageField_.Count; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ForeignMessage GetRepeatedMessageField(int index) {
      return repeatedMessageField_[index];
    }
    
    public const int RepeatedStringPieceFieldFieldNumber = 11;
    private pbc::PopsicleList<string> repeatedStringPieceField_ = new pbc::PopsicleList<string>();
    public scg::IList<string> RepeatedStringPieceFieldList {
      get { return pbc::Lists.AsReadOnly(repeatedStringPieceField_); }
    }
    public int RepeatedStringPieceFieldCount {
      get { return repeatedStringPieceField_.Count; }
    }
    public string GetRepeatedStringPieceField(int index) {
      return repeatedStringPieceField_[index];
    }
    
    public const int RepeatedCordFieldFieldNumber = 12;
    private pbc::PopsicleList<string> repeatedCordField_ = new pbc::PopsicleList<string>();
    public scg::IList<string> RepeatedCordFieldList {
      get { return pbc::Lists.AsReadOnly(repeatedCordField_); }
    }
    public int RepeatedCordFieldCount {
      get { return repeatedCordField_.Count; }
    }
    public string GetRepeatedCordField(int index) {
      return repeatedCordField_[index];
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (HasPrimitiveField) {
        output.WriteInt32(1, "PrimitiveField", PrimitiveField);
      }
      if (HasStringField) {
        output.WriteString(2, "StringField", StringField);
      }
      if (HasEnumField) {
        output.WriteEnum(3, "EnumField", (int) EnumField, EnumField.ToString());
      }
      if (HasMessageField) {
        output.WriteMessage(4, "MessageField", MessageField);
      }
      if (HasStringPieceField) {
        output.WriteString(5, "StringPieceField", StringPieceField);
      }
      if (HasCordField) {
        output.WriteString(6, "CordField", CordField);
      }
      if (repeatedPrimitiveField_.Count > 0) {
        output.WriteArray(pbd::FieldType.Int32, 7, "RepeatedPrimitiveField", repeatedPrimitiveField_);
      }
      if (repeatedStringField_.Count > 0) {
        output.WriteArray(pbd::FieldType.String, 8, "RepeatedStringField", repeatedStringField_);
      }
      if (repeatedEnumField_.Count > 0) {
        output.WriteArray(pbd::FieldType.Enum, 9, "RepeatedEnumField", repeatedEnumField_);
      }
      if (repeatedMessageField_.Count > 0) {
        output.WriteArray(pbd::FieldType.Message, 10, "RepeatedMessageField", repeatedMessageField_);
      }
      if (repeatedStringPieceField_.Count > 0) {
        output.WriteArray(pbd::FieldType.String, 11, "RepeatedStringPieceField", repeatedStringPieceField_);
      }
      if (repeatedCordField_.Count > 0) {
        output.WriteArray(pbd::FieldType.String, 12, "RepeatedCordField", repeatedCordField_);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasPrimitiveField) {
          size += pb::CodedOutputStream.ComputeInt32Size(1, PrimitiveField);
        }
        if (HasStringField) {
          size += pb::CodedOutputStream.ComputeStringSize(2, StringField);
        }
        if (HasEnumField) {
          size += pb::CodedOutputStream.ComputeEnumSize(3, (int) EnumField);
        }
        if (HasMessageField) {
          size += pb::CodedOutputStream.ComputeMessageSize(4, MessageField);
        }
        if (HasStringPieceField) {
          size += pb::CodedOutputStream.ComputeStringSize(5, StringPieceField);
        }
        if (HasCordField) {
          size += pb::CodedOutputStream.ComputeStringSize(6, CordField);
        }
        {
          int dataSize = 0;
          foreach (int element in RepeatedPrimitiveFieldList) {
            dataSize += pb::CodedOutputStream.ComputeInt32SizeNoTag(element);
          }
          size += dataSize;
          size += 1 * repeatedPrimitiveField_.Count;
        }
        {
          int dataSize = 0;
          foreach (string element in RepeatedStringFieldList) {
            dataSize += pb::CodedOutputStream.ComputeStringSizeNoTag(element);
          }
          size += dataSize;
          size += 1 * repeatedStringField_.Count;
        }
        {
          int dataSize = 0;
          if (repeatedEnumField_.Count > 0) {
            foreach (global::Google.ProtocolBuffers.TestProtos.ForeignEnum element in repeatedEnumField_) {
              dataSize += pb::CodedOutputStream.ComputeEnumSizeNoTag((int) element);
            }
            size += dataSize;
            size += 1 * repeatedEnumField_.Count;
          }
        }
        foreach (global::Google.ProtocolBuffers.TestProtos.ForeignMessage element in RepeatedMessageFieldList) {
          size += pb::CodedOutputStream.ComputeMessageSize(10, element);
        }
        {
          int dataSize = 0;
          foreach (string element in RepeatedStringPieceFieldList) {
            dataSize += pb::CodedOutputStream.ComputeStringSizeNoTag(element);
          }
          size += dataSize;
          size += 1 * repeatedStringPieceField_.Count;
        }
        {
          int dataSize = 0;
          foreach (string element in RepeatedCordFieldList) {
            dataSize += pb::CodedOutputStream.ComputeStringSizeNoTag(element);
          }
          size += dataSize;
          size += 1 * repeatedCordField_.Count;
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static TestCamelCaseFieldNames ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestCamelCaseFieldNames ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestCamelCaseFieldNames ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestCamelCaseFieldNames ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestCamelCaseFieldNames ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestCamelCaseFieldNames ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestCamelCaseFieldNames ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestCamelCaseFieldNames ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestCamelCaseFieldNames ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestCamelCaseFieldNames 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(TestCamelCaseFieldNames 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<TestCamelCaseFieldNames, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestCamelCaseFieldNames result = new TestCamelCaseFieldNames();
      
      protected override TestCamelCaseFieldNames MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestCamelCaseFieldNames();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestCamelCaseFieldNames.Descriptor; }
      }
      
      public override TestCamelCaseFieldNames DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestCamelCaseFieldNames.DefaultInstance; }
      }
      
      public override TestCamelCaseFieldNames BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        result.repeatedPrimitiveField_.MakeReadOnly();
        result.repeatedStringField_.MakeReadOnly();
        result.repeatedEnumField_.MakeReadOnly();
        result.repeatedMessageField_.MakeReadOnly();
        result.repeatedStringPieceField_.MakeReadOnly();
        result.repeatedCordField_.MakeReadOnly();
        TestCamelCaseFieldNames returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestCamelCaseFieldNames) {
          return MergeFrom((TestCamelCaseFieldNames) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestCamelCaseFieldNames other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestCamelCaseFieldNames.DefaultInstance) return this;
        if (other.HasPrimitiveField) {
          PrimitiveField = other.PrimitiveField;
        }
        if (other.HasStringField) {
          StringField = other.StringField;
        }
        if (other.HasEnumField) {
          EnumField = other.EnumField;
        }
        if (other.HasMessageField) {
          MergeMessageField(other.MessageField);
        }
        if (other.HasStringPieceField) {
          StringPieceField = other.StringPieceField;
        }
        if (other.HasCordField) {
          CordField = other.CordField;
        }
        if (other.repeatedPrimitiveField_.Count != 0) {
          base.AddRange(other.repeatedPrimitiveField_, result.repeatedPrimitiveField_);
        }
        if (other.repeatedStringField_.Count != 0) {
          base.AddRange(other.repeatedStringField_, result.repeatedStringField_);
        }
        if (other.repeatedEnumField_.Count != 0) {
          base.AddRange(other.repeatedEnumField_, result.repeatedEnumField_);
        }
        if (other.repeatedMessageField_.Count != 0) {
          base.AddRange(other.repeatedMessageField_, result.repeatedMessageField_);
        }
        if (other.repeatedStringPieceField_.Count != 0) {
          base.AddRange(other.repeatedStringPieceField_, result.repeatedStringPieceField_);
        }
        if (other.repeatedCordField_.Count != 0) {
          base.AddRange(other.repeatedCordField_, result.repeatedCordField_);
        }
        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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
            case 8: {
              result.hasPrimitiveField |= input.ReadInt32(ref result.primitiveField_);
              break;
            }
            case 18: {
              result.hasStringField |= input.ReadString(ref result.stringField_);
              break;
            }
            case 24: {
              object unknown;
              if(input.ReadEnum(ref result.enumField_, out unknown)) {
                result.hasEnumField = true;
              } else if(unknown is int) {
                if (unknownFields == null) {
                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                }
                unknownFields.MergeVarintField(3, (ulong)(int)unknown);
              }
              break;
            }
            case 34: {
              global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.ForeignMessage.CreateBuilder();
              if (HasMessageField) {
                subBuilder.MergeFrom(MessageField);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              MessageField = subBuilder.BuildPartial();
              break;
            }
            case 42: {
              result.hasStringPieceField |= input.ReadString(ref result.stringPieceField_);
              break;
            }
            case 50: {
              result.hasCordField |= input.ReadString(ref result.cordField_);
              break;
            }
            case 56: {
              input.ReadPrimitiveArray(pbd::FieldType.Int32, tag, field_name, result.repeatedPrimitiveField_);
              break;
            }
            case 66: {
              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedStringField_);
              break;
            }
            case 72: {
              scg::ICollection<object> unknownItems;
              input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>(tag, field_name, result.repeatedEnumField_, out unknownItems);
              if (unknownItems != null) {
                if (unknownFields == null) {
                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                }
                foreach (object rawValue in unknownItems)
                  if (rawValue is int)
                    unknownFields.MergeVarintField(9, (ulong)(int)rawValue);
              }
              break;
            }
            case 82: {
              input.ReadMessageArray(tag, field_name, result.repeatedMessageField_, global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance, extensionRegistry);
              break;
            }
            case 90: {
              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedStringPieceField_);
              break;
            }
            case 98: {
              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedCordField_);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      public bool HasPrimitiveField {
        get { return result.HasPrimitiveField; }
      }
      public int PrimitiveField {
        get { return result.PrimitiveField; }
        set { SetPrimitiveField(value); }
      }
      public Builder SetPrimitiveField(int value) {
        result.hasPrimitiveField = true;
        result.primitiveField_ = value;
        return this;
      }
      public Builder ClearPrimitiveField() {
        result.hasPrimitiveField = false;
        result.primitiveField_ = 0;
        return this;
      }
      
      public bool HasStringField {
        get { return result.HasStringField; }
      }
      public string StringField {
        get { return result.StringField; }
        set { SetStringField(value); }
      }
      public Builder SetStringField(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasStringField = true;
        result.stringField_ = value;
        return this;
      }
      public Builder ClearStringField() {
        result.hasStringField = false;
        result.stringField_ = "";
        return this;
      }
      
      public bool HasEnumField {
       get { return result.HasEnumField; }
      }
      public global::Google.ProtocolBuffers.TestProtos.ForeignEnum EnumField {
        get { return result.EnumField; }
        set { SetEnumField(value); }
      }
      public Builder SetEnumField(global::Google.ProtocolBuffers.TestProtos.ForeignEnum value) {
        result.hasEnumField = true;
        result.enumField_ = value;
        return this;
      }
      public Builder ClearEnumField() {
        result.hasEnumField = false;
        result.enumField_ = global::Google.ProtocolBuffers.TestProtos.ForeignEnum.FOREIGN_FOO;
        return this;
      }
      
      public bool HasMessageField {
       get { return result.HasMessageField; }
      }
      public global::Google.ProtocolBuffers.TestProtos.ForeignMessage MessageField {
        get { return result.MessageField; }
        set { SetMessageField(value); }
      }
      public Builder SetMessageField(global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasMessageField = true;
        result.messageField_ = value;
        return this;
      }
      public Builder SetMessageField(global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.hasMessageField = true;
        result.messageField_ = builderForValue.Build();
        return this;
      }
      public Builder MergeMessageField(global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        if (result.HasMessageField &&
            result.messageField_ != global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance) {
            result.messageField_ = global::Google.ProtocolBuffers.TestProtos.ForeignMessage.CreateBuilder(result.messageField_).MergeFrom(value).BuildPartial();
        } else {
          result.messageField_ = value;
        }
        result.hasMessageField = true;
        return this;
      }
      public Builder ClearMessageField() {
        result.hasMessageField = false;
        result.messageField_ = global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance;
        return this;
      }
      
      public bool HasStringPieceField {
        get { return result.HasStringPieceField; }
      }
      public string StringPieceField {
        get { return result.StringPieceField; }
        set { SetStringPieceField(value); }
      }
      public Builder SetStringPieceField(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasStringPieceField = true;
        result.stringPieceField_ = value;
        return this;
      }
      public Builder ClearStringPieceField() {
        result.hasStringPieceField = false;
        result.stringPieceField_ = "";
        return this;
      }
      
      public bool HasCordField {
        get { return result.HasCordField; }
      }
      public string CordField {
        get { return result.CordField; }
        set { SetCordField(value); }
      }
      public Builder SetCordField(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasCordField = true;
        result.cordField_ = value;
        return this;
      }
      public Builder ClearCordField() {
        result.hasCordField = false;
        result.cordField_ = "";
        return this;
      }
      
      public pbc::IPopsicleList<int> RepeatedPrimitiveFieldList {
        get { return result.repeatedPrimitiveField_; }
      }
      public int RepeatedPrimitiveFieldCount {
        get { return result.RepeatedPrimitiveFieldCount; }
      }
      public int GetRepeatedPrimitiveField(int index) {
        return result.GetRepeatedPrimitiveField(index);
      }
      public Builder SetRepeatedPrimitiveField(int index, int value) {
        result.repeatedPrimitiveField_[index] = value;
        return this;
      }
      public Builder AddRepeatedPrimitiveField(int value) {
        result.repeatedPrimitiveField_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedPrimitiveField(scg::IEnumerable<int> values) {
        base.AddRange(values, result.repeatedPrimitiveField_);
        return this;
      }
      public Builder ClearRepeatedPrimitiveField() {
        result.repeatedPrimitiveField_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<string> RepeatedStringFieldList {
        get { return result.repeatedStringField_; }
      }
      public int RepeatedStringFieldCount {
        get { return result.RepeatedStringFieldCount; }
      }
      public string GetRepeatedStringField(int index) {
        return result.GetRepeatedStringField(index);
      }
      public Builder SetRepeatedStringField(int index, string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedStringField_[index] = value;
        return this;
      }
      public Builder AddRepeatedStringField(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedStringField_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedStringField(scg::IEnumerable<string> values) {
        base.AddRange(values, result.repeatedStringField_);
        return this;
      }
      public Builder ClearRepeatedStringField() {
        result.repeatedStringField_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> RepeatedEnumFieldList {
        get { return result.repeatedEnumField_; }
      }
      public int RepeatedEnumFieldCount {
        get { return result.RepeatedEnumFieldCount; }
      }
      public global::Google.ProtocolBuffers.TestProtos.ForeignEnum GetRepeatedEnumField(int index) {
        return result.GetRepeatedEnumField(index);
      }
      public Builder SetRepeatedEnumField(int index, global::Google.ProtocolBuffers.TestProtos.ForeignEnum value) {
        result.repeatedEnumField_[index] = value;
        return this;
      }
      public Builder AddRepeatedEnumField(global::Google.ProtocolBuffers.TestProtos.ForeignEnum value) {
        result.repeatedEnumField_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedEnumField(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> values) {
        base.AddRange(values, result.repeatedEnumField_);
        return this;
      }
      public Builder ClearRepeatedEnumField() {
        result.repeatedEnumField_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignMessage> RepeatedMessageFieldList {
        get { return result.repeatedMessageField_; }
      }
      public int RepeatedMessageFieldCount {
        get { return result.RepeatedMessageFieldCount; }
      }
      public global::Google.ProtocolBuffers.TestProtos.ForeignMessage GetRepeatedMessageField(int index) {
        return result.GetRepeatedMessageField(index);
      }
      public Builder SetRepeatedMessageField(int index, global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedMessageField_[index] = value;
        return this;
      }
      public Builder SetRepeatedMessageField(int index, global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.repeatedMessageField_[index] = builderForValue.Build();
        return this;
      }
      public Builder AddRepeatedMessageField(global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedMessageField_.Add(value);
        return this;
      }
      public Builder AddRepeatedMessageField(global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.repeatedMessageField_.Add(builderForValue.Build());
        return this;
      }
      public Builder AddRangeRepeatedMessageField(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.ForeignMessage> values) {
        base.AddRange(values, result.repeatedMessageField_);
        return this;
      }
      public Builder ClearRepeatedMessageField() {
        result.repeatedMessageField_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<string> RepeatedStringPieceFieldList {
        get { return result.repeatedStringPieceField_; }
      }
      public int RepeatedStringPieceFieldCount {
        get { return result.RepeatedStringPieceFieldCount; }
      }
      public string GetRepeatedStringPieceField(int index) {
        return result.GetRepeatedStringPieceField(index);
      }
      public Builder SetRepeatedStringPieceField(int index, string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedStringPieceField_[index] = value;
        return this;
      }
      public Builder AddRepeatedStringPieceField(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedStringPieceField_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedStringPieceField(scg::IEnumerable<string> values) {
        base.AddRange(values, result.repeatedStringPieceField_);
        return this;
      }
      public Builder ClearRepeatedStringPieceField() {
        result.repeatedStringPieceField_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<string> RepeatedCordFieldList {
        get { return result.repeatedCordField_; }
      }
      public int RepeatedCordFieldCount {
        get { return result.RepeatedCordFieldCount; }
      }
      public string GetRepeatedCordField(int index) {
        return result.GetRepeatedCordField(index);
      }
      public Builder SetRepeatedCordField(int index, string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedCordField_[index] = value;
        return this;
      }
      public Builder AddRepeatedCordField(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedCordField_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedCordField(scg::IEnumerable<string> values) {
        base.AddRange(values, result.repeatedCordField_);
        return this;
      }
      public Builder ClearRepeatedCordField() {
        result.repeatedCordField_.Clear();
        return this;
      }
    }
    static TestCamelCaseFieldNames() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 TestFieldOrderings : pb::ExtendableMessage<TestFieldOrderings, TestFieldOrderings.Builder> {
    private static readonly TestFieldOrderings defaultInstance = new Builder().BuildPartial();
    public static TestFieldOrderings DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestFieldOrderings DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestFieldOrderings ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestFieldOrderings__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestFieldOrderings, TestFieldOrderings.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestFieldOrderings__FieldAccessorTable; }
    }
    
    public const int MyStringFieldNumber = 11;
    private bool hasMyString;
    private string myString_ = "";
    public bool HasMyString {
      get { return hasMyString; }
    }
    public string MyString {
      get { return myString_; }
    }
    
    public const int MyIntFieldNumber = 1;
    private bool hasMyInt;
    private long myInt_ = 0L;
    public bool HasMyInt {
      get { return hasMyInt; }
    }
    public long MyInt {
      get { return myInt_; }
    }
    
    public const int MyFloatFieldNumber = 101;
    private bool hasMyFloat;
    private float myFloat_ = 0F;
    public bool HasMyFloat {
      get { return hasMyFloat; }
    }
    public float MyFloat {
      get { return myFloat_; }
    }
    
    public override bool IsInitialized {
      get {
        if (!ExtensionsAreInitialized) return false;
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      pb::ExtendableMessage<TestFieldOrderings, TestFieldOrderings.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
      if (HasMyInt) {
        output.WriteInt64(1, "my_int", MyInt);
      }
      extensionWriter.WriteUntil(11, output);
      if (HasMyString) {
        output.WriteString(11, "my_string", MyString);
      }
      extensionWriter.WriteUntil(101, output);
      if (HasMyFloat) {
        output.WriteFloat(101, "my_float", MyFloat);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasMyString) {
          size += pb::CodedOutputStream.ComputeStringSize(11, MyString);
        }
        if (HasMyInt) {
          size += pb::CodedOutputStream.ComputeInt64Size(1, MyInt);
        }
        if (HasMyFloat) {
          size += pb::CodedOutputStream.ComputeFloatSize(101, MyFloat);
        }
        size += ExtensionsSerializedSize;
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static TestFieldOrderings ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestFieldOrderings ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestFieldOrderings ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestFieldOrderings ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestFieldOrderings ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestFieldOrderings ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestFieldOrderings ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestFieldOrderings ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestFieldOrderings ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestFieldOrderings 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(TestFieldOrderings 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<TestFieldOrderings, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestFieldOrderings result = new TestFieldOrderings();
      
      protected override TestFieldOrderings MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestFieldOrderings();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestFieldOrderings.Descriptor; }
      }
      
      public override TestFieldOrderings DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestFieldOrderings.DefaultInstance; }
      }
      
      public override TestFieldOrderings BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        TestFieldOrderings returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestFieldOrderings) {
          return MergeFrom((TestFieldOrderings) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestFieldOrderings other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestFieldOrderings.DefaultInstance) return this;
        if (other.HasMyString) {
          MyString = other.MyString;
        }
        if (other.HasMyInt) {
          MyInt = other.MyInt;
        }
        if (other.HasMyFloat) {
          MyFloat = other.MyFloat;
        }
          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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
            case 8: {
              result.hasMyInt |= input.ReadInt64(ref result.myInt_);
              break;
            }
            case 90: {
              result.hasMyString |= input.ReadString(ref result.myString_);
              break;
            }
            case 813: {
              result.hasMyFloat |= input.ReadFloat(ref result.myFloat_);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      public bool HasMyString {
        get { return result.HasMyString; }
      }
      public string MyString {
        get { return result.MyString; }
        set { SetMyString(value); }
      }
      public Builder SetMyString(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasMyString = true;
        result.myString_ = value;
        return this;
      }
      public Builder ClearMyString() {
        result.hasMyString = false;
        result.myString_ = "";
        return this;
      }
      
      public bool HasMyInt {
        get { return result.HasMyInt; }
      }
      public long MyInt {
        get { return result.MyInt; }
        set { SetMyInt(value); }
      }
      public Builder SetMyInt(long value) {
        result.hasMyInt = true;
        result.myInt_ = value;
        return this;
      }
      public Builder ClearMyInt() {
        result.hasMyInt = false;
        result.myInt_ = 0L;
        return this;
      }
      
      public bool HasMyFloat {
        get { return result.HasMyFloat; }
      }
      public float MyFloat {
        get { return result.MyFloat; }
        set { SetMyFloat(value); }
      }
      public Builder SetMyFloat(float value) {
        result.hasMyFloat = true;
        result.myFloat_ = value;
        return this;
      }
      public Builder ClearMyFloat() {
        result.hasMyFloat = false;
        result.myFloat_ = 0F;
        return this;
      }
    }
    static TestFieldOrderings() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 TestExtremeDefaultValues : pb::GeneratedMessage<TestExtremeDefaultValues, TestExtremeDefaultValues.Builder> {
    private static readonly TestExtremeDefaultValues defaultInstance = new Builder().BuildPartial();
    public static TestExtremeDefaultValues DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestExtremeDefaultValues DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestExtremeDefaultValues ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestExtremeDefaultValues__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestExtremeDefaultValues, TestExtremeDefaultValues.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestExtremeDefaultValues__FieldAccessorTable; }
    }
    
    public const int EscapedBytesFieldNumber = 1;
    private bool hasEscapedBytes;
    private pb::ByteString escapedBytes_ = (pb::ByteString) global::Google.ProtocolBuffers.TestProtos.TestExtremeDefaultValues.Descriptor.Fields[0].DefaultValue;
    public bool HasEscapedBytes {
      get { return hasEscapedBytes; }
    }
    public pb::ByteString EscapedBytes {
      get { return escapedBytes_; }
    }
    
    public const int LargeUint32FieldNumber = 2;
    private bool hasLargeUint32;
    private uint largeUint32_ = 4294967295;
    public bool HasLargeUint32 {
      get { return hasLargeUint32; }
    }
    [global::System.CLSCompliant(false)]
    public uint LargeUint32 {
      get { return largeUint32_; }
    }
    
    public const int LargeUint64FieldNumber = 3;
    private bool hasLargeUint64;
    private ulong largeUint64_ = 18446744073709551615UL;
    public bool HasLargeUint64 {
      get { return hasLargeUint64; }
    }
    [global::System.CLSCompliant(false)]
    public ulong LargeUint64 {
      get { return largeUint64_; }
    }
    
    public const int SmallInt32FieldNumber = 4;
    private bool hasSmallInt32;
    private int smallInt32_ = -2147483647;
    public bool HasSmallInt32 {
      get { return hasSmallInt32; }
    }
    public int SmallInt32 {
      get { return smallInt32_; }
    }
    
    public const int SmallInt64FieldNumber = 5;
    private bool hasSmallInt64;
    private long smallInt64_ = -9223372036854775807L;
    public bool HasSmallInt64 {
      get { return hasSmallInt64; }
    }
    public long SmallInt64 {
      get { return smallInt64_; }
    }
    
    public const int Utf8StringFieldNumber = 6;
    private bool hasUtf8String;
    private string utf8String_ = (string) global::Google.ProtocolBuffers.TestProtos.TestExtremeDefaultValues.Descriptor.Fields[5].DefaultValue;
    public bool HasUtf8String {
      get { return hasUtf8String; }
    }
    public string Utf8String {
      get { return utf8String_; }
    }
    
    public const int ZeroFloatFieldNumber = 7;
    private bool hasZeroFloat;
    private float zeroFloat_ = 0F;
    public bool HasZeroFloat {
      get { return hasZeroFloat; }
    }
    public float ZeroFloat {
      get { return zeroFloat_; }
    }
    
    public const int OneFloatFieldNumber = 8;
    private bool hasOneFloat;
    private float oneFloat_ = 1F;
    public bool HasOneFloat {
      get { return hasOneFloat; }
    }
    public float OneFloat {
      get { return oneFloat_; }
    }
    
    public const int SmallFloatFieldNumber = 9;
    private bool hasSmallFloat;
    private float smallFloat_ = 1.5F;
    public bool HasSmallFloat {
      get { return hasSmallFloat; }
    }
    public float SmallFloat {
      get { return smallFloat_; }
    }
    
    public const int NegativeOneFloatFieldNumber = 10;
    private bool hasNegativeOneFloat;
    private float negativeOneFloat_ = -1F;
    public bool HasNegativeOneFloat {
      get { return hasNegativeOneFloat; }
    }
    public float NegativeOneFloat {
      get { return negativeOneFloat_; }
    }
    
    public const int NegativeFloatFieldNumber = 11;
    private bool hasNegativeFloat;
    private float negativeFloat_ = -1.5F;
    public bool HasNegativeFloat {
      get { return hasNegativeFloat; }
    }
    public float NegativeFloat {
      get { return negativeFloat_; }
    }
    
    public const int LargeFloatFieldNumber = 12;
    private bool hasLargeFloat;
    private float largeFloat_ = 2E+08F;
    public bool HasLargeFloat {
      get { return hasLargeFloat; }
    }
    public float LargeFloat {
      get { return largeFloat_; }
    }
    
    public const int SmallNegativeFloatFieldNumber = 13;
    private bool hasSmallNegativeFloat;
    private float smallNegativeFloat_ = -8E-28F;
    public bool HasSmallNegativeFloat {
      get { return hasSmallNegativeFloat; }
    }
    public float SmallNegativeFloat {
      get { return smallNegativeFloat_; }
    }
    
    public const int InfDoubleFieldNumber = 14;
    private bool hasInfDouble;
    private double infDouble_ = double.PositiveInfinity;
    public bool HasInfDouble {
      get { return hasInfDouble; }
    }
    public double InfDouble {
      get { return infDouble_; }
    }
    
    public const int NegInfDoubleFieldNumber = 15;
    private bool hasNegInfDouble;
    private double negInfDouble_ = double.NegativeInfinity;
    public bool HasNegInfDouble {
      get { return hasNegInfDouble; }
    }
    public double NegInfDouble {
      get { return negInfDouble_; }
    }
    
    public const int NanDoubleFieldNumber = 16;
    private bool hasNanDouble;
    private double nanDouble_ = double.NaN;
    public bool HasNanDouble {
      get { return hasNanDouble; }
    }
    public double NanDouble {
      get { return nanDouble_; }
    }
    
    public const int InfFloatFieldNumber = 17;
    private bool hasInfFloat;
    private float infFloat_ = float.PositiveInfinity;
    public bool HasInfFloat {
      get { return hasInfFloat; }
    }
    public float InfFloat {
      get { return infFloat_; }
    }
    
    public const int NegInfFloatFieldNumber = 18;
    private bool hasNegInfFloat;
    private float negInfFloat_ = float.NegativeInfinity;
    public bool HasNegInfFloat {
      get { return hasNegInfFloat; }
    }
    public float NegInfFloat {
      get { return negInfFloat_; }
    }
    
    public const int NanFloatFieldNumber = 19;
    private bool hasNanFloat;
    private float nanFloat_ = float.NaN;
    public bool HasNanFloat {
      get { return hasNanFloat; }
    }
    public float NanFloat {
      get { return nanFloat_; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (HasEscapedBytes) {
        output.WriteBytes(1, "escaped_bytes", EscapedBytes);
      }
      if (HasLargeUint32) {
        output.WriteUInt32(2, "large_uint32", LargeUint32);
      }
      if (HasLargeUint64) {
        output.WriteUInt64(3, "large_uint64", LargeUint64);
      }
      if (HasSmallInt32) {
        output.WriteInt32(4, "small_int32", SmallInt32);
      }
      if (HasSmallInt64) {
        output.WriteInt64(5, "small_int64", SmallInt64);
      }
      if (HasUtf8String) {
        output.WriteString(6, "utf8_string", Utf8String);
      }
      if (HasZeroFloat) {
        output.WriteFloat(7, "zero_float", ZeroFloat);
      }
      if (HasOneFloat) {
        output.WriteFloat(8, "one_float", OneFloat);
      }
      if (HasSmallFloat) {
        output.WriteFloat(9, "small_float", SmallFloat);
      }
      if (HasNegativeOneFloat) {
        output.WriteFloat(10, "negative_one_float", NegativeOneFloat);
      }
      if (HasNegativeFloat) {
        output.WriteFloat(11, "negative_float", NegativeFloat);
      }
      if (HasLargeFloat) {
        output.WriteFloat(12, "large_float", LargeFloat);
      }
      if (HasSmallNegativeFloat) {
        output.WriteFloat(13, "small_negative_float", SmallNegativeFloat);
      }
      if (HasInfDouble) {
        output.WriteDouble(14, "inf_double", InfDouble);
      }
      if (HasNegInfDouble) {
        output.WriteDouble(15, "neg_inf_double", NegInfDouble);
      }
      if (HasNanDouble) {
        output.WriteDouble(16, "nan_double", NanDouble);
      }
      if (HasInfFloat) {
        output.WriteFloat(17, "inf_float", InfFloat);
      }
      if (HasNegInfFloat) {
        output.WriteFloat(18, "neg_inf_float", NegInfFloat);
      }
      if (HasNanFloat) {
        output.WriteFloat(19, "nan_float", NanFloat);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasEscapedBytes) {
          size += pb::CodedOutputStream.ComputeBytesSize(1, EscapedBytes);
        }
        if (HasLargeUint32) {
          size += pb::CodedOutputStream.ComputeUInt32Size(2, LargeUint32);
        }
        if (HasLargeUint64) {
          size += pb::CodedOutputStream.ComputeUInt64Size(3, LargeUint64);
        }
        if (HasSmallInt32) {
          size += pb::CodedOutputStream.ComputeInt32Size(4, SmallInt32);
        }
        if (HasSmallInt64) {
          size += pb::CodedOutputStream.ComputeInt64Size(5, SmallInt64);
        }
        if (HasUtf8String) {
          size += pb::CodedOutputStream.ComputeStringSize(6, Utf8String);
        }
        if (HasZeroFloat) {
          size += pb::CodedOutputStream.ComputeFloatSize(7, ZeroFloat);
        }
        if (HasOneFloat) {
          size += pb::CodedOutputStream.ComputeFloatSize(8, OneFloat);
        }
        if (HasSmallFloat) {
          size += pb::CodedOutputStream.ComputeFloatSize(9, SmallFloat);
        }
        if (HasNegativeOneFloat) {
          size += pb::CodedOutputStream.ComputeFloatSize(10, NegativeOneFloat);
        }
        if (HasNegativeFloat) {
          size += pb::CodedOutputStream.ComputeFloatSize(11, NegativeFloat);
        }
        if (HasLargeFloat) {
          size += pb::CodedOutputStream.ComputeFloatSize(12, LargeFloat);
        }
        if (HasSmallNegativeFloat) {
          size += pb::CodedOutputStream.ComputeFloatSize(13, SmallNegativeFloat);
        }
        if (HasInfDouble) {
          size += pb::CodedOutputStream.ComputeDoubleSize(14, InfDouble);
        }
        if (HasNegInfDouble) {
          size += pb::CodedOutputStream.ComputeDoubleSize(15, NegInfDouble);
        }
        if (HasNanDouble) {
          size += pb::CodedOutputStream.ComputeDoubleSize(16, NanDouble);
        }
        if (HasInfFloat) {
          size += pb::CodedOutputStream.ComputeFloatSize(17, InfFloat);
        }
        if (HasNegInfFloat) {
          size += pb::CodedOutputStream.ComputeFloatSize(18, NegInfFloat);
        }
        if (HasNanFloat) {
          size += pb::CodedOutputStream.ComputeFloatSize(19, NanFloat);
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static TestExtremeDefaultValues ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestExtremeDefaultValues ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestExtremeDefaultValues ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestExtremeDefaultValues ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestExtremeDefaultValues ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestExtremeDefaultValues ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestExtremeDefaultValues ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestExtremeDefaultValues ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestExtremeDefaultValues ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestExtremeDefaultValues 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(TestExtremeDefaultValues 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<TestExtremeDefaultValues, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestExtremeDefaultValues result = new TestExtremeDefaultValues();
      
      protected override TestExtremeDefaultValues MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestExtremeDefaultValues();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestExtremeDefaultValues.Descriptor; }
      }
      
      public override TestExtremeDefaultValues DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestExtremeDefaultValues.DefaultInstance; }
      }
      
      public override TestExtremeDefaultValues BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        TestExtremeDefaultValues returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestExtremeDefaultValues) {
          return MergeFrom((TestExtremeDefaultValues) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestExtremeDefaultValues other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestExtremeDefaultValues.DefaultInstance) return this;
        if (other.HasEscapedBytes) {
          EscapedBytes = other.EscapedBytes;
        }
        if (other.HasLargeUint32) {
          LargeUint32 = other.LargeUint32;
        }
        if (other.HasLargeUint64) {
          LargeUint64 = other.LargeUint64;
        }
        if (other.HasSmallInt32) {
          SmallInt32 = other.SmallInt32;
        }
        if (other.HasSmallInt64) {
          SmallInt64 = other.SmallInt64;
        }
        if (other.HasUtf8String) {
          Utf8String = other.Utf8String;
        }
        if (other.HasZeroFloat) {
          ZeroFloat = other.ZeroFloat;
        }
        if (other.HasOneFloat) {
          OneFloat = other.OneFloat;
        }
        if (other.HasSmallFloat) {
          SmallFloat = other.SmallFloat;
        }
        if (other.HasNegativeOneFloat) {
          NegativeOneFloat = other.NegativeOneFloat;
        }
        if (other.HasNegativeFloat) {
          NegativeFloat = other.NegativeFloat;
        }
        if (other.HasLargeFloat) {
          LargeFloat = other.LargeFloat;
        }
        if (other.HasSmallNegativeFloat) {
          SmallNegativeFloat = other.SmallNegativeFloat;
        }
        if (other.HasInfDouble) {
          InfDouble = other.InfDouble;
        }
        if (other.HasNegInfDouble) {
          NegInfDouble = other.NegInfDouble;
        }
        if (other.HasNanDouble) {
          NanDouble = other.NanDouble;
        }
        if (other.HasInfFloat) {
          InfFloat = other.InfFloat;
        }
        if (other.HasNegInfFloat) {
          NegInfFloat = other.NegInfFloat;
        }
        if (other.HasNanFloat) {
          NanFloat = other.NanFloat;
        }
        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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
            case 10: {
              result.hasEscapedBytes |= input.ReadBytes(ref result.escapedBytes_);
              break;
            }
            case 16: {
              result.hasLargeUint32 |= input.ReadUInt32(ref result.largeUint32_);
              break;
            }
            case 24: {
              result.hasLargeUint64 |= input.ReadUInt64(ref result.largeUint64_);
              break;
            }
            case 32: {
              result.hasSmallInt32 |= input.ReadInt32(ref result.smallInt32_);
              break;
            }
            case 40: {
              result.hasSmallInt64 |= input.ReadInt64(ref result.smallInt64_);
              break;
            }
            case 50: {
              result.hasUtf8String |= input.ReadString(ref result.utf8String_);
              break;
            }
            case 61: {
              result.hasZeroFloat |= input.ReadFloat(ref result.zeroFloat_);
              break;
            }
            case 69: {
              result.hasOneFloat |= input.ReadFloat(ref result.oneFloat_);
              break;
            }
            case 77: {
              result.hasSmallFloat |= input.ReadFloat(ref result.smallFloat_);
              break;
            }
            case 85: {
              result.hasNegativeOneFloat |= input.ReadFloat(ref result.negativeOneFloat_);
              break;
            }
            case 93: {
              result.hasNegativeFloat |= input.ReadFloat(ref result.negativeFloat_);
              break;
            }
            case 101: {
              result.hasLargeFloat |= input.ReadFloat(ref result.largeFloat_);
              break;
            }
            case 109: {
              result.hasSmallNegativeFloat |= input.ReadFloat(ref result.smallNegativeFloat_);
              break;
            }
            case 113: {
              result.hasInfDouble |= input.ReadDouble(ref result.infDouble_);
              break;
            }
            case 121: {
              result.hasNegInfDouble |= input.ReadDouble(ref result.negInfDouble_);
              break;
            }
            case 129: {
              result.hasNanDouble |= input.ReadDouble(ref result.nanDouble_);
              break;
            }
            case 141: {
              result.hasInfFloat |= input.ReadFloat(ref result.infFloat_);
              break;
            }
            case 149: {
              result.hasNegInfFloat |= input.ReadFloat(ref result.negInfFloat_);
              break;
            }
            case 157: {
              result.hasNanFloat |= input.ReadFloat(ref result.nanFloat_);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      public bool HasEscapedBytes {
        get { return result.HasEscapedBytes; }
      }
      public pb::ByteString EscapedBytes {
        get { return result.EscapedBytes; }
        set { SetEscapedBytes(value); }
      }
      public Builder SetEscapedBytes(pb::ByteString value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasEscapedBytes = true;
        result.escapedBytes_ = value;
        return this;
      }
      public Builder ClearEscapedBytes() {
        result.hasEscapedBytes = false;
        result.escapedBytes_ = (pb::ByteString) global::Google.ProtocolBuffers.TestProtos.TestExtremeDefaultValues.Descriptor.Fields[0].DefaultValue;
        return this;
      }
      
      public bool HasLargeUint32 {
        get { return result.HasLargeUint32; }
      }
      [global::System.CLSCompliant(false)]
      public uint LargeUint32 {
        get { return result.LargeUint32; }
        set { SetLargeUint32(value); }
      }
      [global::System.CLSCompliant(false)]
      public Builder SetLargeUint32(uint value) {
        result.hasLargeUint32 = true;
        result.largeUint32_ = value;
        return this;
      }
      public Builder ClearLargeUint32() {
        result.hasLargeUint32 = false;
        result.largeUint32_ = 4294967295;
        return this;
      }
      
      public bool HasLargeUint64 {
        get { return result.HasLargeUint64; }
      }
      [global::System.CLSCompliant(false)]
      public ulong LargeUint64 {
        get { return result.LargeUint64; }
        set { SetLargeUint64(value); }
      }
      [global::System.CLSCompliant(false)]
      public Builder SetLargeUint64(ulong value) {
        result.hasLargeUint64 = true;
        result.largeUint64_ = value;
        return this;
      }
      public Builder ClearLargeUint64() {
        result.hasLargeUint64 = false;
        result.largeUint64_ = 18446744073709551615UL;
        return this;
      }
      
      public bool HasSmallInt32 {
        get { return result.HasSmallInt32; }
      }
      public int SmallInt32 {
        get { return result.SmallInt32; }
        set { SetSmallInt32(value); }
      }
      public Builder SetSmallInt32(int value) {
        result.hasSmallInt32 = true;
        result.smallInt32_ = value;
        return this;
      }
      public Builder ClearSmallInt32() {
        result.hasSmallInt32 = false;
        result.smallInt32_ = -2147483647;
        return this;
      }
      
      public bool HasSmallInt64 {
        get { return result.HasSmallInt64; }
      }
      public long SmallInt64 {
        get { return result.SmallInt64; }
        set { SetSmallInt64(value); }
      }
      public Builder SetSmallInt64(long value) {
        result.hasSmallInt64 = true;
        result.smallInt64_ = value;
        return this;
      }
      public Builder ClearSmallInt64() {
        result.hasSmallInt64 = false;
        result.smallInt64_ = -9223372036854775807L;
        return this;
      }
      
      public bool HasUtf8String {
        get { return result.HasUtf8String; }
      }
      public string Utf8String {
        get { return result.Utf8String; }
        set { SetUtf8String(value); }
      }
      public Builder SetUtf8String(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasUtf8String = true;
        result.utf8String_ = value;
        return this;
      }
      public Builder ClearUtf8String() {
        result.hasUtf8String = false;
        result.utf8String_ = (string) global::Google.ProtocolBuffers.TestProtos.TestExtremeDefaultValues.Descriptor.Fields[5].DefaultValue;
        return this;
      }
      
      public bool HasZeroFloat {
        get { return result.HasZeroFloat; }
      }
      public float ZeroFloat {
        get { return result.ZeroFloat; }
        set { SetZeroFloat(value); }
      }
      public Builder SetZeroFloat(float value) {
        result.hasZeroFloat = true;
        result.zeroFloat_ = value;
        return this;
      }
      public Builder ClearZeroFloat() {
        result.hasZeroFloat = false;
        result.zeroFloat_ = 0F;
        return this;
      }
      
      public bool HasOneFloat {
        get { return result.HasOneFloat; }
      }
      public float OneFloat {
        get { return result.OneFloat; }
        set { SetOneFloat(value); }
      }
      public Builder SetOneFloat(float value) {
        result.hasOneFloat = true;
        result.oneFloat_ = value;
        return this;
      }
      public Builder ClearOneFloat() {
        result.hasOneFloat = false;
        result.oneFloat_ = 1F;
        return this;
      }
      
      public bool HasSmallFloat {
        get { return result.HasSmallFloat; }
      }
      public float SmallFloat {
        get { return result.SmallFloat; }
        set { SetSmallFloat(value); }
      }
      public Builder SetSmallFloat(float value) {
        result.hasSmallFloat = true;
        result.smallFloat_ = value;
        return this;
      }
      public Builder ClearSmallFloat() {
        result.hasSmallFloat = false;
        result.smallFloat_ = 1.5F;
        return this;
      }
      
      public bool HasNegativeOneFloat {
        get { return result.HasNegativeOneFloat; }
      }
      public float NegativeOneFloat {
        get { return result.NegativeOneFloat; }
        set { SetNegativeOneFloat(value); }
      }
      public Builder SetNegativeOneFloat(float value) {
        result.hasNegativeOneFloat = true;
        result.negativeOneFloat_ = value;
        return this;
      }
      public Builder ClearNegativeOneFloat() {
        result.hasNegativeOneFloat = false;
        result.negativeOneFloat_ = -1F;
        return this;
      }
      
      public bool HasNegativeFloat {
        get { return result.HasNegativeFloat; }
      }
      public float NegativeFloat {
        get { return result.NegativeFloat; }
        set { SetNegativeFloat(value); }
      }
      public Builder SetNegativeFloat(float value) {
        result.hasNegativeFloat = true;
        result.negativeFloat_ = value;
        return this;
      }
      public Builder ClearNegativeFloat() {
        result.hasNegativeFloat = false;
        result.negativeFloat_ = -1.5F;
        return this;
      }
      
      public bool HasLargeFloat {
        get { return result.HasLargeFloat; }
      }
      public float LargeFloat {
        get { return result.LargeFloat; }
        set { SetLargeFloat(value); }
      }
      public Builder SetLargeFloat(float value) {
        result.hasLargeFloat = true;
        result.largeFloat_ = value;
        return this;
      }
      public Builder ClearLargeFloat() {
        result.hasLargeFloat = false;
        result.largeFloat_ = 2E+08F;
        return this;
      }
      
      public bool HasSmallNegativeFloat {
        get { return result.HasSmallNegativeFloat; }
      }
      public float SmallNegativeFloat {
        get { return result.SmallNegativeFloat; }
        set { SetSmallNegativeFloat(value); }
      }
      public Builder SetSmallNegativeFloat(float value) {
        result.hasSmallNegativeFloat = true;
        result.smallNegativeFloat_ = value;
        return this;
      }
      public Builder ClearSmallNegativeFloat() {
        result.hasSmallNegativeFloat = false;
        result.smallNegativeFloat_ = -8E-28F;
        return this;
      }
      
      public bool HasInfDouble {
        get { return result.HasInfDouble; }
      }
      public double InfDouble {
        get { return result.InfDouble; }
        set { SetInfDouble(value); }
      }
      public Builder SetInfDouble(double value) {
        result.hasInfDouble = true;
        result.infDouble_ = value;
        return this;
      }
      public Builder ClearInfDouble() {
        result.hasInfDouble = false;
        result.infDouble_ = double.PositiveInfinity;
        return this;
      }
      
      public bool HasNegInfDouble {
        get { return result.HasNegInfDouble; }
      }
      public double NegInfDouble {
        get { return result.NegInfDouble; }
        set { SetNegInfDouble(value); }
      }
      public Builder SetNegInfDouble(double value) {
        result.hasNegInfDouble = true;
        result.negInfDouble_ = value;
        return this;
      }
      public Builder ClearNegInfDouble() {
        result.hasNegInfDouble = false;
        result.negInfDouble_ = double.NegativeInfinity;
        return this;
      }
      
      public bool HasNanDouble {
        get { return result.HasNanDouble; }
      }
      public double NanDouble {
        get { return result.NanDouble; }
        set { SetNanDouble(value); }
      }
      public Builder SetNanDouble(double value) {
        result.hasNanDouble = true;
        result.nanDouble_ = value;
        return this;
      }
      public Builder ClearNanDouble() {
        result.hasNanDouble = false;
        result.nanDouble_ = double.NaN;
        return this;
      }
      
      public bool HasInfFloat {
        get { return result.HasInfFloat; }
      }
      public float InfFloat {
        get { return result.InfFloat; }
        set { SetInfFloat(value); }
      }
      public Builder SetInfFloat(float value) {
        result.hasInfFloat = true;
        result.infFloat_ = value;
        return this;
      }
      public Builder ClearInfFloat() {
        result.hasInfFloat = false;
        result.infFloat_ = float.PositiveInfinity;
        return this;
      }
      
      public bool HasNegInfFloat {
        get { return result.HasNegInfFloat; }
      }
      public float NegInfFloat {
        get { return result.NegInfFloat; }
        set { SetNegInfFloat(value); }
      }
      public Builder SetNegInfFloat(float value) {
        result.hasNegInfFloat = true;
        result.negInfFloat_ = value;
        return this;
      }
      public Builder ClearNegInfFloat() {
        result.hasNegInfFloat = false;
        result.negInfFloat_ = float.NegativeInfinity;
        return this;
      }
      
      public bool HasNanFloat {
        get { return result.HasNanFloat; }
      }
      public float NanFloat {
        get { return result.NanFloat; }
        set { SetNanFloat(value); }
      }
      public Builder SetNanFloat(float value) {
        result.hasNanFloat = true;
        result.nanFloat_ = value;
        return this;
      }
      public Builder ClearNanFloat() {
        result.hasNanFloat = false;
        result.nanFloat_ = float.NaN;
        return this;
      }
    }
    static TestExtremeDefaultValues() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 OneString : pb::GeneratedMessage<OneString, OneString.Builder> {
    private static readonly OneString defaultInstance = new Builder().BuildPartial();
    public static OneString DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override OneString DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override OneString ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_OneString__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<OneString, OneString.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_OneString__FieldAccessorTable; }
    }
    
    public const int DataFieldNumber = 1;
    private bool hasData;
    private string data_ = "";
    public bool HasData {
      get { return hasData; }
    }
    public string Data {
      get { return data_; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (HasData) {
        output.WriteString(1, "data", Data);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasData) {
          size += pb::CodedOutputStream.ComputeStringSize(1, Data);
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static OneString ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static OneString ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static OneString ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static OneString ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static OneString ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static OneString ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static OneString ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static OneString ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static OneString ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static OneString 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(OneString 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<OneString, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      OneString result = new OneString();
      
      protected override OneString MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new OneString();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.OneString.Descriptor; }
      }
      
      public override OneString DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.OneString.DefaultInstance; }
      }
      
      public override OneString BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        OneString returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is OneString) {
          return MergeFrom((OneString) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(OneString other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.OneString.DefaultInstance) return this;
        if (other.HasData) {
          Data = other.Data;
        }
        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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
            case 10: {
              result.hasData |= input.ReadString(ref result.data_);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      public bool HasData {
        get { return result.HasData; }
      }
      public string Data {
        get { return result.Data; }
        set { SetData(value); }
      }
      public Builder SetData(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasData = true;
        result.data_ = value;
        return this;
      }
      public Builder ClearData() {
        result.hasData = false;
        result.data_ = "";
        return this;
      }
    }
    static OneString() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 OneBytes : pb::GeneratedMessage<OneBytes, OneBytes.Builder> {
    private static readonly OneBytes defaultInstance = new Builder().BuildPartial();
    public static OneBytes DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override OneBytes DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override OneBytes ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_OneBytes__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<OneBytes, OneBytes.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_OneBytes__FieldAccessorTable; }
    }
    
    public const int DataFieldNumber = 1;
    private bool hasData;
    private pb::ByteString data_ = pb::ByteString.Empty;
    public bool HasData {
      get { return hasData; }
    }
    public pb::ByteString Data {
      get { return data_; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (HasData) {
        output.WriteBytes(1, "data", Data);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasData) {
          size += pb::CodedOutputStream.ComputeBytesSize(1, Data);
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static OneBytes ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static OneBytes ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static OneBytes ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static OneBytes ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static OneBytes ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static OneBytes ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static OneBytes ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static OneBytes ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static OneBytes ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static OneBytes 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(OneBytes 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<OneBytes, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      OneBytes result = new OneBytes();
      
      protected override OneBytes MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new OneBytes();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.OneBytes.Descriptor; }
      }
      
      public override OneBytes DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.OneBytes.DefaultInstance; }
      }
      
      public override OneBytes BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        OneBytes returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is OneBytes) {
          return MergeFrom((OneBytes) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(OneBytes other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.OneBytes.DefaultInstance) return this;
        if (other.HasData) {
          Data = other.Data;
        }
        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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
            case 10: {
              result.hasData |= input.ReadBytes(ref result.data_);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      public bool HasData {
        get { return result.HasData; }
      }
      public pb::ByteString Data {
        get { return result.Data; }
        set { SetData(value); }
      }
      public Builder SetData(pb::ByteString value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasData = true;
        result.data_ = value;
        return this;
      }
      public Builder ClearData() {
        result.hasData = false;
        result.data_ = pb::ByteString.Empty;
        return this;
      }
    }
    static OneBytes() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 TestPackedTypes : pb::GeneratedMessage<TestPackedTypes, TestPackedTypes.Builder> {
    private static readonly TestPackedTypes defaultInstance = new Builder().BuildPartial();
    public static TestPackedTypes DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestPackedTypes DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestPackedTypes ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestPackedTypes__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestPackedTypes, TestPackedTypes.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestPackedTypes__FieldAccessorTable; }
    }
    
    public const int PackedInt32FieldNumber = 90;
    private int packedInt32MemoizedSerializedSize;
    private pbc::PopsicleList<int> packedInt32_ = new pbc::PopsicleList<int>();
    public scg::IList<int> PackedInt32List {
      get { return pbc::Lists.AsReadOnly(packedInt32_); }
    }
    public int PackedInt32Count {
      get { return packedInt32_.Count; }
    }
    public int GetPackedInt32(int index) {
      return packedInt32_[index];
    }
    
    public const int PackedInt64FieldNumber = 91;
    private int packedInt64MemoizedSerializedSize;
    private pbc::PopsicleList<long> packedInt64_ = new pbc::PopsicleList<long>();
    public scg::IList<long> PackedInt64List {
      get { return pbc::Lists.AsReadOnly(packedInt64_); }
    }
    public int PackedInt64Count {
      get { return packedInt64_.Count; }
    }
    public long GetPackedInt64(int index) {
      return packedInt64_[index];
    }
    
    public const int PackedUint32FieldNumber = 92;
    private int packedUint32MemoizedSerializedSize;
    private pbc::PopsicleList<uint> packedUint32_ = new pbc::PopsicleList<uint>();
    [global::System.CLSCompliant(false)]
    public scg::IList<uint> PackedUint32List {
      get { return pbc::Lists.AsReadOnly(packedUint32_); }
    }
    public int PackedUint32Count {
      get { return packedUint32_.Count; }
    }
    [global::System.CLSCompliant(false)]
    public uint GetPackedUint32(int index) {
      return packedUint32_[index];
    }
    
    public const int PackedUint64FieldNumber = 93;
    private int packedUint64MemoizedSerializedSize;
    private pbc::PopsicleList<ulong> packedUint64_ = new pbc::PopsicleList<ulong>();
    [global::System.CLSCompliant(false)]
    public scg::IList<ulong> PackedUint64List {
      get { return pbc::Lists.AsReadOnly(packedUint64_); }
    }
    public int PackedUint64Count {
      get { return packedUint64_.Count; }
    }
    [global::System.CLSCompliant(false)]
    public ulong GetPackedUint64(int index) {
      return packedUint64_[index];
    }
    
    public const int PackedSint32FieldNumber = 94;
    private int packedSint32MemoizedSerializedSize;
    private pbc::PopsicleList<int> packedSint32_ = new pbc::PopsicleList<int>();
    public scg::IList<int> PackedSint32List {
      get { return pbc::Lists.AsReadOnly(packedSint32_); }
    }
    public int PackedSint32Count {
      get { return packedSint32_.Count; }
    }
    public int GetPackedSint32(int index) {
      return packedSint32_[index];
    }
    
    public const int PackedSint64FieldNumber = 95;
    private int packedSint64MemoizedSerializedSize;
    private pbc::PopsicleList<long> packedSint64_ = new pbc::PopsicleList<long>();
    public scg::IList<long> PackedSint64List {
      get { return pbc::Lists.AsReadOnly(packedSint64_); }
    }
    public int PackedSint64Count {
      get { return packedSint64_.Count; }
    }
    public long GetPackedSint64(int index) {
      return packedSint64_[index];
    }
    
    public const int PackedFixed32FieldNumber = 96;
    private int packedFixed32MemoizedSerializedSize;
    private pbc::PopsicleList<uint> packedFixed32_ = new pbc::PopsicleList<uint>();
    [global::System.CLSCompliant(false)]
    public scg::IList<uint> PackedFixed32List {
      get { return pbc::Lists.AsReadOnly(packedFixed32_); }
    }
    public int PackedFixed32Count {
      get { return packedFixed32_.Count; }
    }
    [global::System.CLSCompliant(false)]
    public uint GetPackedFixed32(int index) {
      return packedFixed32_[index];
    }
    
    public const int PackedFixed64FieldNumber = 97;
    private int packedFixed64MemoizedSerializedSize;
    private pbc::PopsicleList<ulong> packedFixed64_ = new pbc::PopsicleList<ulong>();
    [global::System.CLSCompliant(false)]
    public scg::IList<ulong> PackedFixed64List {
      get { return pbc::Lists.AsReadOnly(packedFixed64_); }
    }
    public int PackedFixed64Count {
      get { return packedFixed64_.Count; }
    }
    [global::System.CLSCompliant(false)]
    public ulong GetPackedFixed64(int index) {
      return packedFixed64_[index];
    }
    
    public const int PackedSfixed32FieldNumber = 98;
    private int packedSfixed32MemoizedSerializedSize;
    private pbc::PopsicleList<int> packedSfixed32_ = new pbc::PopsicleList<int>();
    public scg::IList<int> PackedSfixed32List {
      get { return pbc::Lists.AsReadOnly(packedSfixed32_); }
    }
    public int PackedSfixed32Count {
      get { return packedSfixed32_.Count; }
    }
    public int GetPackedSfixed32(int index) {
      return packedSfixed32_[index];
    }
    
    public const int PackedSfixed64FieldNumber = 99;
    private int packedSfixed64MemoizedSerializedSize;
    private pbc::PopsicleList<long> packedSfixed64_ = new pbc::PopsicleList<long>();
    public scg::IList<long> PackedSfixed64List {
      get { return pbc::Lists.AsReadOnly(packedSfixed64_); }
    }
    public int PackedSfixed64Count {
      get { return packedSfixed64_.Count; }
    }
    public long GetPackedSfixed64(int index) {
      return packedSfixed64_[index];
    }
    
    public const int PackedFloatFieldNumber = 100;
    private int packedFloatMemoizedSerializedSize;
    private pbc::PopsicleList<float> packedFloat_ = new pbc::PopsicleList<float>();
    public scg::IList<float> PackedFloatList {
      get { return pbc::Lists.AsReadOnly(packedFloat_); }
    }
    public int PackedFloatCount {
      get { return packedFloat_.Count; }
    }
    public float GetPackedFloat(int index) {
      return packedFloat_[index];
    }
    
    public const int PackedDoubleFieldNumber = 101;
    private int packedDoubleMemoizedSerializedSize;
    private pbc::PopsicleList<double> packedDouble_ = new pbc::PopsicleList<double>();
    public scg::IList<double> PackedDoubleList {
      get { return pbc::Lists.AsReadOnly(packedDouble_); }
    }
    public int PackedDoubleCount {
      get { return packedDouble_.Count; }
    }
    public double GetPackedDouble(int index) {
      return packedDouble_[index];
    }
    
    public const int PackedBoolFieldNumber = 102;
    private int packedBoolMemoizedSerializedSize;
    private pbc::PopsicleList<bool> packedBool_ = new pbc::PopsicleList<bool>();
    public scg::IList<bool> PackedBoolList {
      get { return pbc::Lists.AsReadOnly(packedBool_); }
    }
    public int PackedBoolCount {
      get { return packedBool_.Count; }
    }
    public bool GetPackedBool(int index) {
      return packedBool_[index];
    }
    
    public const int PackedEnumFieldNumber = 103;
    private int packedEnumMemoizedSerializedSize;
    private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> packedEnum_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>();
    public scg::IList<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> PackedEnumList {
      get { return pbc::Lists.AsReadOnly(packedEnum_); }
    }
    public int PackedEnumCount {
      get { return packedEnum_.Count; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ForeignEnum GetPackedEnum(int index) {
      return packedEnum_[index];
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (packedInt32_.Count > 0) {
        output.WritePackedArray(pbd::FieldType.Int32, 90, "packed_int32", packedInt32MemoizedSerializedSize, packedInt32_);
      }
      if (packedInt64_.Count > 0) {
        output.WritePackedArray(pbd::FieldType.Int64, 91, "packed_int64", packedInt64MemoizedSerializedSize, packedInt64_);
      }
      if (packedUint32_.Count > 0) {
        output.WritePackedArray(pbd::FieldType.UInt32, 92, "packed_uint32", packedUint32MemoizedSerializedSize, packedUint32_);
      }
      if (packedUint64_.Count > 0) {
        output.WritePackedArray(pbd::FieldType.UInt64, 93, "packed_uint64", packedUint64MemoizedSerializedSize, packedUint64_);
      }
      if (packedSint32_.Count > 0) {
        output.WritePackedArray(pbd::FieldType.SInt32, 94, "packed_sint32", packedSint32MemoizedSerializedSize, packedSint32_);
      }
      if (packedSint64_.Count > 0) {
        output.WritePackedArray(pbd::FieldType.SInt64, 95, "packed_sint64", packedSint64MemoizedSerializedSize, packedSint64_);
      }
      if (packedFixed32_.Count > 0) {
        output.WritePackedArray(pbd::FieldType.Fixed32, 96, "packed_fixed32", packedFixed32MemoizedSerializedSize, packedFixed32_);
      }
      if (packedFixed64_.Count > 0) {
        output.WritePackedArray(pbd::FieldType.Fixed64, 97, "packed_fixed64", packedFixed64MemoizedSerializedSize, packedFixed64_);
      }
      if (packedSfixed32_.Count > 0) {
        output.WritePackedArray(pbd::FieldType.SFixed32, 98, "packed_sfixed32", packedSfixed32MemoizedSerializedSize, packedSfixed32_);
      }
      if (packedSfixed64_.Count > 0) {
        output.WritePackedArray(pbd::FieldType.SFixed64, 99, "packed_sfixed64", packedSfixed64MemoizedSerializedSize, packedSfixed64_);
      }
      if (packedFloat_.Count > 0) {
        output.WritePackedArray(pbd::FieldType.Float, 100, "packed_float", packedFloatMemoizedSerializedSize, packedFloat_);
      }
      if (packedDouble_.Count > 0) {
        output.WritePackedArray(pbd::FieldType.Double, 101, "packed_double", packedDoubleMemoizedSerializedSize, packedDouble_);
      }
      if (packedBool_.Count > 0) {
        output.WritePackedArray(pbd::FieldType.Bool, 102, "packed_bool", packedBoolMemoizedSerializedSize, packedBool_);
      }
      if (packedEnum_.Count > 0) {
        output.WritePackedArray(pbd::FieldType.Enum, 103, "packed_enum", packedEnumMemoizedSerializedSize, packedEnum_);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        {
          int dataSize = 0;
          foreach (int element in PackedInt32List) {
            dataSize += pb::CodedOutputStream.ComputeInt32SizeNoTag(element);
          }
          size += dataSize;
          if (packedInt32_.Count != 0) {
            size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);
          }
          packedInt32MemoizedSerializedSize = dataSize;
        }
        {
          int dataSize = 0;
          foreach (long element in PackedInt64List) {
            dataSize += pb::CodedOutputStream.ComputeInt64SizeNoTag(element);
          }
          size += dataSize;
          if (packedInt64_.Count != 0) {
            size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);
          }
          packedInt64MemoizedSerializedSize = dataSize;
        }
        {
          int dataSize = 0;
          foreach (uint element in PackedUint32List) {
            dataSize += pb::CodedOutputStream.ComputeUInt32SizeNoTag(element);
          }
          size += dataSize;
          if (packedUint32_.Count != 0) {
            size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);
          }
          packedUint32MemoizedSerializedSize = dataSize;
        }
        {
          int dataSize = 0;
          foreach (ulong element in PackedUint64List) {
            dataSize += pb::CodedOutputStream.ComputeUInt64SizeNoTag(element);
          }
          size += dataSize;
          if (packedUint64_.Count != 0) {
            size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);
          }
          packedUint64MemoizedSerializedSize = dataSize;
        }
        {
          int dataSize = 0;
          foreach (int element in PackedSint32List) {
            dataSize += pb::CodedOutputStream.ComputeSInt32SizeNoTag(element);
          }
          size += dataSize;
          if (packedSint32_.Count != 0) {
            size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);
          }
          packedSint32MemoizedSerializedSize = dataSize;
        }
        {
          int dataSize = 0;
          foreach (long element in PackedSint64List) {
            dataSize += pb::CodedOutputStream.ComputeSInt64SizeNoTag(element);
          }
          size += dataSize;
          if (packedSint64_.Count != 0) {
            size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);
          }
          packedSint64MemoizedSerializedSize = dataSize;
        }
        {
          int dataSize = 0;
          dataSize = 4 * packedFixed32_.Count;
          size += dataSize;
          if (packedFixed32_.Count != 0) {
            size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);
          }
          packedFixed32MemoizedSerializedSize = dataSize;
        }
        {
          int dataSize = 0;
          dataSize = 8 * packedFixed64_.Count;
          size += dataSize;
          if (packedFixed64_.Count != 0) {
            size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);
          }
          packedFixed64MemoizedSerializedSize = dataSize;
        }
        {
          int dataSize = 0;
          dataSize = 4 * packedSfixed32_.Count;
          size += dataSize;
          if (packedSfixed32_.Count != 0) {
            size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);
          }
          packedSfixed32MemoizedSerializedSize = dataSize;
        }
        {
          int dataSize = 0;
          dataSize = 8 * packedSfixed64_.Count;
          size += dataSize;
          if (packedSfixed64_.Count != 0) {
            size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);
          }
          packedSfixed64MemoizedSerializedSize = dataSize;
        }
        {
          int dataSize = 0;
          dataSize = 4 * packedFloat_.Count;
          size += dataSize;
          if (packedFloat_.Count != 0) {
            size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);
          }
          packedFloatMemoizedSerializedSize = dataSize;
        }
        {
          int dataSize = 0;
          dataSize = 8 * packedDouble_.Count;
          size += dataSize;
          if (packedDouble_.Count != 0) {
            size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);
          }
          packedDoubleMemoizedSerializedSize = dataSize;
        }
        {
          int dataSize = 0;
          dataSize = 1 * packedBool_.Count;
          size += dataSize;
          if (packedBool_.Count != 0) {
            size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);
          }
          packedBoolMemoizedSerializedSize = dataSize;
        }
        {
          int dataSize = 0;
          if (packedEnum_.Count > 0) {
            foreach (global::Google.ProtocolBuffers.TestProtos.ForeignEnum element in packedEnum_) {
              dataSize += pb::CodedOutputStream.ComputeEnumSizeNoTag((int) element);
            }
            size += dataSize;
            size += 2;
            size += pb::CodedOutputStream.ComputeRawVarint32Size((uint) dataSize);
          }
          packedEnumMemoizedSerializedSize = dataSize;
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static TestPackedTypes ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestPackedTypes ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestPackedTypes ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestPackedTypes ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestPackedTypes ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestPackedTypes ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestPackedTypes ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestPackedTypes ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestPackedTypes ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestPackedTypes 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(TestPackedTypes 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<TestPackedTypes, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestPackedTypes result = new TestPackedTypes();
      
      protected override TestPackedTypes MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestPackedTypes();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestPackedTypes.Descriptor; }
      }
      
      public override TestPackedTypes DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestPackedTypes.DefaultInstance; }
      }
      
      public override TestPackedTypes BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        result.packedInt32_.MakeReadOnly();
        result.packedInt64_.MakeReadOnly();
        result.packedUint32_.MakeReadOnly();
        result.packedUint64_.MakeReadOnly();
        result.packedSint32_.MakeReadOnly();
        result.packedSint64_.MakeReadOnly();
        result.packedFixed32_.MakeReadOnly();
        result.packedFixed64_.MakeReadOnly();
        result.packedSfixed32_.MakeReadOnly();
        result.packedSfixed64_.MakeReadOnly();
        result.packedFloat_.MakeReadOnly();
        result.packedDouble_.MakeReadOnly();
        result.packedBool_.MakeReadOnly();
        result.packedEnum_.MakeReadOnly();
        TestPackedTypes returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestPackedTypes) {
          return MergeFrom((TestPackedTypes) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestPackedTypes other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestPackedTypes.DefaultInstance) return this;
        if (other.packedInt32_.Count != 0) {
          base.AddRange(other.packedInt32_, result.packedInt32_);
        }
        if (other.packedInt64_.Count != 0) {
          base.AddRange(other.packedInt64_, result.packedInt64_);
        }
        if (other.packedUint32_.Count != 0) {
          base.AddRange(other.packedUint32_, result.packedUint32_);
        }
        if (other.packedUint64_.Count != 0) {
          base.AddRange(other.packedUint64_, result.packedUint64_);
        }
        if (other.packedSint32_.Count != 0) {
          base.AddRange(other.packedSint32_, result.packedSint32_);
        }
        if (other.packedSint64_.Count != 0) {
          base.AddRange(other.packedSint64_, result.packedSint64_);
        }
        if (other.packedFixed32_.Count != 0) {
          base.AddRange(other.packedFixed32_, result.packedFixed32_);
        }
        if (other.packedFixed64_.Count != 0) {
          base.AddRange(other.packedFixed64_, result.packedFixed64_);
        }
        if (other.packedSfixed32_.Count != 0) {
          base.AddRange(other.packedSfixed32_, result.packedSfixed32_);
        }
        if (other.packedSfixed64_.Count != 0) {
          base.AddRange(other.packedSfixed64_, result.packedSfixed64_);
        }
        if (other.packedFloat_.Count != 0) {
          base.AddRange(other.packedFloat_, result.packedFloat_);
        }
        if (other.packedDouble_.Count != 0) {
          base.AddRange(other.packedDouble_, result.packedDouble_);
        }
        if (other.packedBool_.Count != 0) {
          base.AddRange(other.packedBool_, result.packedBool_);
        }
        if (other.packedEnum_.Count != 0) {
          base.AddRange(other.packedEnum_, result.packedEnum_);
        }
        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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
            case 722: {
              input.ReadPrimitiveArray(pbd::FieldType.Int32, tag, field_name, result.packedInt32_);
              break;
            }
            case 730: {
              input.ReadPrimitiveArray(pbd::FieldType.Int64, tag, field_name, result.packedInt64_);
              break;
            }
            case 738: {
              input.ReadPrimitiveArray(pbd::FieldType.UInt32, tag, field_name, result.packedUint32_);
              break;
            }
            case 746: {
              input.ReadPrimitiveArray(pbd::FieldType.UInt64, tag, field_name, result.packedUint64_);
              break;
            }
            case 754: {
              input.ReadPrimitiveArray(pbd::FieldType.SInt32, tag, field_name, result.packedSint32_);
              break;
            }
            case 762: {
              input.ReadPrimitiveArray(pbd::FieldType.SInt64, tag, field_name, result.packedSint64_);
              break;
            }
            case 770: {
              input.ReadPrimitiveArray(pbd::FieldType.Fixed32, tag, field_name, result.packedFixed32_);
              break;
            }
            case 778: {
              input.ReadPrimitiveArray(pbd::FieldType.Fixed64, tag, field_name, result.packedFixed64_);
              break;
            }
            case 786: {
              input.ReadPrimitiveArray(pbd::FieldType.SFixed32, tag, field_name, result.packedSfixed32_);
              break;
            }
            case 794: {
              input.ReadPrimitiveArray(pbd::FieldType.SFixed64, tag, field_name, result.packedSfixed64_);
              break;
            }
            case 802: {
              input.ReadPrimitiveArray(pbd::FieldType.Float, tag, field_name, result.packedFloat_);
              break;
            }
            case 810: {
              input.ReadPrimitiveArray(pbd::FieldType.Double, tag, field_name, result.packedDouble_);
              break;
            }
            case 818: {
              input.ReadPrimitiveArray(pbd::FieldType.Bool, tag, field_name, result.packedBool_);
              break;
            }
            case 826: {
              scg::ICollection<object> unknownItems;
              input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>(tag, field_name, result.packedEnum_, out unknownItems);
              if (unknownItems != null) {
                if (unknownFields == null) {
                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                }
                foreach (object rawValue in unknownItems)
                  if (rawValue is int)
                    unknownFields.MergeVarintField(103, (ulong)(int)rawValue);
              }
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      public pbc::IPopsicleList<int> PackedInt32List {
        get { return result.packedInt32_; }
      }
      public int PackedInt32Count {
        get { return result.PackedInt32Count; }
      }
      public int GetPackedInt32(int index) {
        return result.GetPackedInt32(index);
      }
      public Builder SetPackedInt32(int index, int value) {
        result.packedInt32_[index] = value;
        return this;
      }
      public Builder AddPackedInt32(int value) {
        result.packedInt32_.Add(value);
        return this;
      }
      public Builder AddRangePackedInt32(scg::IEnumerable<int> values) {
        base.AddRange(values, result.packedInt32_);
        return this;
      }
      public Builder ClearPackedInt32() {
        result.packedInt32_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<long> PackedInt64List {
        get { return result.packedInt64_; }
      }
      public int PackedInt64Count {
        get { return result.PackedInt64Count; }
      }
      public long GetPackedInt64(int index) {
        return result.GetPackedInt64(index);
      }
      public Builder SetPackedInt64(int index, long value) {
        result.packedInt64_[index] = value;
        return this;
      }
      public Builder AddPackedInt64(long value) {
        result.packedInt64_.Add(value);
        return this;
      }
      public Builder AddRangePackedInt64(scg::IEnumerable<long> values) {
        base.AddRange(values, result.packedInt64_);
        return this;
      }
      public Builder ClearPackedInt64() {
        result.packedInt64_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<uint> PackedUint32List {
        get { return result.packedUint32_; }
      }
      public int PackedUint32Count {
        get { return result.PackedUint32Count; }
      }
      [global::System.CLSCompliant(false)]
      public uint GetPackedUint32(int index) {
        return result.GetPackedUint32(index);
      }
      [global::System.CLSCompliant(false)]
      public Builder SetPackedUint32(int index, uint value) {
        result.packedUint32_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddPackedUint32(uint value) {
        result.packedUint32_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangePackedUint32(scg::IEnumerable<uint> values) {
        base.AddRange(values, result.packedUint32_);
        return this;
      }
      public Builder ClearPackedUint32() {
        result.packedUint32_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<ulong> PackedUint64List {
        get { return result.packedUint64_; }
      }
      public int PackedUint64Count {
        get { return result.PackedUint64Count; }
      }
      [global::System.CLSCompliant(false)]
      public ulong GetPackedUint64(int index) {
        return result.GetPackedUint64(index);
      }
      [global::System.CLSCompliant(false)]
      public Builder SetPackedUint64(int index, ulong value) {
        result.packedUint64_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddPackedUint64(ulong value) {
        result.packedUint64_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangePackedUint64(scg::IEnumerable<ulong> values) {
        base.AddRange(values, result.packedUint64_);
        return this;
      }
      public Builder ClearPackedUint64() {
        result.packedUint64_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<int> PackedSint32List {
        get { return result.packedSint32_; }
      }
      public int PackedSint32Count {
        get { return result.PackedSint32Count; }
      }
      public int GetPackedSint32(int index) {
        return result.GetPackedSint32(index);
      }
      public Builder SetPackedSint32(int index, int value) {
        result.packedSint32_[index] = value;
        return this;
      }
      public Builder AddPackedSint32(int value) {
        result.packedSint32_.Add(value);
        return this;
      }
      public Builder AddRangePackedSint32(scg::IEnumerable<int> values) {
        base.AddRange(values, result.packedSint32_);
        return this;
      }
      public Builder ClearPackedSint32() {
        result.packedSint32_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<long> PackedSint64List {
        get { return result.packedSint64_; }
      }
      public int PackedSint64Count {
        get { return result.PackedSint64Count; }
      }
      public long GetPackedSint64(int index) {
        return result.GetPackedSint64(index);
      }
      public Builder SetPackedSint64(int index, long value) {
        result.packedSint64_[index] = value;
        return this;
      }
      public Builder AddPackedSint64(long value) {
        result.packedSint64_.Add(value);
        return this;
      }
      public Builder AddRangePackedSint64(scg::IEnumerable<long> values) {
        base.AddRange(values, result.packedSint64_);
        return this;
      }
      public Builder ClearPackedSint64() {
        result.packedSint64_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<uint> PackedFixed32List {
        get { return result.packedFixed32_; }
      }
      public int PackedFixed32Count {
        get { return result.PackedFixed32Count; }
      }
      [global::System.CLSCompliant(false)]
      public uint GetPackedFixed32(int index) {
        return result.GetPackedFixed32(index);
      }
      [global::System.CLSCompliant(false)]
      public Builder SetPackedFixed32(int index, uint value) {
        result.packedFixed32_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddPackedFixed32(uint value) {
        result.packedFixed32_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangePackedFixed32(scg::IEnumerable<uint> values) {
        base.AddRange(values, result.packedFixed32_);
        return this;
      }
      public Builder ClearPackedFixed32() {
        result.packedFixed32_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<ulong> PackedFixed64List {
        get { return result.packedFixed64_; }
      }
      public int PackedFixed64Count {
        get { return result.PackedFixed64Count; }
      }
      [global::System.CLSCompliant(false)]
      public ulong GetPackedFixed64(int index) {
        return result.GetPackedFixed64(index);
      }
      [global::System.CLSCompliant(false)]
      public Builder SetPackedFixed64(int index, ulong value) {
        result.packedFixed64_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddPackedFixed64(ulong value) {
        result.packedFixed64_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangePackedFixed64(scg::IEnumerable<ulong> values) {
        base.AddRange(values, result.packedFixed64_);
        return this;
      }
      public Builder ClearPackedFixed64() {
        result.packedFixed64_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<int> PackedSfixed32List {
        get { return result.packedSfixed32_; }
      }
      public int PackedSfixed32Count {
        get { return result.PackedSfixed32Count; }
      }
      public int GetPackedSfixed32(int index) {
        return result.GetPackedSfixed32(index);
      }
      public Builder SetPackedSfixed32(int index, int value) {
        result.packedSfixed32_[index] = value;
        return this;
      }
      public Builder AddPackedSfixed32(int value) {
        result.packedSfixed32_.Add(value);
        return this;
      }
      public Builder AddRangePackedSfixed32(scg::IEnumerable<int> values) {
        base.AddRange(values, result.packedSfixed32_);
        return this;
      }
      public Builder ClearPackedSfixed32() {
        result.packedSfixed32_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<long> PackedSfixed64List {
        get { return result.packedSfixed64_; }
      }
      public int PackedSfixed64Count {
        get { return result.PackedSfixed64Count; }
      }
      public long GetPackedSfixed64(int index) {
        return result.GetPackedSfixed64(index);
      }
      public Builder SetPackedSfixed64(int index, long value) {
        result.packedSfixed64_[index] = value;
        return this;
      }
      public Builder AddPackedSfixed64(long value) {
        result.packedSfixed64_.Add(value);
        return this;
      }
      public Builder AddRangePackedSfixed64(scg::IEnumerable<long> values) {
        base.AddRange(values, result.packedSfixed64_);
        return this;
      }
      public Builder ClearPackedSfixed64() {
        result.packedSfixed64_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<float> PackedFloatList {
        get { return result.packedFloat_; }
      }
      public int PackedFloatCount {
        get { return result.PackedFloatCount; }
      }
      public float GetPackedFloat(int index) {
        return result.GetPackedFloat(index);
      }
      public Builder SetPackedFloat(int index, float value) {
        result.packedFloat_[index] = value;
        return this;
      }
      public Builder AddPackedFloat(float value) {
        result.packedFloat_.Add(value);
        return this;
      }
      public Builder AddRangePackedFloat(scg::IEnumerable<float> values) {
        base.AddRange(values, result.packedFloat_);
        return this;
      }
      public Builder ClearPackedFloat() {
        result.packedFloat_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<double> PackedDoubleList {
        get { return result.packedDouble_; }
      }
      public int PackedDoubleCount {
        get { return result.PackedDoubleCount; }
      }
      public double GetPackedDouble(int index) {
        return result.GetPackedDouble(index);
      }
      public Builder SetPackedDouble(int index, double value) {
        result.packedDouble_[index] = value;
        return this;
      }
      public Builder AddPackedDouble(double value) {
        result.packedDouble_.Add(value);
        return this;
      }
      public Builder AddRangePackedDouble(scg::IEnumerable<double> values) {
        base.AddRange(values, result.packedDouble_);
        return this;
      }
      public Builder ClearPackedDouble() {
        result.packedDouble_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<bool> PackedBoolList {
        get { return result.packedBool_; }
      }
      public int PackedBoolCount {
        get { return result.PackedBoolCount; }
      }
      public bool GetPackedBool(int index) {
        return result.GetPackedBool(index);
      }
      public Builder SetPackedBool(int index, bool value) {
        result.packedBool_[index] = value;
        return this;
      }
      public Builder AddPackedBool(bool value) {
        result.packedBool_.Add(value);
        return this;
      }
      public Builder AddRangePackedBool(scg::IEnumerable<bool> values) {
        base.AddRange(values, result.packedBool_);
        return this;
      }
      public Builder ClearPackedBool() {
        result.packedBool_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> PackedEnumList {
        get { return result.packedEnum_; }
      }
      public int PackedEnumCount {
        get { return result.PackedEnumCount; }
      }
      public global::Google.ProtocolBuffers.TestProtos.ForeignEnum GetPackedEnum(int index) {
        return result.GetPackedEnum(index);
      }
      public Builder SetPackedEnum(int index, global::Google.ProtocolBuffers.TestProtos.ForeignEnum value) {
        result.packedEnum_[index] = value;
        return this;
      }
      public Builder AddPackedEnum(global::Google.ProtocolBuffers.TestProtos.ForeignEnum value) {
        result.packedEnum_.Add(value);
        return this;
      }
      public Builder AddRangePackedEnum(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> values) {
        base.AddRange(values, result.packedEnum_);
        return this;
      }
      public Builder ClearPackedEnum() {
        result.packedEnum_.Clear();
        return this;
      }
    }
    static TestPackedTypes() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 TestUnpackedTypes : pb::GeneratedMessage<TestUnpackedTypes, TestUnpackedTypes.Builder> {
    private static readonly TestUnpackedTypes defaultInstance = new Builder().BuildPartial();
    public static TestUnpackedTypes DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestUnpackedTypes DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestUnpackedTypes ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestUnpackedTypes__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestUnpackedTypes, TestUnpackedTypes.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestUnpackedTypes__FieldAccessorTable; }
    }
    
    public const int UnpackedInt32FieldNumber = 90;
    private pbc::PopsicleList<int> unpackedInt32_ = new pbc::PopsicleList<int>();
    public scg::IList<int> UnpackedInt32List {
      get { return pbc::Lists.AsReadOnly(unpackedInt32_); }
    }
    public int UnpackedInt32Count {
      get { return unpackedInt32_.Count; }
    }
    public int GetUnpackedInt32(int index) {
      return unpackedInt32_[index];
    }
    
    public const int UnpackedInt64FieldNumber = 91;
    private pbc::PopsicleList<long> unpackedInt64_ = new pbc::PopsicleList<long>();
    public scg::IList<long> UnpackedInt64List {
      get { return pbc::Lists.AsReadOnly(unpackedInt64_); }
    }
    public int UnpackedInt64Count {
      get { return unpackedInt64_.Count; }
    }
    public long GetUnpackedInt64(int index) {
      return unpackedInt64_[index];
    }
    
    public const int UnpackedUint32FieldNumber = 92;
    private pbc::PopsicleList<uint> unpackedUint32_ = new pbc::PopsicleList<uint>();
    [global::System.CLSCompliant(false)]
    public scg::IList<uint> UnpackedUint32List {
      get { return pbc::Lists.AsReadOnly(unpackedUint32_); }
    }
    public int UnpackedUint32Count {
      get { return unpackedUint32_.Count; }
    }
    [global::System.CLSCompliant(false)]
    public uint GetUnpackedUint32(int index) {
      return unpackedUint32_[index];
    }
    
    public const int UnpackedUint64FieldNumber = 93;
    private pbc::PopsicleList<ulong> unpackedUint64_ = new pbc::PopsicleList<ulong>();
    [global::System.CLSCompliant(false)]
    public scg::IList<ulong> UnpackedUint64List {
      get { return pbc::Lists.AsReadOnly(unpackedUint64_); }
    }
    public int UnpackedUint64Count {
      get { return unpackedUint64_.Count; }
    }
    [global::System.CLSCompliant(false)]
    public ulong GetUnpackedUint64(int index) {
      return unpackedUint64_[index];
    }
    
    public const int UnpackedSint32FieldNumber = 94;
    private pbc::PopsicleList<int> unpackedSint32_ = new pbc::PopsicleList<int>();
    public scg::IList<int> UnpackedSint32List {
      get { return pbc::Lists.AsReadOnly(unpackedSint32_); }
    }
    public int UnpackedSint32Count {
      get { return unpackedSint32_.Count; }
    }
    public int GetUnpackedSint32(int index) {
      return unpackedSint32_[index];
    }
    
    public const int UnpackedSint64FieldNumber = 95;
    private pbc::PopsicleList<long> unpackedSint64_ = new pbc::PopsicleList<long>();
    public scg::IList<long> UnpackedSint64List {
      get { return pbc::Lists.AsReadOnly(unpackedSint64_); }
    }
    public int UnpackedSint64Count {
      get { return unpackedSint64_.Count; }
    }
    public long GetUnpackedSint64(int index) {
      return unpackedSint64_[index];
    }
    
    public const int UnpackedFixed32FieldNumber = 96;
    private pbc::PopsicleList<uint> unpackedFixed32_ = new pbc::PopsicleList<uint>();
    [global::System.CLSCompliant(false)]
    public scg::IList<uint> UnpackedFixed32List {
      get { return pbc::Lists.AsReadOnly(unpackedFixed32_); }
    }
    public int UnpackedFixed32Count {
      get { return unpackedFixed32_.Count; }
    }
    [global::System.CLSCompliant(false)]
    public uint GetUnpackedFixed32(int index) {
      return unpackedFixed32_[index];
    }
    
    public const int UnpackedFixed64FieldNumber = 97;
    private pbc::PopsicleList<ulong> unpackedFixed64_ = new pbc::PopsicleList<ulong>();
    [global::System.CLSCompliant(false)]
    public scg::IList<ulong> UnpackedFixed64List {
      get { return pbc::Lists.AsReadOnly(unpackedFixed64_); }
    }
    public int UnpackedFixed64Count {
      get { return unpackedFixed64_.Count; }
    }
    [global::System.CLSCompliant(false)]
    public ulong GetUnpackedFixed64(int index) {
      return unpackedFixed64_[index];
    }
    
    public const int UnpackedSfixed32FieldNumber = 98;
    private pbc::PopsicleList<int> unpackedSfixed32_ = new pbc::PopsicleList<int>();
    public scg::IList<int> UnpackedSfixed32List {
      get { return pbc::Lists.AsReadOnly(unpackedSfixed32_); }
    }
    public int UnpackedSfixed32Count {
      get { return unpackedSfixed32_.Count; }
    }
    public int GetUnpackedSfixed32(int index) {
      return unpackedSfixed32_[index];
    }
    
    public const int UnpackedSfixed64FieldNumber = 99;
    private pbc::PopsicleList<long> unpackedSfixed64_ = new pbc::PopsicleList<long>();
    public scg::IList<long> UnpackedSfixed64List {
      get { return pbc::Lists.AsReadOnly(unpackedSfixed64_); }
    }
    public int UnpackedSfixed64Count {
      get { return unpackedSfixed64_.Count; }
    }
    public long GetUnpackedSfixed64(int index) {
      return unpackedSfixed64_[index];
    }
    
    public const int UnpackedFloatFieldNumber = 100;
    private pbc::PopsicleList<float> unpackedFloat_ = new pbc::PopsicleList<float>();
    public scg::IList<float> UnpackedFloatList {
      get { return pbc::Lists.AsReadOnly(unpackedFloat_); }
    }
    public int UnpackedFloatCount {
      get { return unpackedFloat_.Count; }
    }
    public float GetUnpackedFloat(int index) {
      return unpackedFloat_[index];
    }
    
    public const int UnpackedDoubleFieldNumber = 101;
    private pbc::PopsicleList<double> unpackedDouble_ = new pbc::PopsicleList<double>();
    public scg::IList<double> UnpackedDoubleList {
      get { return pbc::Lists.AsReadOnly(unpackedDouble_); }
    }
    public int UnpackedDoubleCount {
      get { return unpackedDouble_.Count; }
    }
    public double GetUnpackedDouble(int index) {
      return unpackedDouble_[index];
    }
    
    public const int UnpackedBoolFieldNumber = 102;
    private pbc::PopsicleList<bool> unpackedBool_ = new pbc::PopsicleList<bool>();
    public scg::IList<bool> UnpackedBoolList {
      get { return pbc::Lists.AsReadOnly(unpackedBool_); }
    }
    public int UnpackedBoolCount {
      get { return unpackedBool_.Count; }
    }
    public bool GetUnpackedBool(int index) {
      return unpackedBool_[index];
    }
    
    public const int UnpackedEnumFieldNumber = 103;
    private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> unpackedEnum_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>();
    public scg::IList<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> UnpackedEnumList {
      get { return pbc::Lists.AsReadOnly(unpackedEnum_); }
    }
    public int UnpackedEnumCount {
      get { return unpackedEnum_.Count; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ForeignEnum GetUnpackedEnum(int index) {
      return unpackedEnum_[index];
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (unpackedInt32_.Count > 0) {
        output.WriteArray(pbd::FieldType.Int32, 90, "unpacked_int32", unpackedInt32_);
      }
      if (unpackedInt64_.Count > 0) {
        output.WriteArray(pbd::FieldType.Int64, 91, "unpacked_int64", unpackedInt64_);
      }
      if (unpackedUint32_.Count > 0) {
        output.WriteArray(pbd::FieldType.UInt32, 92, "unpacked_uint32", unpackedUint32_);
      }
      if (unpackedUint64_.Count > 0) {
        output.WriteArray(pbd::FieldType.UInt64, 93, "unpacked_uint64", unpackedUint64_);
      }
      if (unpackedSint32_.Count > 0) {
        output.WriteArray(pbd::FieldType.SInt32, 94, "unpacked_sint32", unpackedSint32_);
      }
      if (unpackedSint64_.Count > 0) {
        output.WriteArray(pbd::FieldType.SInt64, 95, "unpacked_sint64", unpackedSint64_);
      }
      if (unpackedFixed32_.Count > 0) {
        output.WriteArray(pbd::FieldType.Fixed32, 96, "unpacked_fixed32", unpackedFixed32_);
      }
      if (unpackedFixed64_.Count > 0) {
        output.WriteArray(pbd::FieldType.Fixed64, 97, "unpacked_fixed64", unpackedFixed64_);
      }
      if (unpackedSfixed32_.Count > 0) {
        output.WriteArray(pbd::FieldType.SFixed32, 98, "unpacked_sfixed32", unpackedSfixed32_);
      }
      if (unpackedSfixed64_.Count > 0) {
        output.WriteArray(pbd::FieldType.SFixed64, 99, "unpacked_sfixed64", unpackedSfixed64_);
      }
      if (unpackedFloat_.Count > 0) {
        output.WriteArray(pbd::FieldType.Float, 100, "unpacked_float", unpackedFloat_);
      }
      if (unpackedDouble_.Count > 0) {
        output.WriteArray(pbd::FieldType.Double, 101, "unpacked_double", unpackedDouble_);
      }
      if (unpackedBool_.Count > 0) {
        output.WriteArray(pbd::FieldType.Bool, 102, "unpacked_bool", unpackedBool_);
      }
      if (unpackedEnum_.Count > 0) {
        output.WriteArray(pbd::FieldType.Enum, 103, "unpacked_enum", unpackedEnum_);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        {
          int dataSize = 0;
          foreach (int element in UnpackedInt32List) {
            dataSize += pb::CodedOutputStream.ComputeInt32SizeNoTag(element);
          }
          size += dataSize;
          size += 2 * unpackedInt32_.Count;
        }
        {
          int dataSize = 0;
          foreach (long element in UnpackedInt64List) {
            dataSize += pb::CodedOutputStream.ComputeInt64SizeNoTag(element);
          }
          size += dataSize;
          size += 2 * unpackedInt64_.Count;
        }
        {
          int dataSize = 0;
          foreach (uint element in UnpackedUint32List) {
            dataSize += pb::CodedOutputStream.ComputeUInt32SizeNoTag(element);
          }
          size += dataSize;
          size += 2 * unpackedUint32_.Count;
        }
        {
          int dataSize = 0;
          foreach (ulong element in UnpackedUint64List) {
            dataSize += pb::CodedOutputStream.ComputeUInt64SizeNoTag(element);
          }
          size += dataSize;
          size += 2 * unpackedUint64_.Count;
        }
        {
          int dataSize = 0;
          foreach (int element in UnpackedSint32List) {
            dataSize += pb::CodedOutputStream.ComputeSInt32SizeNoTag(element);
          }
          size += dataSize;
          size += 2 * unpackedSint32_.Count;
        }
        {
          int dataSize = 0;
          foreach (long element in UnpackedSint64List) {
            dataSize += pb::CodedOutputStream.ComputeSInt64SizeNoTag(element);
          }
          size += dataSize;
          size += 2 * unpackedSint64_.Count;
        }
        {
          int dataSize = 0;
          dataSize = 4 * unpackedFixed32_.Count;
          size += dataSize;
          size += 2 * unpackedFixed32_.Count;
        }
        {
          int dataSize = 0;
          dataSize = 8 * unpackedFixed64_.Count;
          size += dataSize;
          size += 2 * unpackedFixed64_.Count;
        }
        {
          int dataSize = 0;
          dataSize = 4 * unpackedSfixed32_.Count;
          size += dataSize;
          size += 2 * unpackedSfixed32_.Count;
        }
        {
          int dataSize = 0;
          dataSize = 8 * unpackedSfixed64_.Count;
          size += dataSize;
          size += 2 * unpackedSfixed64_.Count;
        }
        {
          int dataSize = 0;
          dataSize = 4 * unpackedFloat_.Count;
          size += dataSize;
          size += 2 * unpackedFloat_.Count;
        }
        {
          int dataSize = 0;
          dataSize = 8 * unpackedDouble_.Count;
          size += dataSize;
          size += 2 * unpackedDouble_.Count;
        }
        {
          int dataSize = 0;
          dataSize = 1 * unpackedBool_.Count;
          size += dataSize;
          size += 2 * unpackedBool_.Count;
        }
        {
          int dataSize = 0;
          if (unpackedEnum_.Count > 0) {
            foreach (global::Google.ProtocolBuffers.TestProtos.ForeignEnum element in unpackedEnum_) {
              dataSize += pb::CodedOutputStream.ComputeEnumSizeNoTag((int) element);
            }
            size += dataSize;
            size += 2 * unpackedEnum_.Count;
          }
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static TestUnpackedTypes ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestUnpackedTypes ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestUnpackedTypes ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestUnpackedTypes ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestUnpackedTypes ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestUnpackedTypes ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestUnpackedTypes ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestUnpackedTypes ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestUnpackedTypes ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestUnpackedTypes 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(TestUnpackedTypes 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<TestUnpackedTypes, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestUnpackedTypes result = new TestUnpackedTypes();
      
      protected override TestUnpackedTypes MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestUnpackedTypes();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestUnpackedTypes.Descriptor; }
      }
      
      public override TestUnpackedTypes DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestUnpackedTypes.DefaultInstance; }
      }
      
      public override TestUnpackedTypes BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        result.unpackedInt32_.MakeReadOnly();
        result.unpackedInt64_.MakeReadOnly();
        result.unpackedUint32_.MakeReadOnly();
        result.unpackedUint64_.MakeReadOnly();
        result.unpackedSint32_.MakeReadOnly();
        result.unpackedSint64_.MakeReadOnly();
        result.unpackedFixed32_.MakeReadOnly();
        result.unpackedFixed64_.MakeReadOnly();
        result.unpackedSfixed32_.MakeReadOnly();
        result.unpackedSfixed64_.MakeReadOnly();
        result.unpackedFloat_.MakeReadOnly();
        result.unpackedDouble_.MakeReadOnly();
        result.unpackedBool_.MakeReadOnly();
        result.unpackedEnum_.MakeReadOnly();
        TestUnpackedTypes returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestUnpackedTypes) {
          return MergeFrom((TestUnpackedTypes) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestUnpackedTypes other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestUnpackedTypes.DefaultInstance) return this;
        if (other.unpackedInt32_.Count != 0) {
          base.AddRange(other.unpackedInt32_, result.unpackedInt32_);
        }
        if (other.unpackedInt64_.Count != 0) {
          base.AddRange(other.unpackedInt64_, result.unpackedInt64_);
        }
        if (other.unpackedUint32_.Count != 0) {
          base.AddRange(other.unpackedUint32_, result.unpackedUint32_);
        }
        if (other.unpackedUint64_.Count != 0) {
          base.AddRange(other.unpackedUint64_, result.unpackedUint64_);
        }
        if (other.unpackedSint32_.Count != 0) {
          base.AddRange(other.unpackedSint32_, result.unpackedSint32_);
        }
        if (other.unpackedSint64_.Count != 0) {
          base.AddRange(other.unpackedSint64_, result.unpackedSint64_);
        }
        if (other.unpackedFixed32_.Count != 0) {
          base.AddRange(other.unpackedFixed32_, result.unpackedFixed32_);
        }
        if (other.unpackedFixed64_.Count != 0) {
          base.AddRange(other.unpackedFixed64_, result.unpackedFixed64_);
        }
        if (other.unpackedSfixed32_.Count != 0) {
          base.AddRange(other.unpackedSfixed32_, result.unpackedSfixed32_);
        }
        if (other.unpackedSfixed64_.Count != 0) {
          base.AddRange(other.unpackedSfixed64_, result.unpackedSfixed64_);
        }
        if (other.unpackedFloat_.Count != 0) {
          base.AddRange(other.unpackedFloat_, result.unpackedFloat_);
        }
        if (other.unpackedDouble_.Count != 0) {
          base.AddRange(other.unpackedDouble_, result.unpackedDouble_);
        }
        if (other.unpackedBool_.Count != 0) {
          base.AddRange(other.unpackedBool_, result.unpackedBool_);
        }
        if (other.unpackedEnum_.Count != 0) {
          base.AddRange(other.unpackedEnum_, result.unpackedEnum_);
        }
        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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
            case 720: {
              input.ReadPrimitiveArray(pbd::FieldType.Int32, tag, field_name, result.unpackedInt32_);
              break;
            }
            case 728: {
              input.ReadPrimitiveArray(pbd::FieldType.Int64, tag, field_name, result.unpackedInt64_);
              break;
            }
            case 736: {
              input.ReadPrimitiveArray(pbd::FieldType.UInt32, tag, field_name, result.unpackedUint32_);
              break;
            }
            case 744: {
              input.ReadPrimitiveArray(pbd::FieldType.UInt64, tag, field_name, result.unpackedUint64_);
              break;
            }
            case 752: {
              input.ReadPrimitiveArray(pbd::FieldType.SInt32, tag, field_name, result.unpackedSint32_);
              break;
            }
            case 760: {
              input.ReadPrimitiveArray(pbd::FieldType.SInt64, tag, field_name, result.unpackedSint64_);
              break;
            }
            case 773: {
              input.ReadPrimitiveArray(pbd::FieldType.Fixed32, tag, field_name, result.unpackedFixed32_);
              break;
            }
            case 777: {
              input.ReadPrimitiveArray(pbd::FieldType.Fixed64, tag, field_name, result.unpackedFixed64_);
              break;
            }
            case 789: {
              input.ReadPrimitiveArray(pbd::FieldType.SFixed32, tag, field_name, result.unpackedSfixed32_);
              break;
            }
            case 793: {
              input.ReadPrimitiveArray(pbd::FieldType.SFixed64, tag, field_name, result.unpackedSfixed64_);
              break;
            }
            case 805: {
              input.ReadPrimitiveArray(pbd::FieldType.Float, tag, field_name, result.unpackedFloat_);
              break;
            }
            case 809: {
              input.ReadPrimitiveArray(pbd::FieldType.Double, tag, field_name, result.unpackedDouble_);
              break;
            }
            case 816: {
              input.ReadPrimitiveArray(pbd::FieldType.Bool, tag, field_name, result.unpackedBool_);
              break;
            }
            case 824: {
              scg::ICollection<object> unknownItems;
              input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>(tag, field_name, result.unpackedEnum_, out unknownItems);
              if (unknownItems != null) {
                if (unknownFields == null) {
                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                }
                foreach (object rawValue in unknownItems)
                  if (rawValue is int)
                    unknownFields.MergeVarintField(103, (ulong)(int)rawValue);
              }
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      public pbc::IPopsicleList<int> UnpackedInt32List {
        get { return result.unpackedInt32_; }
      }
      public int UnpackedInt32Count {
        get { return result.UnpackedInt32Count; }
      }
      public int GetUnpackedInt32(int index) {
        return result.GetUnpackedInt32(index);
      }
      public Builder SetUnpackedInt32(int index, int value) {
        result.unpackedInt32_[index] = value;
        return this;
      }
      public Builder AddUnpackedInt32(int value) {
        result.unpackedInt32_.Add(value);
        return this;
      }
      public Builder AddRangeUnpackedInt32(scg::IEnumerable<int> values) {
        base.AddRange(values, result.unpackedInt32_);
        return this;
      }
      public Builder ClearUnpackedInt32() {
        result.unpackedInt32_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<long> UnpackedInt64List {
        get { return result.unpackedInt64_; }
      }
      public int UnpackedInt64Count {
        get { return result.UnpackedInt64Count; }
      }
      public long GetUnpackedInt64(int index) {
        return result.GetUnpackedInt64(index);
      }
      public Builder SetUnpackedInt64(int index, long value) {
        result.unpackedInt64_[index] = value;
        return this;
      }
      public Builder AddUnpackedInt64(long value) {
        result.unpackedInt64_.Add(value);
        return this;
      }
      public Builder AddRangeUnpackedInt64(scg::IEnumerable<long> values) {
        base.AddRange(values, result.unpackedInt64_);
        return this;
      }
      public Builder ClearUnpackedInt64() {
        result.unpackedInt64_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<uint> UnpackedUint32List {
        get { return result.unpackedUint32_; }
      }
      public int UnpackedUint32Count {
        get { return result.UnpackedUint32Count; }
      }
      [global::System.CLSCompliant(false)]
      public uint GetUnpackedUint32(int index) {
        return result.GetUnpackedUint32(index);
      }
      [global::System.CLSCompliant(false)]
      public Builder SetUnpackedUint32(int index, uint value) {
        result.unpackedUint32_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddUnpackedUint32(uint value) {
        result.unpackedUint32_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangeUnpackedUint32(scg::IEnumerable<uint> values) {
        base.AddRange(values, result.unpackedUint32_);
        return this;
      }
      public Builder ClearUnpackedUint32() {
        result.unpackedUint32_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<ulong> UnpackedUint64List {
        get { return result.unpackedUint64_; }
      }
      public int UnpackedUint64Count {
        get { return result.UnpackedUint64Count; }
      }
      [global::System.CLSCompliant(false)]
      public ulong GetUnpackedUint64(int index) {
        return result.GetUnpackedUint64(index);
      }
      [global::System.CLSCompliant(false)]
      public Builder SetUnpackedUint64(int index, ulong value) {
        result.unpackedUint64_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddUnpackedUint64(ulong value) {
        result.unpackedUint64_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangeUnpackedUint64(scg::IEnumerable<ulong> values) {
        base.AddRange(values, result.unpackedUint64_);
        return this;
      }
      public Builder ClearUnpackedUint64() {
        result.unpackedUint64_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<int> UnpackedSint32List {
        get { return result.unpackedSint32_; }
      }
      public int UnpackedSint32Count {
        get { return result.UnpackedSint32Count; }
      }
      public int GetUnpackedSint32(int index) {
        return result.GetUnpackedSint32(index);
      }
      public Builder SetUnpackedSint32(int index, int value) {
        result.unpackedSint32_[index] = value;
        return this;
      }
      public Builder AddUnpackedSint32(int value) {
        result.unpackedSint32_.Add(value);
        return this;
      }
      public Builder AddRangeUnpackedSint32(scg::IEnumerable<int> values) {
        base.AddRange(values, result.unpackedSint32_);
        return this;
      }
      public Builder ClearUnpackedSint32() {
        result.unpackedSint32_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<long> UnpackedSint64List {
        get { return result.unpackedSint64_; }
      }
      public int UnpackedSint64Count {
        get { return result.UnpackedSint64Count; }
      }
      public long GetUnpackedSint64(int index) {
        return result.GetUnpackedSint64(index);
      }
      public Builder SetUnpackedSint64(int index, long value) {
        result.unpackedSint64_[index] = value;
        return this;
      }
      public Builder AddUnpackedSint64(long value) {
        result.unpackedSint64_.Add(value);
        return this;
      }
      public Builder AddRangeUnpackedSint64(scg::IEnumerable<long> values) {
        base.AddRange(values, result.unpackedSint64_);
        return this;
      }
      public Builder ClearUnpackedSint64() {
        result.unpackedSint64_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<uint> UnpackedFixed32List {
        get { return result.unpackedFixed32_; }
      }
      public int UnpackedFixed32Count {
        get { return result.UnpackedFixed32Count; }
      }
      [global::System.CLSCompliant(false)]
      public uint GetUnpackedFixed32(int index) {
        return result.GetUnpackedFixed32(index);
      }
      [global::System.CLSCompliant(false)]
      public Builder SetUnpackedFixed32(int index, uint value) {
        result.unpackedFixed32_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddUnpackedFixed32(uint value) {
        result.unpackedFixed32_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangeUnpackedFixed32(scg::IEnumerable<uint> values) {
        base.AddRange(values, result.unpackedFixed32_);
        return this;
      }
      public Builder ClearUnpackedFixed32() {
        result.unpackedFixed32_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<ulong> UnpackedFixed64List {
        get { return result.unpackedFixed64_; }
      }
      public int UnpackedFixed64Count {
        get { return result.UnpackedFixed64Count; }
      }
      [global::System.CLSCompliant(false)]
      public ulong GetUnpackedFixed64(int index) {
        return result.GetUnpackedFixed64(index);
      }
      [global::System.CLSCompliant(false)]
      public Builder SetUnpackedFixed64(int index, ulong value) {
        result.unpackedFixed64_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddUnpackedFixed64(ulong value) {
        result.unpackedFixed64_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangeUnpackedFixed64(scg::IEnumerable<ulong> values) {
        base.AddRange(values, result.unpackedFixed64_);
        return this;
      }
      public Builder ClearUnpackedFixed64() {
        result.unpackedFixed64_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<int> UnpackedSfixed32List {
        get { return result.unpackedSfixed32_; }
      }
      public int UnpackedSfixed32Count {
        get { return result.UnpackedSfixed32Count; }
      }
      public int GetUnpackedSfixed32(int index) {
        return result.GetUnpackedSfixed32(index);
      }
      public Builder SetUnpackedSfixed32(int index, int value) {
        result.unpackedSfixed32_[index] = value;
        return this;
      }
      public Builder AddUnpackedSfixed32(int value) {
        result.unpackedSfixed32_.Add(value);
        return this;
      }
      public Builder AddRangeUnpackedSfixed32(scg::IEnumerable<int> values) {
        base.AddRange(values, result.unpackedSfixed32_);
        return this;
      }
      public Builder ClearUnpackedSfixed32() {
        result.unpackedSfixed32_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<long> UnpackedSfixed64List {
        get { return result.unpackedSfixed64_; }
      }
      public int UnpackedSfixed64Count {
        get { return result.UnpackedSfixed64Count; }
      }
      public long GetUnpackedSfixed64(int index) {
        return result.GetUnpackedSfixed64(index);
      }
      public Builder SetUnpackedSfixed64(int index, long value) {
        result.unpackedSfixed64_[index] = value;
        return this;
      }
      public Builder AddUnpackedSfixed64(long value) {
        result.unpackedSfixed64_.Add(value);
        return this;
      }
      public Builder AddRangeUnpackedSfixed64(scg::IEnumerable<long> values) {
        base.AddRange(values, result.unpackedSfixed64_);
        return this;
      }
      public Builder ClearUnpackedSfixed64() {
        result.unpackedSfixed64_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<float> UnpackedFloatList {
        get { return result.unpackedFloat_; }
      }
      public int UnpackedFloatCount {
        get { return result.UnpackedFloatCount; }
      }
      public float GetUnpackedFloat(int index) {
        return result.GetUnpackedFloat(index);
      }
      public Builder SetUnpackedFloat(int index, float value) {
        result.unpackedFloat_[index] = value;
        return this;
      }
      public Builder AddUnpackedFloat(float value) {
        result.unpackedFloat_.Add(value);
        return this;
      }
      public Builder AddRangeUnpackedFloat(scg::IEnumerable<float> values) {
        base.AddRange(values, result.unpackedFloat_);
        return this;
      }
      public Builder ClearUnpackedFloat() {
        result.unpackedFloat_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<double> UnpackedDoubleList {
        get { return result.unpackedDouble_; }
      }
      public int UnpackedDoubleCount {
        get { return result.UnpackedDoubleCount; }
      }
      public double GetUnpackedDouble(int index) {
        return result.GetUnpackedDouble(index);
      }
      public Builder SetUnpackedDouble(int index, double value) {
        result.unpackedDouble_[index] = value;
        return this;
      }
      public Builder AddUnpackedDouble(double value) {
        result.unpackedDouble_.Add(value);
        return this;
      }
      public Builder AddRangeUnpackedDouble(scg::IEnumerable<double> values) {
        base.AddRange(values, result.unpackedDouble_);
        return this;
      }
      public Builder ClearUnpackedDouble() {
        result.unpackedDouble_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<bool> UnpackedBoolList {
        get { return result.unpackedBool_; }
      }
      public int UnpackedBoolCount {
        get { return result.UnpackedBoolCount; }
      }
      public bool GetUnpackedBool(int index) {
        return result.GetUnpackedBool(index);
      }
      public Builder SetUnpackedBool(int index, bool value) {
        result.unpackedBool_[index] = value;
        return this;
      }
      public Builder AddUnpackedBool(bool value) {
        result.unpackedBool_.Add(value);
        return this;
      }
      public Builder AddRangeUnpackedBool(scg::IEnumerable<bool> values) {
        base.AddRange(values, result.unpackedBool_);
        return this;
      }
      public Builder ClearUnpackedBool() {
        result.unpackedBool_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> UnpackedEnumList {
        get { return result.unpackedEnum_; }
      }
      public int UnpackedEnumCount {
        get { return result.UnpackedEnumCount; }
      }
      public global::Google.ProtocolBuffers.TestProtos.ForeignEnum GetUnpackedEnum(int index) {
        return result.GetUnpackedEnum(index);
      }
      public Builder SetUnpackedEnum(int index, global::Google.ProtocolBuffers.TestProtos.ForeignEnum value) {
        result.unpackedEnum_[index] = value;
        return this;
      }
      public Builder AddUnpackedEnum(global::Google.ProtocolBuffers.TestProtos.ForeignEnum value) {
        result.unpackedEnum_.Add(value);
        return this;
      }
      public Builder AddRangeUnpackedEnum(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> values) {
        base.AddRange(values, result.unpackedEnum_);
        return this;
      }
      public Builder ClearUnpackedEnum() {
        result.unpackedEnum_.Clear();
        return this;
      }
    }
    static TestUnpackedTypes() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 TestPackedExtensions : pb::ExtendableMessage<TestPackedExtensions, TestPackedExtensions.Builder> {
    private static readonly TestPackedExtensions defaultInstance = new Builder().BuildPartial();
    public static TestPackedExtensions DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestPackedExtensions DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestPackedExtensions ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestPackedExtensions__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestPackedExtensions, TestPackedExtensions.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestPackedExtensions__FieldAccessorTable; }
    }
    
    public override bool IsInitialized {
      get {
        if (!ExtensionsAreInitialized) return false;
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      pb::ExtendableMessage<TestPackedExtensions, TestPackedExtensions.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
      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;
        size += ExtensionsSerializedSize;
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static TestPackedExtensions ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestPackedExtensions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestPackedExtensions ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestPackedExtensions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestPackedExtensions ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestPackedExtensions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestPackedExtensions ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestPackedExtensions ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestPackedExtensions ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestPackedExtensions 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(TestPackedExtensions 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<TestPackedExtensions, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestPackedExtensions result = new TestPackedExtensions();
      
      protected override TestPackedExtensions MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestPackedExtensions();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestPackedExtensions.Descriptor; }
      }
      
      public override TestPackedExtensions DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestPackedExtensions.DefaultInstance; }
      }
      
      public override TestPackedExtensions BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        TestPackedExtensions returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestPackedExtensions) {
          return MergeFrom((TestPackedExtensions) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestPackedExtensions other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestPackedExtensions.DefaultInstance) return this;
          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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
    }
    static TestPackedExtensions() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 TestDynamicExtensions : pb::GeneratedMessage<TestDynamicExtensions, TestDynamicExtensions.Builder> {
    private static readonly TestDynamicExtensions defaultInstance = new Builder().BuildPartial();
    public static TestDynamicExtensions DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestDynamicExtensions DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestDynamicExtensions ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestDynamicExtensions__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestDynamicExtensions, TestDynamicExtensions.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestDynamicExtensions__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 DynamicEnumType {
        DYNAMIC_FOO = 2200,
        DYNAMIC_BAR = 2201,
        DYNAMIC_BAZ = 2202,
      }
      
      [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
      [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
      [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
      public sealed partial class DynamicMessageType : pb::GeneratedMessage<DynamicMessageType, DynamicMessageType.Builder> {
        private static readonly DynamicMessageType defaultInstance = new Builder().BuildPartial();
        public static DynamicMessageType DefaultInstance {
          get { return defaultInstance; }
        }
        
        public override DynamicMessageType DefaultInstanceForType {
          get { return defaultInstance; }
        }
        
        protected override DynamicMessageType ThisMessage {
          get { return this; }
        }
        
        public static pbd::MessageDescriptor Descriptor {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestDynamicExtensions_DynamicMessageType__Descriptor; }
        }
        
        protected override pb::FieldAccess.FieldAccessorTable<DynamicMessageType, DynamicMessageType.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestDynamicExtensions_DynamicMessageType__FieldAccessorTable; }
        }
        
        public const int DynamicFieldFieldNumber = 2100;
        private bool hasDynamicField;
        private int dynamicField_ = 0;
        public bool HasDynamicField {
          get { return hasDynamicField; }
        }
        public int DynamicField {
          get { return dynamicField_; }
        }
        
        public override bool IsInitialized {
          get {
            return true;
          }
        }
        
        public override void WriteTo(pb::ICodedOutputStream output) {
          int size = SerializedSize;
          if (HasDynamicField) {
            output.WriteInt32(2100, "dynamic_field", DynamicField);
          }
          UnknownFields.WriteTo(output);
        }
        
        private int memoizedSerializedSize = -1;
        public override int SerializedSize {
          get {
            int size = memoizedSerializedSize;
            if (size != -1) return size;
            
            size = 0;
            if (HasDynamicField) {
              size += pb::CodedOutputStream.ComputeInt32Size(2100, DynamicField);
            }
            size += UnknownFields.SerializedSize;
            memoizedSerializedSize = size;
            return size;
          }
        }
        
        public static DynamicMessageType ParseFrom(pb::ByteString data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static DynamicMessageType ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static DynamicMessageType ParseFrom(byte[] data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static DynamicMessageType ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static DynamicMessageType ParseFrom(global::System.IO.Stream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static DynamicMessageType ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static DynamicMessageType ParseDelimitedFrom(global::System.IO.Stream input) {
          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
        }
        public static DynamicMessageType ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
        }
        public static DynamicMessageType ParseFrom(pb::CodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static DynamicMessageType 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(DynamicMessageType 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<DynamicMessageType, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {}
          
          DynamicMessageType result = new DynamicMessageType();
          
          protected override DynamicMessageType MessageBeingBuilt {
            get { return result; }
          }
          
          public override Builder Clear() {
            result = new DynamicMessageType();
            return this;
          }
          
          public override Builder Clone() {
            return new Builder().MergeFrom(result);
          }
          
          public override pbd::MessageDescriptor DescriptorForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicMessageType.Descriptor; }
          }
          
          public override DynamicMessageType DefaultInstanceForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicMessageType.DefaultInstance; }
          }
          
          public override DynamicMessageType BuildPartial() {
            if (result == null) {
              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
            }
            DynamicMessageType returnMe = result;
            result = null;
            return returnMe;
          }
          
          public override Builder MergeFrom(pb::IMessage other) {
            if (other is DynamicMessageType) {
              return MergeFrom((DynamicMessageType) other);
            } else {
              base.MergeFrom(other);
              return this;
            }
          }
          
          public override Builder MergeFrom(DynamicMessageType other) {
            if (other == global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicMessageType.DefaultInstance) return this;
            if (other.HasDynamicField) {
              DynamicField = other.DynamicField;
            }
            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;
            uint tag;
            string field_name;
            while (input.ReadTag(out tag, out field_name)) {
              switch (tag) {
                case 0: {
                  throw pb::InvalidProtocolBufferException.InvalidTag();
                }
                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, field_name);
                  break;
                }
                case 16800: {
                  result.hasDynamicField |= input.ReadInt32(ref result.dynamicField_);
                  break;
                }
              }
            }
            
            if (unknownFields != null) {
              this.UnknownFields = unknownFields.Build();
            }
            return this;
          }
          
          
          public bool HasDynamicField {
            get { return result.HasDynamicField; }
          }
          public int DynamicField {
            get { return result.DynamicField; }
            set { SetDynamicField(value); }
          }
          public Builder SetDynamicField(int value) {
            result.hasDynamicField = true;
            result.dynamicField_ = value;
            return this;
          }
          public Builder ClearDynamicField() {
            result.hasDynamicField = false;
            result.dynamicField_ = 0;
            return this;
          }
        }
        static DynamicMessageType() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
        }
      }
      
    }
    #endregion
    
    public const int ScalarExtensionFieldNumber = 2000;
    private bool hasScalarExtension;
    private uint scalarExtension_ = 0;
    public bool HasScalarExtension {
      get { return hasScalarExtension; }
    }
    [global::System.CLSCompliant(false)]
    public uint ScalarExtension {
      get { return scalarExtension_; }
    }
    
    public const int EnumExtensionFieldNumber = 2001;
    private bool hasEnumExtension;
    private global::Google.ProtocolBuffers.TestProtos.ForeignEnum enumExtension_ = global::Google.ProtocolBuffers.TestProtos.ForeignEnum.FOREIGN_FOO;
    public bool HasEnumExtension {
      get { return hasEnumExtension; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ForeignEnum EnumExtension {
      get { return enumExtension_; }
    }
    
    public const int DynamicEnumExtensionFieldNumber = 2002;
    private bool hasDynamicEnumExtension;
    private global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicEnumType dynamicEnumExtension_ = global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicEnumType.DYNAMIC_FOO;
    public bool HasDynamicEnumExtension {
      get { return hasDynamicEnumExtension; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicEnumType DynamicEnumExtension {
      get { return dynamicEnumExtension_; }
    }
    
    public const int MessageExtensionFieldNumber = 2003;
    private bool hasMessageExtension;
    private global::Google.ProtocolBuffers.TestProtos.ForeignMessage messageExtension_ = global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance;
    public bool HasMessageExtension {
      get { return hasMessageExtension; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ForeignMessage MessageExtension {
      get { return messageExtension_; }
    }
    
    public const int DynamicMessageExtensionFieldNumber = 2004;
    private bool hasDynamicMessageExtension;
    private global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicMessageType dynamicMessageExtension_ = global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicMessageType.DefaultInstance;
    public bool HasDynamicMessageExtension {
      get { return hasDynamicMessageExtension; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicMessageType DynamicMessageExtension {
      get { return dynamicMessageExtension_; }
    }
    
    public const int RepeatedExtensionFieldNumber = 2005;
    private pbc::PopsicleList<string> repeatedExtension_ = new pbc::PopsicleList<string>();
    public scg::IList<string> RepeatedExtensionList {
      get { return pbc::Lists.AsReadOnly(repeatedExtension_); }
    }
    public int RepeatedExtensionCount {
      get { return repeatedExtension_.Count; }
    }
    public string GetRepeatedExtension(int index) {
      return repeatedExtension_[index];
    }
    
    public const int PackedExtensionFieldNumber = 2006;
    private int packedExtensionMemoizedSerializedSize;
    private pbc::PopsicleList<int> packedExtension_ = new pbc::PopsicleList<int>();
    public scg::IList<int> PackedExtensionList {
      get { return pbc::Lists.AsReadOnly(packedExtension_); }
    }
    public int PackedExtensionCount {
      get { return packedExtension_.Count; }
    }
    public int GetPackedExtension(int index) {
      return packedExtension_[index];
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (HasScalarExtension) {
        output.WriteFixed32(2000, "scalar_extension", ScalarExtension);
      }
      if (HasEnumExtension) {
        output.WriteEnum(2001, "enum_extension", (int) EnumExtension, EnumExtension.ToString());
      }
      if (HasDynamicEnumExtension) {
        output.WriteEnum(2002, "dynamic_enum_extension", (int) DynamicEnumExtension, DynamicEnumExtension.ToString());
      }
      if (HasMessageExtension) {
        output.WriteMessage(2003, "message_extension", MessageExtension);
      }
      if (HasDynamicMessageExtension) {
        output.WriteMessage(2004, "dynamic_message_extension", DynamicMessageExtension);
      }
      if (repeatedExtension_.Count > 0) {
        output.WriteArray(pbd::FieldType.String, 2005, "repeated_extension", repeatedExtension_);
      }
      if (packedExtension_.Count > 0) {
        output.WritePackedArray(pbd::FieldType.SInt32, 2006, "packed_extension", packedExtensionMemoizedSerializedSize, packedExtension_);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        if (HasScalarExtension) {
          size += pb::CodedOutputStream.ComputeFixed32Size(2000, ScalarExtension);
        }
        if (HasEnumExtension) {
          size += pb::CodedOutputStream.ComputeEnumSize(2001, (int) EnumExtension);
        }
        if (HasDynamicEnumExtension) {
          size += pb::CodedOutputStream.ComputeEnumSize(2002, (int) DynamicEnumExtension);
        }
        if (HasMessageExtension) {
          size += pb::CodedOutputStream.ComputeMessageSize(2003, MessageExtension);
        }
        if (HasDynamicMessageExtension) {
          size += pb::CodedOutputStream.ComputeMessageSize(2004, DynamicMessageExtension);
        }
        {
          int dataSize = 0;
          foreach (string element in RepeatedExtensionList) {
            dataSize += pb::CodedOutputStream.ComputeStringSizeNoTag(element);
          }
          size += dataSize;
          size += 2 * repeatedExtension_.Count;
        }
        {
          int dataSize = 0;
          foreach (int element in PackedExtensionList) {
            dataSize += pb::CodedOutputStream.ComputeSInt32SizeNoTag(element);
          }
          size += dataSize;
          if (packedExtension_.Count != 0) {
            size += 2 + pb::CodedOutputStream.ComputeInt32SizeNoTag(dataSize);
          }
          packedExtensionMemoizedSerializedSize = dataSize;
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static TestDynamicExtensions ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestDynamicExtensions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestDynamicExtensions ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestDynamicExtensions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestDynamicExtensions ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestDynamicExtensions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestDynamicExtensions ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestDynamicExtensions ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestDynamicExtensions ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestDynamicExtensions 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(TestDynamicExtensions 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<TestDynamicExtensions, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestDynamicExtensions result = new TestDynamicExtensions();
      
      protected override TestDynamicExtensions MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestDynamicExtensions();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Descriptor; }
      }
      
      public override TestDynamicExtensions DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.DefaultInstance; }
      }
      
      public override TestDynamicExtensions BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        result.repeatedExtension_.MakeReadOnly();
        result.packedExtension_.MakeReadOnly();
        TestDynamicExtensions returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestDynamicExtensions) {
          return MergeFrom((TestDynamicExtensions) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestDynamicExtensions other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.DefaultInstance) return this;
        if (other.HasScalarExtension) {
          ScalarExtension = other.ScalarExtension;
        }
        if (other.HasEnumExtension) {
          EnumExtension = other.EnumExtension;
        }
        if (other.HasDynamicEnumExtension) {
          DynamicEnumExtension = other.DynamicEnumExtension;
        }
        if (other.HasMessageExtension) {
          MergeMessageExtension(other.MessageExtension);
        }
        if (other.HasDynamicMessageExtension) {
          MergeDynamicMessageExtension(other.DynamicMessageExtension);
        }
        if (other.repeatedExtension_.Count != 0) {
          base.AddRange(other.repeatedExtension_, result.repeatedExtension_);
        }
        if (other.packedExtension_.Count != 0) {
          base.AddRange(other.packedExtension_, result.packedExtension_);
        }
        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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
            case 16005: {
              result.hasScalarExtension |= input.ReadFixed32(ref result.scalarExtension_);
              break;
            }
            case 16008: {
              object unknown;
              if(input.ReadEnum(ref result.enumExtension_, out unknown)) {
                result.hasEnumExtension = true;
              } else if(unknown is int) {
                if (unknownFields == null) {
                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                }
                unknownFields.MergeVarintField(2001, (ulong)(int)unknown);
              }
              break;
            }
            case 16016: {
              object unknown;
              if(input.ReadEnum(ref result.dynamicEnumExtension_, out unknown)) {
                result.hasDynamicEnumExtension = true;
              } else if(unknown is int) {
                if (unknownFields == null) {
                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                }
                unknownFields.MergeVarintField(2002, (ulong)(int)unknown);
              }
              break;
            }
            case 16026: {
              global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.ForeignMessage.CreateBuilder();
              if (HasMessageExtension) {
                subBuilder.MergeFrom(MessageExtension);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              MessageExtension = subBuilder.BuildPartial();
              break;
            }
            case 16034: {
              global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicMessageType.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicMessageType.CreateBuilder();
              if (HasDynamicMessageExtension) {
                subBuilder.MergeFrom(DynamicMessageExtension);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              DynamicMessageExtension = subBuilder.BuildPartial();
              break;
            }
            case 16042: {
              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedExtension_);
              break;
            }
            case 16050: {
              input.ReadPrimitiveArray(pbd::FieldType.SInt32, tag, field_name, result.packedExtension_);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      public bool HasScalarExtension {
        get { return result.HasScalarExtension; }
      }
      [global::System.CLSCompliant(false)]
      public uint ScalarExtension {
        get { return result.ScalarExtension; }
        set { SetScalarExtension(value); }
      }
      [global::System.CLSCompliant(false)]
      public Builder SetScalarExtension(uint value) {
        result.hasScalarExtension = true;
        result.scalarExtension_ = value;
        return this;
      }
      public Builder ClearScalarExtension() {
        result.hasScalarExtension = false;
        result.scalarExtension_ = 0;
        return this;
      }
      
      public bool HasEnumExtension {
       get { return result.HasEnumExtension; }
      }
      public global::Google.ProtocolBuffers.TestProtos.ForeignEnum EnumExtension {
        get { return result.EnumExtension; }
        set { SetEnumExtension(value); }
      }
      public Builder SetEnumExtension(global::Google.ProtocolBuffers.TestProtos.ForeignEnum value) {
        result.hasEnumExtension = true;
        result.enumExtension_ = value;
        return this;
      }
      public Builder ClearEnumExtension() {
        result.hasEnumExtension = false;
        result.enumExtension_ = global::Google.ProtocolBuffers.TestProtos.ForeignEnum.FOREIGN_FOO;
        return this;
      }
      
      public bool HasDynamicEnumExtension {
       get { return result.HasDynamicEnumExtension; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicEnumType DynamicEnumExtension {
        get { return result.DynamicEnumExtension; }
        set { SetDynamicEnumExtension(value); }
      }
      public Builder SetDynamicEnumExtension(global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicEnumType value) {
        result.hasDynamicEnumExtension = true;
        result.dynamicEnumExtension_ = value;
        return this;
      }
      public Builder ClearDynamicEnumExtension() {
        result.hasDynamicEnumExtension = false;
        result.dynamicEnumExtension_ = global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicEnumType.DYNAMIC_FOO;
        return this;
      }
      
      public bool HasMessageExtension {
       get { return result.HasMessageExtension; }
      }
      public global::Google.ProtocolBuffers.TestProtos.ForeignMessage MessageExtension {
        get { return result.MessageExtension; }
        set { SetMessageExtension(value); }
      }
      public Builder SetMessageExtension(global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasMessageExtension = true;
        result.messageExtension_ = value;
        return this;
      }
      public Builder SetMessageExtension(global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.hasMessageExtension = true;
        result.messageExtension_ = builderForValue.Build();
        return this;
      }
      public Builder MergeMessageExtension(global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        if (result.HasMessageExtension &&
            result.messageExtension_ != global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance) {
            result.messageExtension_ = global::Google.ProtocolBuffers.TestProtos.ForeignMessage.CreateBuilder(result.messageExtension_).MergeFrom(value).BuildPartial();
        } else {
          result.messageExtension_ = value;
        }
        result.hasMessageExtension = true;
        return this;
      }
      public Builder ClearMessageExtension() {
        result.hasMessageExtension = false;
        result.messageExtension_ = global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance;
        return this;
      }
      
      public bool HasDynamicMessageExtension {
       get { return result.HasDynamicMessageExtension; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicMessageType DynamicMessageExtension {
        get { return result.DynamicMessageExtension; }
        set { SetDynamicMessageExtension(value); }
      }
      public Builder SetDynamicMessageExtension(global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicMessageType value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasDynamicMessageExtension = true;
        result.dynamicMessageExtension_ = value;
        return this;
      }
      public Builder SetDynamicMessageExtension(global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicMessageType.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.hasDynamicMessageExtension = true;
        result.dynamicMessageExtension_ = builderForValue.Build();
        return this;
      }
      public Builder MergeDynamicMessageExtension(global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicMessageType value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        if (result.HasDynamicMessageExtension &&
            result.dynamicMessageExtension_ != global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicMessageType.DefaultInstance) {
            result.dynamicMessageExtension_ = global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicMessageType.CreateBuilder(result.dynamicMessageExtension_).MergeFrom(value).BuildPartial();
        } else {
          result.dynamicMessageExtension_ = value;
        }
        result.hasDynamicMessageExtension = true;
        return this;
      }
      public Builder ClearDynamicMessageExtension() {
        result.hasDynamicMessageExtension = false;
        result.dynamicMessageExtension_ = global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicMessageType.DefaultInstance;
        return this;
      }
      
      public pbc::IPopsicleList<string> RepeatedExtensionList {
        get { return result.repeatedExtension_; }
      }
      public int RepeatedExtensionCount {
        get { return result.RepeatedExtensionCount; }
      }
      public string GetRepeatedExtension(int index) {
        return result.GetRepeatedExtension(index);
      }
      public Builder SetRepeatedExtension(int index, string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedExtension_[index] = value;
        return this;
      }
      public Builder AddRepeatedExtension(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.repeatedExtension_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedExtension(scg::IEnumerable<string> values) {
        base.AddRange(values, result.repeatedExtension_);
        return this;
      }
      public Builder ClearRepeatedExtension() {
        result.repeatedExtension_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<int> PackedExtensionList {
        get { return result.packedExtension_; }
      }
      public int PackedExtensionCount {
        get { return result.PackedExtensionCount; }
      }
      public int GetPackedExtension(int index) {
        return result.GetPackedExtension(index);
      }
      public Builder SetPackedExtension(int index, int value) {
        result.packedExtension_[index] = value;
        return this;
      }
      public Builder AddPackedExtension(int value) {
        result.packedExtension_.Add(value);
        return this;
      }
      public Builder AddRangePackedExtension(scg::IEnumerable<int> values) {
        base.AddRange(values, result.packedExtension_);
        return this;
      }
      public Builder ClearPackedExtension() {
        result.packedExtension_.Clear();
        return this;
      }
    }
    static TestDynamicExtensions() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 TestRepeatedScalarDifferentTagSizes : pb::GeneratedMessage<TestRepeatedScalarDifferentTagSizes, TestRepeatedScalarDifferentTagSizes.Builder> {
    private static readonly TestRepeatedScalarDifferentTagSizes defaultInstance = new Builder().BuildPartial();
    public static TestRepeatedScalarDifferentTagSizes DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestRepeatedScalarDifferentTagSizes DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestRepeatedScalarDifferentTagSizes ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestRepeatedScalarDifferentTagSizes__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestRepeatedScalarDifferentTagSizes, TestRepeatedScalarDifferentTagSizes.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_TestRepeatedScalarDifferentTagSizes__FieldAccessorTable; }
    }
    
    public const int RepeatedFixed32FieldNumber = 12;
    private pbc::PopsicleList<uint> repeatedFixed32_ = new pbc::PopsicleList<uint>();
    [global::System.CLSCompliant(false)]
    public scg::IList<uint> RepeatedFixed32List {
      get { return pbc::Lists.AsReadOnly(repeatedFixed32_); }
    }
    public int RepeatedFixed32Count {
      get { return repeatedFixed32_.Count; }
    }
    [global::System.CLSCompliant(false)]
    public uint GetRepeatedFixed32(int index) {
      return repeatedFixed32_[index];
    }
    
    public const int RepeatedInt32FieldNumber = 13;
    private pbc::PopsicleList<int> repeatedInt32_ = new pbc::PopsicleList<int>();
    public scg::IList<int> RepeatedInt32List {
      get { return pbc::Lists.AsReadOnly(repeatedInt32_); }
    }
    public int RepeatedInt32Count {
      get { return repeatedInt32_.Count; }
    }
    public int GetRepeatedInt32(int index) {
      return repeatedInt32_[index];
    }
    
    public const int RepeatedFixed64FieldNumber = 2046;
    private pbc::PopsicleList<ulong> repeatedFixed64_ = new pbc::PopsicleList<ulong>();
    [global::System.CLSCompliant(false)]
    public scg::IList<ulong> RepeatedFixed64List {
      get { return pbc::Lists.AsReadOnly(repeatedFixed64_); }
    }
    public int RepeatedFixed64Count {
      get { return repeatedFixed64_.Count; }
    }
    [global::System.CLSCompliant(false)]
    public ulong GetRepeatedFixed64(int index) {
      return repeatedFixed64_[index];
    }
    
    public const int RepeatedInt64FieldNumber = 2047;
    private pbc::PopsicleList<long> repeatedInt64_ = new pbc::PopsicleList<long>();
    public scg::IList<long> RepeatedInt64List {
      get { return pbc::Lists.AsReadOnly(repeatedInt64_); }
    }
    public int RepeatedInt64Count {
      get { return repeatedInt64_.Count; }
    }
    public long GetRepeatedInt64(int index) {
      return repeatedInt64_[index];
    }
    
    public const int RepeatedFloatFieldNumber = 262142;
    private pbc::PopsicleList<float> repeatedFloat_ = new pbc::PopsicleList<float>();
    public scg::IList<float> RepeatedFloatList {
      get { return pbc::Lists.AsReadOnly(repeatedFloat_); }
    }
    public int RepeatedFloatCount {
      get { return repeatedFloat_.Count; }
    }
    public float GetRepeatedFloat(int index) {
      return repeatedFloat_[index];
    }
    
    public const int RepeatedUint64FieldNumber = 262143;
    private pbc::PopsicleList<ulong> repeatedUint64_ = new pbc::PopsicleList<ulong>();
    [global::System.CLSCompliant(false)]
    public scg::IList<ulong> RepeatedUint64List {
      get { return pbc::Lists.AsReadOnly(repeatedUint64_); }
    }
    public int RepeatedUint64Count {
      get { return repeatedUint64_.Count; }
    }
    [global::System.CLSCompliant(false)]
    public ulong GetRepeatedUint64(int index) {
      return repeatedUint64_[index];
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      int size = SerializedSize;
      if (repeatedFixed32_.Count > 0) {
        output.WriteArray(pbd::FieldType.Fixed32, 12, "repeated_fixed32", repeatedFixed32_);
      }
      if (repeatedInt32_.Count > 0) {
        output.WriteArray(pbd::FieldType.Int32, 13, "repeated_int32", repeatedInt32_);
      }
      if (repeatedFixed64_.Count > 0) {
        output.WriteArray(pbd::FieldType.Fixed64, 2046, "repeated_fixed64", repeatedFixed64_);
      }
      if (repeatedInt64_.Count > 0) {
        output.WriteArray(pbd::FieldType.Int64, 2047, "repeated_int64", repeatedInt64_);
      }
      if (repeatedFloat_.Count > 0) {
        output.WriteArray(pbd::FieldType.Float, 262142, "repeated_float", repeatedFloat_);
      }
      if (repeatedUint64_.Count > 0) {
        output.WriteArray(pbd::FieldType.UInt64, 262143, "repeated_uint64", repeatedUint64_);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        
        size = 0;
        {
          int dataSize = 0;
          dataSize = 4 * repeatedFixed32_.Count;
          size += dataSize;
          size += 1 * repeatedFixed32_.Count;
        }
        {
          int dataSize = 0;
          foreach (int element in RepeatedInt32List) {
            dataSize += pb::CodedOutputStream.ComputeInt32SizeNoTag(element);
          }
          size += dataSize;
          size += 1 * repeatedInt32_.Count;
        }
        {
          int dataSize = 0;
          dataSize = 8 * repeatedFixed64_.Count;
          size += dataSize;
          size += 2 * repeatedFixed64_.Count;
        }
        {
          int dataSize = 0;
          foreach (long element in RepeatedInt64List) {
            dataSize += pb::CodedOutputStream.ComputeInt64SizeNoTag(element);
          }
          size += dataSize;
          size += 2 * repeatedInt64_.Count;
        }
        {
          int dataSize = 0;
          dataSize = 4 * repeatedFloat_.Count;
          size += dataSize;
          size += 3 * repeatedFloat_.Count;
        }
        {
          int dataSize = 0;
          foreach (ulong element in RepeatedUint64List) {
            dataSize += pb::CodedOutputStream.ComputeUInt64SizeNoTag(element);
          }
          size += dataSize;
          size += 3 * repeatedUint64_.Count;
        }
        size += UnknownFields.SerializedSize;
        memoizedSerializedSize = size;
        return size;
      }
    }
    
    public static TestRepeatedScalarDifferentTagSizes ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestRepeatedScalarDifferentTagSizes ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestRepeatedScalarDifferentTagSizes ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestRepeatedScalarDifferentTagSizes ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestRepeatedScalarDifferentTagSizes ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestRepeatedScalarDifferentTagSizes ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestRepeatedScalarDifferentTagSizes ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestRepeatedScalarDifferentTagSizes ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestRepeatedScalarDifferentTagSizes ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestRepeatedScalarDifferentTagSizes 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(TestRepeatedScalarDifferentTagSizes 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<TestRepeatedScalarDifferentTagSizes, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestRepeatedScalarDifferentTagSizes result = new TestRepeatedScalarDifferentTagSizes();
      
      protected override TestRepeatedScalarDifferentTagSizes MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestRepeatedScalarDifferentTagSizes();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestRepeatedScalarDifferentTagSizes.Descriptor; }
      }
      
      public override TestRepeatedScalarDifferentTagSizes DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestRepeatedScalarDifferentTagSizes.DefaultInstance; }
      }
      
      public override TestRepeatedScalarDifferentTagSizes BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        result.repeatedFixed32_.MakeReadOnly();
        result.repeatedInt32_.MakeReadOnly();
        result.repeatedFixed64_.MakeReadOnly();
        result.repeatedInt64_.MakeReadOnly();
        result.repeatedFloat_.MakeReadOnly();
        result.repeatedUint64_.MakeReadOnly();
        TestRepeatedScalarDifferentTagSizes returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestRepeatedScalarDifferentTagSizes) {
          return MergeFrom((TestRepeatedScalarDifferentTagSizes) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(TestRepeatedScalarDifferentTagSizes other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestRepeatedScalarDifferentTagSizes.DefaultInstance) return this;
        if (other.repeatedFixed32_.Count != 0) {
          base.AddRange(other.repeatedFixed32_, result.repeatedFixed32_);
        }
        if (other.repeatedInt32_.Count != 0) {
          base.AddRange(other.repeatedInt32_, result.repeatedInt32_);
        }
        if (other.repeatedFixed64_.Count != 0) {
          base.AddRange(other.repeatedFixed64_, result.repeatedFixed64_);
        }
        if (other.repeatedInt64_.Count != 0) {
          base.AddRange(other.repeatedInt64_, result.repeatedInt64_);
        }
        if (other.repeatedFloat_.Count != 0) {
          base.AddRange(other.repeatedFloat_, result.repeatedFloat_);
        }
        if (other.repeatedUint64_.Count != 0) {
          base.AddRange(other.repeatedUint64_, result.repeatedUint64_);
        }
        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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
            case 101: {
              input.ReadPrimitiveArray(pbd::FieldType.Fixed32, tag, field_name, result.repeatedFixed32_);
              break;
            }
            case 104: {
              input.ReadPrimitiveArray(pbd::FieldType.Int32, tag, field_name, result.repeatedInt32_);
              break;
            }
            case 16369: {
              input.ReadPrimitiveArray(pbd::FieldType.Fixed64, tag, field_name, result.repeatedFixed64_);
              break;
            }
            case 16376: {
              input.ReadPrimitiveArray(pbd::FieldType.Int64, tag, field_name, result.repeatedInt64_);
              break;
            }
            case 2097141: {
              input.ReadPrimitiveArray(pbd::FieldType.Float, tag, field_name, result.repeatedFloat_);
              break;
            }
            case 2097144: {
              input.ReadPrimitiveArray(pbd::FieldType.UInt64, tag, field_name, result.repeatedUint64_);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<uint> RepeatedFixed32List {
        get { return result.repeatedFixed32_; }
      }
      public int RepeatedFixed32Count {
        get { return result.RepeatedFixed32Count; }
      }
      [global::System.CLSCompliant(false)]
      public uint GetRepeatedFixed32(int index) {
        return result.GetRepeatedFixed32(index);
      }
      [global::System.CLSCompliant(false)]
      public Builder SetRepeatedFixed32(int index, uint value) {
        result.repeatedFixed32_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRepeatedFixed32(uint value) {
        result.repeatedFixed32_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangeRepeatedFixed32(scg::IEnumerable<uint> values) {
        base.AddRange(values, result.repeatedFixed32_);
        return this;
      }
      public Builder ClearRepeatedFixed32() {
        result.repeatedFixed32_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<int> RepeatedInt32List {
        get { return result.repeatedInt32_; }
      }
      public int RepeatedInt32Count {
        get { return result.RepeatedInt32Count; }
      }
      public int GetRepeatedInt32(int index) {
        return result.GetRepeatedInt32(index);
      }
      public Builder SetRepeatedInt32(int index, int value) {
        result.repeatedInt32_[index] = value;
        return this;
      }
      public Builder AddRepeatedInt32(int value) {
        result.repeatedInt32_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedInt32(scg::IEnumerable<int> values) {
        base.AddRange(values, result.repeatedInt32_);
        return this;
      }
      public Builder ClearRepeatedInt32() {
        result.repeatedInt32_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<ulong> RepeatedFixed64List {
        get { return result.repeatedFixed64_; }
      }
      public int RepeatedFixed64Count {
        get { return result.RepeatedFixed64Count; }
      }
      [global::System.CLSCompliant(false)]
      public ulong GetRepeatedFixed64(int index) {
        return result.GetRepeatedFixed64(index);
      }
      [global::System.CLSCompliant(false)]
      public Builder SetRepeatedFixed64(int index, ulong value) {
        result.repeatedFixed64_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRepeatedFixed64(ulong value) {
        result.repeatedFixed64_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangeRepeatedFixed64(scg::IEnumerable<ulong> values) {
        base.AddRange(values, result.repeatedFixed64_);
        return this;
      }
      public Builder ClearRepeatedFixed64() {
        result.repeatedFixed64_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<long> RepeatedInt64List {
        get { return result.repeatedInt64_; }
      }
      public int RepeatedInt64Count {
        get { return result.RepeatedInt64Count; }
      }
      public long GetRepeatedInt64(int index) {
        return result.GetRepeatedInt64(index);
      }
      public Builder SetRepeatedInt64(int index, long value) {
        result.repeatedInt64_[index] = value;
        return this;
      }
      public Builder AddRepeatedInt64(long value) {
        result.repeatedInt64_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedInt64(scg::IEnumerable<long> values) {
        base.AddRange(values, result.repeatedInt64_);
        return this;
      }
      public Builder ClearRepeatedInt64() {
        result.repeatedInt64_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<float> RepeatedFloatList {
        get { return result.repeatedFloat_; }
      }
      public int RepeatedFloatCount {
        get { return result.RepeatedFloatCount; }
      }
      public float GetRepeatedFloat(int index) {
        return result.GetRepeatedFloat(index);
      }
      public Builder SetRepeatedFloat(int index, float value) {
        result.repeatedFloat_[index] = value;
        return this;
      }
      public Builder AddRepeatedFloat(float value) {
        result.repeatedFloat_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedFloat(scg::IEnumerable<float> values) {
        base.AddRange(values, result.repeatedFloat_);
        return this;
      }
      public Builder ClearRepeatedFloat() {
        result.repeatedFloat_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<ulong> RepeatedUint64List {
        get { return result.repeatedUint64_; }
      }
      public int RepeatedUint64Count {
        get { return result.RepeatedUint64Count; }
      }
      [global::System.CLSCompliant(false)]
      public ulong GetRepeatedUint64(int index) {
        return result.GetRepeatedUint64(index);
      }
      [global::System.CLSCompliant(false)]
      public Builder SetRepeatedUint64(int index, ulong value) {
        result.repeatedUint64_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRepeatedUint64(ulong value) {
        result.repeatedUint64_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangeRepeatedUint64(scg::IEnumerable<ulong> values) {
        base.AddRange(values, result.repeatedUint64_);
        return this;
      }
      public Builder ClearRepeatedUint64() {
        result.repeatedUint64_.Clear();
        return this;
      }
    }
    static TestRepeatedScalarDifferentTagSizes() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 FooRequest : pb::GeneratedMessage<FooRequest, FooRequest.Builder> {
    private static readonly FooRequest defaultInstance = new Builder().BuildPartial();
    public static FooRequest DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override FooRequest DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override FooRequest ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_FooRequest__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<FooRequest, FooRequest.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_FooRequest__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 FooRequest ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static FooRequest ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static FooRequest ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static FooRequest ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static FooRequest ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static FooRequest ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static FooRequest ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static FooRequest ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static FooRequest ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static FooRequest 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(FooRequest 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<FooRequest, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      FooRequest result = new FooRequest();
      
      protected override FooRequest MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new FooRequest();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.FooRequest.Descriptor; }
      }
      
      public override FooRequest DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.FooRequest.DefaultInstance; }
      }
      
      public override FooRequest BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        FooRequest returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is FooRequest) {
          return MergeFrom((FooRequest) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(FooRequest other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.FooRequest.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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
    }
    static FooRequest() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 FooResponse : pb::GeneratedMessage<FooResponse, FooResponse.Builder> {
    private static readonly FooResponse defaultInstance = new Builder().BuildPartial();
    public static FooResponse DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override FooResponse DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override FooResponse ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_FooResponse__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<FooResponse, FooResponse.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_FooResponse__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 FooResponse ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static FooResponse ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static FooResponse ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static FooResponse ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static FooResponse ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static FooResponse ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static FooResponse ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static FooResponse ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static FooResponse ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static FooResponse 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(FooResponse 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<FooResponse, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      FooResponse result = new FooResponse();
      
      protected override FooResponse MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new FooResponse();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.FooResponse.Descriptor; }
      }
      
      public override FooResponse DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.FooResponse.DefaultInstance; }
      }
      
      public override FooResponse BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        FooResponse returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is FooResponse) {
          return MergeFrom((FooResponse) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(FooResponse other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.FooResponse.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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
    }
    static FooResponse() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 BarRequest : pb::GeneratedMessage<BarRequest, BarRequest.Builder> {
    private static readonly BarRequest defaultInstance = new Builder().BuildPartial();
    public static BarRequest DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override BarRequest DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override BarRequest ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_BarRequest__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<BarRequest, BarRequest.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_BarRequest__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 BarRequest ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static BarRequest ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static BarRequest ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static BarRequest ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static BarRequest ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static BarRequest ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static BarRequest ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static BarRequest ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static BarRequest ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static BarRequest 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(BarRequest 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<BarRequest, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      BarRequest result = new BarRequest();
      
      protected override BarRequest MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new BarRequest();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.BarRequest.Descriptor; }
      }
      
      public override BarRequest DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.BarRequest.DefaultInstance; }
      }
      
      public override BarRequest BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        BarRequest returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is BarRequest) {
          return MergeFrom((BarRequest) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(BarRequest other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.BarRequest.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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
    }
    static BarRequest() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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 BarResponse : pb::GeneratedMessage<BarResponse, BarResponse.Builder> {
    private static readonly BarResponse defaultInstance = new Builder().BuildPartial();
    public static BarResponse DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override BarResponse DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override BarResponse ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_BarResponse__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<BarResponse, BarResponse.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_BarResponse__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 BarResponse ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static BarResponse ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static BarResponse ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static BarResponse ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static BarResponse ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static BarResponse ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static BarResponse ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static BarResponse ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static BarResponse ParseFrom(pb::CodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static BarResponse 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(BarResponse 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<BarResponse, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      BarResponse result = new BarResponse();
      
      protected override BarResponse MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new BarResponse();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.BarResponse.Descriptor; }
      }
      
      public override BarResponse DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.BarResponse.DefaultInstance; }
      }
      
      public override BarResponse BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        BarResponse returnMe = result;
        result = null;
        return returnMe;
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is BarResponse) {
          return MergeFrom((BarResponse) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(BarResponse other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.BarResponse.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;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          switch (tag) {
            case 0: {
              throw pb::InvalidProtocolBufferException.InvalidTag();
            }
            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, field_name);
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
    }
    static BarResponse() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.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
  
}
