// Generated by ProtoGen, Version=2.4.1.555, Culture=neutral, PublicKeyToken=55f7125234beb589.  DO NOT EDIT!
#pragma warning disable 1591, 0612, 3021
#region Designer generated code

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()]
  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_SparseEnumMessage__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.SparseEnumMessage, global::Google.ProtocolBuffers.TestProtos.SparseEnumMessage.Builder> internal__static_protobuf_unittest_SparseEnumMessage__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(
          string.Concat(
            "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", 
            "EGUiowUKGFRlc3RFeHRyZW1lRGVmYXVsdFZhbHVlcxI/Cg1lc2NhcGVkX2J5", 
            "dGVzGAEgASgMOihcMDAwXDAwMVwwMDdcMDEwXDAxNFxuXHJcdFwwMTNcXFwn", 
            "XCJcMzc2EiAKDGxhcmdlX3VpbnQzMhgCIAEoDToKNDI5NDk2NzI5NRIqCgxs", 
            "YXJnZV91aW50NjQYAyABKAQ6FDE4NDQ2NzQ0MDczNzA5NTUxNjE1EiAKC3Nt", 
            "YWxsX2ludDMyGAQgASgFOgstMjE0NzQ4MzY0NxIpCgtzbWFsbF9pbnQ2NBgF", 
            "IAEoAzoULTkyMjMzNzIwMzY4NTQ3NzU4MDcSGAoLdXRmOF9zdHJpbmcYBiAB", 
            "KAk6A+GItBIVCgp6ZXJvX2Zsb2F0GAcgASgCOgEwEhQKCW9uZV9mbG9hdBgI", 
            "IAEoAjoBMRIYCgtzbWFsbF9mbG9hdBgJIAEoAjoDMS41Eh4KEm5lZ2F0aXZl", 
            "X29uZV9mbG9hdBgKIAEoAjoCLTESHAoObmVnYXRpdmVfZmxvYXQYCyABKAI6", 
            "BC0xLjUSGwoLbGFyZ2VfZmxvYXQYDCABKAI6BjJlKzAwOBIlChRzbWFsbF9u", 
            "ZWdhdGl2ZV9mbG9hdBgNIAEoAjoHLThlLTAyOBIXCgppbmZfZG91YmxlGA4g", 
            "ASgBOgNpbmYSHAoObmVnX2luZl9kb3VibGUYDyABKAE6BC1pbmYSFwoKbmFu", 
            "X2RvdWJsZRgQIAEoAToDbmFuEhYKCWluZl9mbG9hdBgRIAEoAjoDaW5mEhsK", 
            "DW5lZ19pbmZfZmxvYXQYEiABKAI6BC1pbmYSFgoJbmFuX2Zsb2F0GBMgASgC", 
            "OgNuYW4SKwoMY3BwX3RyaWdyYXBoGBQgASgJOhU/ID8gPz8gPz8gPz8/ID8/", 
            "LyA/Py0iSwoRU3BhcnNlRW51bU1lc3NhZ2USNgoLc3BhcnNlX2VudW0YASAB", 
            "KA4yIS5wcm90b2J1Zl91bml0dGVzdC5UZXN0U3BhcnNlRW51bSIZCglPbmVT", 
            "dHJpbmcSDAoEZGF0YRgBIAEoCSIYCghPbmVCeXRlcxIMCgRkYXRhGAEgASgM", 
            "IqoDCg9UZXN0UGFja2VkVHlwZXMSGAoMcGFja2VkX2ludDMyGFogAygFQgIQ", 
            "ARIYCgxwYWNrZWRfaW50NjQYWyADKANCAhABEhkKDXBhY2tlZF91aW50MzIY", 
            "XCADKA1CAhABEhkKDXBhY2tlZF91aW50NjQYXSADKARCAhABEhkKDXBhY2tl", 
            "ZF9zaW50MzIYXiADKBFCAhABEhkKDXBhY2tlZF9zaW50NjQYXyADKBJCAhAB", 
            "EhoKDnBhY2tlZF9maXhlZDMyGGAgAygHQgIQARIaCg5wYWNrZWRfZml4ZWQ2", 
            "NBhhIAMoBkICEAESGwoPcGFja2VkX3NmaXhlZDMyGGIgAygPQgIQARIbCg9w", 
            "YWNrZWRfc2ZpeGVkNjQYYyADKBBCAhABEhgKDHBhY2tlZF9mbG9hdBhkIAMo", 
            "AkICEAESGQoNcGFja2VkX2RvdWJsZRhlIAMoAUICEAESFwoLcGFja2VkX2Jv", 
            "b2wYZiADKAhCAhABEjcKC3BhY2tlZF9lbnVtGGcgAygOMh4ucHJvdG9idWZf", 
            "dW5pdHRlc3QuRm9yZWlnbkVudW1CAhABIsgDChFUZXN0VW5wYWNrZWRUeXBl", 
            "cxIaCg51bnBhY2tlZF9pbnQzMhhaIAMoBUICEAASGgoOdW5wYWNrZWRfaW50", 
            "NjQYWyADKANCAhAAEhsKD3VucGFja2VkX3VpbnQzMhhcIAMoDUICEAASGwoP", 
            "dW5wYWNrZWRfdWludDY0GF0gAygEQgIQABIbCg91bnBhY2tlZF9zaW50MzIY", 
            "XiADKBFCAhAAEhsKD3VucGFja2VkX3NpbnQ2NBhfIAMoEkICEAASHAoQdW5w", 
            "YWNrZWRfZml4ZWQzMhhgIAMoB0ICEAASHAoQdW5wYWNrZWRfZml4ZWQ2NBhh", 
            "IAMoBkICEAASHQoRdW5wYWNrZWRfc2ZpeGVkMzIYYiADKA9CAhAAEh0KEXVu", 
            "cGFja2VkX3NmaXhlZDY0GGMgAygQQgIQABIaCg51bnBhY2tlZF9mbG9hdBhk", 
            "IAMoAkICEAASGwoPdW5wYWNrZWRfZG91YmxlGGUgAygBQgIQABIZCg11bnBh", 
            "Y2tlZF9ib29sGGYgAygIQgIQABI5Cg11bnBhY2tlZF9lbnVtGGcgAygOMh4u", 
            "cHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW1CAhAAIiAKFFRlc3RQYWNr", 
            "ZWRFeHRlbnNpb25zKggIARCAgICAAiKZBAoVVGVzdER5bmFtaWNFeHRlbnNp", 
            "b25zEhkKEHNjYWxhcl9leHRlbnNpb24Y0A8gASgHEjcKDmVudW1fZXh0ZW5z", 
            "aW9uGNEPIAEoDjIeLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtElkK", 
            "FmR5bmFtaWNfZW51bV9leHRlbnNpb24Y0g8gASgOMjgucHJvdG9idWZfdW5p", 
            "dHRlc3QuVGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNFbnVtVHlwZRI9", 
            "ChFtZXNzYWdlX2V4dGVuc2lvbhjTDyABKAsyIS5wcm90b2J1Zl91bml0dGVz", 
            "dC5Gb3JlaWduTWVzc2FnZRJfChlkeW5hbWljX21lc3NhZ2VfZXh0ZW5zaW9u", 
            "GNQPIAEoCzI7LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3REeW5hbWljRXh0ZW5z", 
            "aW9ucy5EeW5hbWljTWVzc2FnZVR5cGUSGwoScmVwZWF0ZWRfZXh0ZW5zaW9u", 
            "GNUPIAMoCRIdChBwYWNrZWRfZXh0ZW5zaW9uGNYPIAMoEUICEAEaLAoSRHlu", 
            "YW1pY01lc3NhZ2VUeXBlEhYKDWR5bmFtaWNfZmllbGQYtBAgASgFIkcKD0R5", 
            "bmFtaWNFbnVtVHlwZRIQCgtEWU5BTUlDX0ZPTxCYERIQCgtEWU5BTUlDX0JB", 
            "UhCZERIQCgtEWU5BTUlDX0JBWhCaESLAAQojVGVzdFJlcGVhdGVkU2NhbGFy", 
            "RGlmZmVyZW50VGFnU2l6ZXMSGAoQcmVwZWF0ZWRfZml4ZWQzMhgMIAMoBxIW", 
            "Cg5yZXBlYXRlZF9pbnQzMhgNIAMoBRIZChByZXBlYXRlZF9maXhlZDY0GP4P", 
            "IAMoBhIXCg5yZXBlYXRlZF9pbnQ2NBj/DyADKAMSGAoOcmVwZWF0ZWRfZmxv", 
            "YXQY/v8PIAMoAhIZCg9yZXBlYXRlZF91aW50NjQY//8PIAMoBCIMCgpGb29S", 
            "ZXF1ZXN0Ig0KC0Zvb1Jlc3BvbnNlIgwKCkJhclJlcXVlc3QiDQoLQmFyUmVz", 
            "cG9uc2UqQAoLRm9yZWlnbkVudW0SDwoLRk9SRUlHTl9GT08QBBIPCgtGT1JF", 
            "SUdOX0JBUhAFEg8KC0ZPUkVJR05fQkFaEAYqRwoUVGVzdEVudW1XaXRoRHVw", 
            "VmFsdWUSCAoERk9PMRABEggKBEJBUjEQAhIHCgNCQVoQAxIICgRGT08yEAES", 
            "CAoEQkFSMhACKokBCg5UZXN0U3BhcnNlRW51bRIMCghTUEFSU0VfQRB7Eg4K", 
            "CFNQQVJTRV9CEKbnAxIPCghTUEFSU0VfQxCysYAGEhUKCFNQQVJTRV9EEPH/", 
            "/////////wESFQoIU1BBUlNFX0UQtN78////////ARIMCghTUEFSU0VfRhAA", 
            "EgwKCFNQQVJTRV9HEAIymQEKC1Rlc3RTZXJ2aWNlEkQKA0ZvbxIdLnByb3Rv", 
            "YnVmX3VuaXR0ZXN0LkZvb1JlcXVlc3QaHi5wcm90b2J1Zl91bml0dGVzdC5G", 
            "b29SZXNwb25zZRJECgNCYXISHS5wcm90b2J1Zl91bml0dGVzdC5CYXJSZXF1", 
            "ZXN0Gh4ucHJvdG9idWZfdW5pdHRlc3QuQmFyUmVzcG9uc2U6RgoYb3B0aW9u", 
            "YWxfaW50MzJfZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFs", 
            "bEV4dGVuc2lvbnMYASABKAU6RgoYb3B0aW9uYWxfaW50NjRfZXh0ZW5zaW9u", 
            "EiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYAiABKAM6", 
            "RwoZb3B0aW9uYWxfdWludDMyX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0", 
            "ZXN0LlRlc3RBbGxFeHRlbnNpb25zGAMgASgNOkcKGW9wdGlvbmFsX3VpbnQ2", 
            "NF9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5z", 
            "aW9ucxgEIAEoBDpHChlvcHRpb25hbF9zaW50MzJfZXh0ZW5zaW9uEiQucHJv", 
            "dG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYBSABKBE6RwoZb3B0", 
            "aW9uYWxfc2ludDY0X2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRl", 
            "c3RBbGxFeHRlbnNpb25zGAYgASgSOkgKGm9wdGlvbmFsX2ZpeGVkMzJfZXh0", 
            "ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMY", 
            "ByABKAc6SAoab3B0aW9uYWxfZml4ZWQ2NF9leHRlbnNpb24SJC5wcm90b2J1", 
            "Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxgIIAEoBjpJChtvcHRpb25h", 
            "bF9zZml4ZWQzMl9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0", 
            "QWxsRXh0ZW5zaW9ucxgJIAEoDzpJChtvcHRpb25hbF9zZml4ZWQ2NF9leHRl", 
            "bnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxgK", 
            "IAEoEDpGChhvcHRpb25hbF9mbG9hdF9leHRlbnNpb24SJC5wcm90b2J1Zl91", 
            "bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxgLIAEoAjpHChlvcHRpb25hbF9k", 
            "b3VibGVfZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4", 
            "dGVuc2lvbnMYDCABKAE6RQoXb3B0aW9uYWxfYm9vbF9leHRlbnNpb24SJC5w", 
            "cm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxgNIAEoCDpHChlv", 
            "cHRpb25hbF9zdHJpbmdfZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3Qu", 
            "VGVzdEFsbEV4dGVuc2lvbnMYDiABKAk6RgoYb3B0aW9uYWxfYnl0ZXNfZXh0", 
            "ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMY", 
            "DyABKAw6cQoXb3B0aW9uYWxncm91cF9leHRlbnNpb24SJC5wcm90b2J1Zl91", 
            "bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxgQIAEoCjIqLnByb3RvYnVmX3Vu", 
            "aXR0ZXN0Lk9wdGlvbmFsR3JvdXBfZXh0ZW5zaW9uOn4KIW9wdGlvbmFsX25l", 
            "c3RlZF9tZXNzYWdlX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRl", 
            "c3RBbGxFeHRlbnNpb25zGBIgASgLMi0ucHJvdG9idWZfdW5pdHRlc3QuVGVz", 
            "dEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2U6cwoib3B0aW9uYWxfZm9yZWlnbl9t", 
            "ZXNzYWdlX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxF", 
            "eHRlbnNpb25zGBMgASgLMiEucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1l", 
            "c3NhZ2U6eAohb3B0aW9uYWxfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uEiQu", 
            "cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYFCABKAsyJy5w", 
            "cm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZTp4Ch5vcHRp", 
            "b25hbF9uZXN0ZWRfZW51bV9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVz", 
            "dC5UZXN0QWxsRXh0ZW5zaW9ucxgVIAEoDjIqLnByb3RvYnVmX3VuaXR0ZXN0", 
            "LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtOm0KH29wdGlvbmFsX2ZvcmVpZ25f", 
            "ZW51bV9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0", 
            "ZW5zaW9ucxgWIAEoDjIeLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVt", 
            "OnIKHm9wdGlvbmFsX2ltcG9ydF9lbnVtX2V4dGVuc2lvbhIkLnByb3RvYnVm", 
            "X3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGBcgASgOMiQucHJvdG9idWZf", 
            "dW5pdHRlc3RfaW1wb3J0LkltcG9ydEVudW06UQofb3B0aW9uYWxfc3RyaW5n", 
            "X3BpZWNlX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxF", 
            "eHRlbnNpb25zGBggASgJQgIIAjpJChdvcHRpb25hbF9jb3JkX2V4dGVuc2lv", 
            "bhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGBkgASgJ", 
            "QgIIATpGChhyZXBlYXRlZF9pbnQzMl9leHRlbnNpb24SJC5wcm90b2J1Zl91", 
            "bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxgfIAMoBTpGChhyZXBlYXRlZF9p", 
            "bnQ2NF9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0", 
            "ZW5zaW9ucxggIAMoAzpHChlyZXBlYXRlZF91aW50MzJfZXh0ZW5zaW9uEiQu", 
            "cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYISADKA06RwoZ", 
            "cmVwZWF0ZWRfdWludDY0X2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0", 
            "LlRlc3RBbGxFeHRlbnNpb25zGCIgAygEOkcKGXJlcGVhdGVkX3NpbnQzMl9l", 
            "eHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9u", 
            "cxgjIAMoETpHChlyZXBlYXRlZF9zaW50NjRfZXh0ZW5zaW9uEiQucHJvdG9i", 
            "dWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYJCADKBI6SAoacmVwZWF0", 
            "ZWRfZml4ZWQzMl9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0", 
            "QWxsRXh0ZW5zaW9ucxglIAMoBzpIChpyZXBlYXRlZF9maXhlZDY0X2V4dGVu", 
            "c2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGCYg", 
            "AygGOkkKG3JlcGVhdGVkX3NmaXhlZDMyX2V4dGVuc2lvbhIkLnByb3RvYnVm", 
            "X3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGCcgAygPOkkKG3JlcGVhdGVk", 
            "X3NmaXhlZDY0X2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RB", 
            "bGxFeHRlbnNpb25zGCggAygQOkYKGHJlcGVhdGVkX2Zsb2F0X2V4dGVuc2lv", 
            "bhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGCkgAygC", 
            "OkcKGXJlcGVhdGVkX2RvdWJsZV9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0", 
            "dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxgqIAMoATpFChdyZXBlYXRlZF9ib29s", 
            "X2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNp", 
            "b25zGCsgAygIOkcKGXJlcGVhdGVkX3N0cmluZ19leHRlbnNpb24SJC5wcm90", 
            "b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxgsIAMoCTpGChhyZXBl", 
            "YXRlZF9ieXRlc19leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0", 
            "QWxsRXh0ZW5zaW9ucxgtIAMoDDpxChdyZXBlYXRlZGdyb3VwX2V4dGVuc2lv", 
            "bhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGC4gAygK", 
            "MioucHJvdG9idWZfdW5pdHRlc3QuUmVwZWF0ZWRHcm91cF9leHRlbnNpb246", 
            "fgohcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2VfZXh0ZW5zaW9uEiQucHJvdG9i", 
            "dWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYMCADKAsyLS5wcm90b2J1", 
            "Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZTpzCiJyZXBl", 
            "YXRlZF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5p", 
            "dHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYMSADKAsyIS5wcm90b2J1Zl91bml0", 
            "dGVzdC5Gb3JlaWduTWVzc2FnZTp4CiFyZXBlYXRlZF9pbXBvcnRfbWVzc2Fn", 
            "ZV9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5z", 
            "aW9ucxgyIAMoCzInLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRN", 
            "ZXNzYWdlOngKHnJlcGVhdGVkX25lc3RlZF9lbnVtX2V4dGVuc2lvbhIkLnBy", 
            "b3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGDMgAygOMioucHJv", 
            "dG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZEVudW06bQofcmVw", 
            "ZWF0ZWRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0", 
            "ZXN0LlRlc3RBbGxFeHRlbnNpb25zGDQgAygOMh4ucHJvdG9idWZfdW5pdHRl", 
            "c3QuRm9yZWlnbkVudW06cgoecmVwZWF0ZWRfaW1wb3J0X2VudW1fZXh0ZW5z", 
            "aW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYNSAD", 
            "KA4yJC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0RW51bTpRCh9y", 
            "ZXBlYXRlZF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5p", 
            "dHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYNiADKAlCAggCOkkKF3JlcGVhdGVk", 
            "X2NvcmRfZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4", 
            "dGVuc2lvbnMYNyADKAlCAggBOkkKF2RlZmF1bHRfaW50MzJfZXh0ZW5zaW9u", 
            "EiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYPSABKAU6", 
            "AjQxOkkKF2RlZmF1bHRfaW50NjRfZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5p", 
            "dHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYPiABKAM6AjQyOkoKGGRlZmF1bHRf", 
            "dWludDMyX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxF", 
            "eHRlbnNpb25zGD8gASgNOgI0MzpKChhkZWZhdWx0X3VpbnQ2NF9leHRlbnNp", 
            "b24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxhAIAEo", 
            "BDoCNDQ6SwoYZGVmYXVsdF9zaW50MzJfZXh0ZW5zaW9uEiQucHJvdG9idWZf", 
            "dW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYQSABKBE6Ay00NTpKChhkZWZh", 
            "dWx0X3NpbnQ2NF9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0", 
            "QWxsRXh0ZW5zaW9ucxhCIAEoEjoCNDY6SwoZZGVmYXVsdF9maXhlZDMyX2V4", 
            "dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25z", 
            "GEMgASgHOgI0NzpLChlkZWZhdWx0X2ZpeGVkNjRfZXh0ZW5zaW9uEiQucHJv", 
            "dG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYRCABKAY6AjQ4OkwK", 
            "GmRlZmF1bHRfc2ZpeGVkMzJfZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRl", 
            "c3QuVGVzdEFsbEV4dGVuc2lvbnMYRSABKA86AjQ5Ok0KGmRlZmF1bHRfc2Zp", 
            "eGVkNjRfZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4", 
            "dGVuc2lvbnMYRiABKBA6Ay01MDpLChdkZWZhdWx0X2Zsb2F0X2V4dGVuc2lv", 
            "bhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGEcgASgC", 
            "OgQ1MS41Ok0KGGRlZmF1bHRfZG91YmxlX2V4dGVuc2lvbhIkLnByb3RvYnVm", 
            "X3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGEggASgBOgU1MjAwMDpKChZk", 
            "ZWZhdWx0X2Jvb2xfZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVz", 
            "dEFsbEV4dGVuc2lvbnMYSSABKAg6BHRydWU6TQoYZGVmYXVsdF9zdHJpbmdf", 
            "ZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lv", 
            "bnMYSiABKAk6BWhlbGxvOkwKF2RlZmF1bHRfYnl0ZXNfZXh0ZW5zaW9uEiQu", 
            "cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYSyABKAw6BXdv", 
            "cmxkOnwKHWRlZmF1bHRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uEiQucHJvdG9i", 
            "dWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYUSABKA4yKi5wcm90b2J1", 
            "Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bToDQkFSOnkKHmRl", 
            "ZmF1bHRfZm9yZWlnbl9lbnVtX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0", 
            "ZXN0LlRlc3RBbGxFeHRlbnNpb25zGFIgASgOMh4ucHJvdG9idWZfdW5pdHRl", 
            "c3QuRm9yZWlnbkVudW06C0ZPUkVJR05fQkFSOn0KHWRlZmF1bHRfaW1wb3J0", 
            "X2VudW1fZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4", 
            "dGVuc2lvbnMYUyABKA4yJC5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1w", 
            "b3J0RW51bToKSU1QT1JUX0JBUjpVCh5kZWZhdWx0X3N0cmluZ19waWVjZV9l", 
            "eHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9u", 
            "cxhUIAEoCToDYWJjQgIIAjpNChZkZWZhdWx0X2NvcmRfZXh0ZW5zaW9uEiQu", 
            "cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYVSABKAk6AzEy", 
            "M0ICCAE6QgoTbXlfZXh0ZW5zaW9uX3N0cmluZxIlLnByb3RvYnVmX3VuaXR0", 
            "ZXN0LlRlc3RGaWVsZE9yZGVyaW5ncxgyIAEoCTo/ChBteV9leHRlbnNpb25f", 
            "aW50EiUucHJvdG9idWZfdW5pdHRlc3QuVGVzdEZpZWxkT3JkZXJpbmdzGAUg", 
            "ASgFOksKFnBhY2tlZF9pbnQzMl9leHRlbnNpb24SJy5wcm90b2J1Zl91bml0", 
            "dGVzdC5UZXN0UGFja2VkRXh0ZW5zaW9ucxhaIAMoBUICEAE6SwoWcGFja2Vk", 
            "X2ludDY0X2V4dGVuc2lvbhInLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNr", 
            "ZWRFeHRlbnNpb25zGFsgAygDQgIQATpMChdwYWNrZWRfdWludDMyX2V4dGVu", 
            "c2lvbhInLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRFeHRlbnNpb25z", 
            "GFwgAygNQgIQATpMChdwYWNrZWRfdWludDY0X2V4dGVuc2lvbhInLnByb3Rv", 
            "YnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRFeHRlbnNpb25zGF0gAygEQgIQATpM", 
            "ChdwYWNrZWRfc2ludDMyX2V4dGVuc2lvbhInLnByb3RvYnVmX3VuaXR0ZXN0", 
            "LlRlc3RQYWNrZWRFeHRlbnNpb25zGF4gAygRQgIQATpMChdwYWNrZWRfc2lu", 
            "dDY0X2V4dGVuc2lvbhInLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRF", 
            "eHRlbnNpb25zGF8gAygSQgIQATpNChhwYWNrZWRfZml4ZWQzMl9leHRlbnNp", 
            "b24SJy5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRXh0ZW5zaW9ucxhg", 
            "IAMoB0ICEAE6TQoYcGFja2VkX2ZpeGVkNjRfZXh0ZW5zaW9uEicucHJvdG9i", 
            "dWZfdW5pdHRlc3QuVGVzdFBhY2tlZEV4dGVuc2lvbnMYYSADKAZCAhABOk4K", 
            "GXBhY2tlZF9zZml4ZWQzMl9leHRlbnNpb24SJy5wcm90b2J1Zl91bml0dGVz", 
            "dC5UZXN0UGFja2VkRXh0ZW5zaW9ucxhiIAMoD0ICEAE6TgoZcGFja2VkX3Nm", 
            "aXhlZDY0X2V4dGVuc2lvbhInLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNr", 
            "ZWRFeHRlbnNpb25zGGMgAygQQgIQATpLChZwYWNrZWRfZmxvYXRfZXh0ZW5z", 
            "aW9uEicucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZEV4dGVuc2lvbnMY", 
            "ZCADKAJCAhABOkwKF3BhY2tlZF9kb3VibGVfZXh0ZW5zaW9uEicucHJvdG9i", 
            "dWZfdW5pdHRlc3QuVGVzdFBhY2tlZEV4dGVuc2lvbnMYZSADKAFCAhABOkoK", 
            "FXBhY2tlZF9ib29sX2V4dGVuc2lvbhInLnByb3RvYnVmX3VuaXR0ZXN0LlRl", 
            "c3RQYWNrZWRFeHRlbnNpb25zGGYgAygIQgIQATpqChVwYWNrZWRfZW51bV9l", 
            "eHRlbnNpb24SJy5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRXh0ZW5z", 
            "aW9ucxhnIAMoDjIeLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtQgIQ", 
            "AUJTQg1Vbml0dGVzdFByb3RvSAGAAQGIAQGQAQHCPjYKIUdvb2dsZS5Qcm90", 
          "b2NvbEJ1ZmZlcnMuVGVzdFByb3RvcxIRVW5pdFRlc3RQcm90b0ZpbGU="));
      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", "CppTrigraph", });
        internal__static_protobuf_unittest_SparseEnumMessage__Descriptor = Descriptor.MessageTypes[22];
        internal__static_protobuf_unittest_SparseEnumMessage__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.SparseEnumMessage, global::Google.ProtocolBuffers.TestProtos.SparseEnumMessage.Builder>(internal__static_protobuf_unittest_SparseEnumMessage__Descriptor,
                new string[] { "SparseEnum", });
        internal__static_protobuf_unittest_OneString__Descriptor = Descriptor.MessageTypes[23];
        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[24];
        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[25];
        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[26];
        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[27];
        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[28];
        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[29];
        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[30];
        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[31];
        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[32];
        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[33];
        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
  public enum ForeignEnum {
    FOREIGN_FOO = 4,
    FOREIGN_BAR = 5,
    FOREIGN_BAZ = 6,
  }
  
  public enum TestEnumWithDupValue {
    FOO1 = 1,
    BAR1 = 2,
    BAZ = 3,
    FOO2 = 1,
    BAR2 = 2,
  }
  
  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()]
  public sealed partial class TestAllTypes : pb::GeneratedMessage<TestAllTypes, TestAllTypes.Builder> {
    private TestAllTypes() { }
    private static readonly TestAllTypes defaultInstance = new TestAllTypes().MakeReadOnly();
    private static readonly string[] _testAllTypesFieldNames = new string[] { "default_bool", "default_bytes", "default_cord", "default_double", "default_fixed32", "default_fixed64", "default_float", "default_foreign_enum", "default_import_enum", "default_int32", "default_int64", "default_nested_enum", "default_sfixed32", "default_sfixed64", "default_sint32", "default_sint64", "default_string", "default_string_piece", "default_uint32", "default_uint64", "optional_bool", "optional_bytes", "optional_cord", "optional_double", "optional_fixed32", "optional_fixed64", "optional_float", "optional_foreign_enum", "optional_foreign_message", "optional_import_enum", "optional_import_message", "optional_int32", "optional_int64", "optional_nested_enum", "optional_nested_message", "optional_sfixed32", "optional_sfixed64", "optional_sint32", "optional_sint64", "optional_string", "optional_string_piece", "optional_uint32", "optional_uint64", "optionalgroup", "repeated_bool", "repeated_bytes", "repeated_cord", "repeated_double", "repeated_fixed32", "repeated_fixed64", "repeated_float", "repeated_foreign_enum", "repeated_foreign_message", "repeated_import_enum", "repeated_import_message", "repeated_int32", "repeated_int64", "repeated_nested_enum", "repeated_nested_message", "repeated_sfixed32", "repeated_sfixed64", "repeated_sint32", "repeated_sint64", "repeated_string", "repeated_string_piece", "repeated_uint32", "repeated_uint64", "repeatedgroup" };
    private static readonly uint[] _testAllTypesFieldTags = new uint[] { 584, 602, 682, 577, 541, 545, 573, 656, 664, 488, 496, 648, 557, 561, 520, 528, 594, 674, 504, 512, 104, 122, 202, 97, 61, 65, 93, 176, 154, 184, 162, 8, 16, 168, 146, 77, 81, 40, 48, 114, 194, 24, 32, 131, 344, 362, 442, 337, 301, 305, 333, 416, 394, 424, 402, 248, 256, 408, 386, 317, 321, 280, 288, 354, 434, 264, 272, 371 };
    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()]
    public static partial class Types {
      public enum NestedEnum {
        FOO = 1,
        BAR = 2,
        BAZ = 3,
      }
      
      [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
      public sealed partial class NestedMessage : pb::GeneratedMessage<NestedMessage, NestedMessage.Builder> {
        private NestedMessage() { }
        private static readonly NestedMessage defaultInstance = new NestedMessage().MakeReadOnly();
        private static readonly string[] _nestedMessageFieldNames = new string[] { "bb" };
        private static readonly uint[] _nestedMessageFieldTags = new uint[] { 8 };
        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_;
        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) {
          CalcSerializedSize();
          string[] field_names = _nestedMessageFieldNames;
          if (hasBb) {
            output.WriteInt32(1, field_names[0], Bb);
          }
          UnknownFields.WriteTo(output);
        }
        
        private int memoizedSerializedSize = -1;
        public override int SerializedSize {
          get {
            int size = memoizedSerializedSize;
            if (size != -1) return size;
            return CalcSerializedSize();
          }
        }
        
        private int CalcSerializedSize() {
          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::ICodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static NestedMessage ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        private NestedMessage MakeReadOnly() {
          return this;
        }
        
        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 new Builder(prototype);
        }
        
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public sealed partial class Builder : pb::GeneratedBuilder<NestedMessage, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {
            result = DefaultInstance;
            resultIsReadOnly = true;
          }
          internal Builder(NestedMessage cloneFrom) {
            result = cloneFrom;
            resultIsReadOnly = true;
          }
          
          private bool resultIsReadOnly;
          private NestedMessage result;
          
          private NestedMessage PrepareBuilder() {
            if (resultIsReadOnly) {
              NestedMessage original = result;
              result = new NestedMessage();
              resultIsReadOnly = false;
              MergeFrom(original);
            }
            return result;
          }
          
          public override bool IsInitialized {
            get { return result.IsInitialized; }
          }
          
          protected override NestedMessage MessageBeingBuilt {
            get { return PrepareBuilder(); }
          }
          
          public override Builder Clear() {
            result = DefaultInstance;
            resultIsReadOnly = true;
            return this;
          }
          
          public override Builder Clone() {
            if (resultIsReadOnly) {
              return new Builder(result);
            } else {
              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 (resultIsReadOnly) {
              return result;
            }
            resultIsReadOnly = true;
            return result.MakeReadOnly();
          }
          
          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;
            PrepareBuilder();
            if (other.HasBb) {
              Bb = other.Bb;
            }
            this.MergeUnknownFields(other.UnknownFields);
            return this;
          }
          
          public override Builder MergeFrom(pb::ICodedInputStream input) {
            return MergeFrom(input, pb::ExtensionRegistry.Empty);
          }
          
          public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
            PrepareBuilder();
            pb::UnknownFieldSet.Builder unknownFields = null;
            uint tag;
            string field_name;
            while (input.ReadTag(out tag, out field_name)) {
              if(tag == 0 && field_name != null) {
                int field_ordinal = global::System.Array.BinarySearch(_nestedMessageFieldNames, field_name, global::System.StringComparer.Ordinal);
                if(field_ordinal >= 0)
                  tag = _nestedMessageFieldTags[field_ordinal];
                else {
                  if (unknownFields == null) {
                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                  }
                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
                  continue;
                }
              }
              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) {
            PrepareBuilder();
            result.hasBb = true;
            result.bb_ = value;
            return this;
          }
          public Builder ClearBb() {
            PrepareBuilder();
            result.hasBb = false;
            result.bb_ = 0;
            return this;
          }
        }
        static NestedMessage() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
        }
      }
      
      [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
      public sealed partial class OptionalGroup : pb::GeneratedMessage<OptionalGroup, OptionalGroup.Builder> {
        private OptionalGroup() { }
        private static readonly OptionalGroup defaultInstance = new OptionalGroup().MakeReadOnly();
        private static readonly string[] _optionalGroupFieldNames = new string[] { "a" };
        private static readonly uint[] _optionalGroupFieldTags = new uint[] { 136 };
        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_;
        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) {
          CalcSerializedSize();
          string[] field_names = _optionalGroupFieldNames;
          if (hasA) {
            output.WriteInt32(17, field_names[0], A);
          }
          UnknownFields.WriteTo(output);
        }
        
        private int memoizedSerializedSize = -1;
        public override int SerializedSize {
          get {
            int size = memoizedSerializedSize;
            if (size != -1) return size;
            return CalcSerializedSize();
          }
        }
        
        private int CalcSerializedSize() {
          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::ICodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static OptionalGroup ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        private OptionalGroup MakeReadOnly() {
          return this;
        }
        
        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 new Builder(prototype);
        }
        
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public sealed partial class Builder : pb::GeneratedBuilder<OptionalGroup, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {
            result = DefaultInstance;
            resultIsReadOnly = true;
          }
          internal Builder(OptionalGroup cloneFrom) {
            result = cloneFrom;
            resultIsReadOnly = true;
          }
          
          private bool resultIsReadOnly;
          private OptionalGroup result;
          
          private OptionalGroup PrepareBuilder() {
            if (resultIsReadOnly) {
              OptionalGroup original = result;
              result = new OptionalGroup();
              resultIsReadOnly = false;
              MergeFrom(original);
            }
            return result;
          }
          
          public override bool IsInitialized {
            get { return result.IsInitialized; }
          }
          
          protected override OptionalGroup MessageBeingBuilt {
            get { return PrepareBuilder(); }
          }
          
          public override Builder Clear() {
            result = DefaultInstance;
            resultIsReadOnly = true;
            return this;
          }
          
          public override Builder Clone() {
            if (resultIsReadOnly) {
              return new Builder(result);
            } else {
              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 (resultIsReadOnly) {
              return result;
            }
            resultIsReadOnly = true;
            return result.MakeReadOnly();
          }
          
          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;
            PrepareBuilder();
            if (other.HasA) {
              A = other.A;
            }
            this.MergeUnknownFields(other.UnknownFields);
            return this;
          }
          
          public override Builder MergeFrom(pb::ICodedInputStream input) {
            return MergeFrom(input, pb::ExtensionRegistry.Empty);
          }
          
          public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
            PrepareBuilder();
            pb::UnknownFieldSet.Builder unknownFields = null;
            uint tag;
            string field_name;
            while (input.ReadTag(out tag, out field_name)) {
              if(tag == 0 && field_name != null) {
                int field_ordinal = global::System.Array.BinarySearch(_optionalGroupFieldNames, field_name, global::System.StringComparer.Ordinal);
                if(field_ordinal >= 0)
                  tag = _optionalGroupFieldTags[field_ordinal];
                else {
                  if (unknownFields == null) {
                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                  }
                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
                  continue;
                }
              }
              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) {
            PrepareBuilder();
            result.hasA = true;
            result.a_ = value;
            return this;
          }
          public Builder ClearA() {
            PrepareBuilder();
            result.hasA = false;
            result.a_ = 0;
            return this;
          }
        }
        static OptionalGroup() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
        }
      }
      
      [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
      public sealed partial class RepeatedGroup : pb::GeneratedMessage<RepeatedGroup, RepeatedGroup.Builder> {
        private RepeatedGroup() { }
        private static readonly RepeatedGroup defaultInstance = new RepeatedGroup().MakeReadOnly();
        private static readonly string[] _repeatedGroupFieldNames = new string[] { "a" };
        private static readonly uint[] _repeatedGroupFieldTags = new uint[] { 376 };
        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_;
        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) {
          CalcSerializedSize();
          string[] field_names = _repeatedGroupFieldNames;
          if (hasA) {
            output.WriteInt32(47, field_names[0], A);
          }
          UnknownFields.WriteTo(output);
        }
        
        private int memoizedSerializedSize = -1;
        public override int SerializedSize {
          get {
            int size = memoizedSerializedSize;
            if (size != -1) return size;
            return CalcSerializedSize();
          }
        }
        
        private int CalcSerializedSize() {
          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::ICodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static RepeatedGroup ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        private RepeatedGroup MakeReadOnly() {
          return this;
        }
        
        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 new Builder(prototype);
        }
        
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public sealed partial class Builder : pb::GeneratedBuilder<RepeatedGroup, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {
            result = DefaultInstance;
            resultIsReadOnly = true;
          }
          internal Builder(RepeatedGroup cloneFrom) {
            result = cloneFrom;
            resultIsReadOnly = true;
          }
          
          private bool resultIsReadOnly;
          private RepeatedGroup result;
          
          private RepeatedGroup PrepareBuilder() {
            if (resultIsReadOnly) {
              RepeatedGroup original = result;
              result = new RepeatedGroup();
              resultIsReadOnly = false;
              MergeFrom(original);
            }
            return result;
          }
          
          public override bool IsInitialized {
            get { return result.IsInitialized; }
          }
          
          protected override RepeatedGroup MessageBeingBuilt {
            get { return PrepareBuilder(); }
          }
          
          public override Builder Clear() {
            result = DefaultInstance;
            resultIsReadOnly = true;
            return this;
          }
          
          public override Builder Clone() {
            if (resultIsReadOnly) {
              return new Builder(result);
            } else {
              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 (resultIsReadOnly) {
              return result;
            }
            resultIsReadOnly = true;
            return result.MakeReadOnly();
          }
          
          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;
            PrepareBuilder();
            if (other.HasA) {
              A = other.A;
            }
            this.MergeUnknownFields(other.UnknownFields);
            return this;
          }
          
          public override Builder MergeFrom(pb::ICodedInputStream input) {
            return MergeFrom(input, pb::ExtensionRegistry.Empty);
          }
          
          public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
            PrepareBuilder();
            pb::UnknownFieldSet.Builder unknownFields = null;
            uint tag;
            string field_name;
            while (input.ReadTag(out tag, out field_name)) {
              if(tag == 0 && field_name != null) {
                int field_ordinal = global::System.Array.BinarySearch(_repeatedGroupFieldNames, field_name, global::System.StringComparer.Ordinal);
                if(field_ordinal >= 0)
                  tag = _repeatedGroupFieldTags[field_ordinal];
                else {
                  if (unknownFields == null) {
                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                  }
                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
                  continue;
                }
              }
              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) {
            PrepareBuilder();
            result.hasA = true;
            result.a_ = value;
            return this;
          }
          public Builder ClearA() {
            PrepareBuilder();
            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_;
    public bool HasOptionalInt32 {
      get { return hasOptionalInt32; }
    }
    public int OptionalInt32 {
      get { return optionalInt32_; }
    }
    
    public const int OptionalInt64FieldNumber = 2;
    private bool hasOptionalInt64;
    private long optionalInt64_;
    public bool HasOptionalInt64 {
      get { return hasOptionalInt64; }
    }
    public long OptionalInt64 {
      get { return optionalInt64_; }
    }
    
    public const int OptionalUint32FieldNumber = 3;
    private bool hasOptionalUint32;
    private uint optionalUint32_;
    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_;
    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_;
    public bool HasOptionalSint32 {
      get { return hasOptionalSint32; }
    }
    public int OptionalSint32 {
      get { return optionalSint32_; }
    }
    
    public const int OptionalSint64FieldNumber = 6;
    private bool hasOptionalSint64;
    private long optionalSint64_;
    public bool HasOptionalSint64 {
      get { return hasOptionalSint64; }
    }
    public long OptionalSint64 {
      get { return optionalSint64_; }
    }
    
    public const int OptionalFixed32FieldNumber = 7;
    private bool hasOptionalFixed32;
    private uint optionalFixed32_;
    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_;
    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_;
    public bool HasOptionalSfixed32 {
      get { return hasOptionalSfixed32; }
    }
    public int OptionalSfixed32 {
      get { return optionalSfixed32_; }
    }
    
    public const int OptionalSfixed64FieldNumber = 10;
    private bool hasOptionalSfixed64;
    private long optionalSfixed64_;
    public bool HasOptionalSfixed64 {
      get { return hasOptionalSfixed64; }
    }
    public long OptionalSfixed64 {
      get { return optionalSfixed64_; }
    }
    
    public const int OptionalFloatFieldNumber = 11;
    private bool hasOptionalFloat;
    private float optionalFloat_;
    public bool HasOptionalFloat {
      get { return hasOptionalFloat; }
    }
    public float OptionalFloat {
      get { return optionalFloat_; }
    }
    
    public const int OptionalDoubleFieldNumber = 12;
    private bool hasOptionalDouble;
    private double optionalDouble_;
    public bool HasOptionalDouble {
      get { return hasOptionalDouble; }
    }
    public double OptionalDouble {
      get { return optionalDouble_; }
    }
    
    public const int OptionalBoolFieldNumber = 13;
    private bool hasOptionalBool;
    private bool optionalBool_;
    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_;
    public bool HasOptionalGroup {
      get { return hasOptionalGroup; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.OptionalGroup OptionalGroup {
      get { return optionalGroup_ ?? global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.OptionalGroup.DefaultInstance; }
    }
    
    public const int OptionalNestedMessageFieldNumber = 18;
    private bool hasOptionalNestedMessage;
    private global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage optionalNestedMessage_;
    public bool HasOptionalNestedMessage {
      get { return hasOptionalNestedMessage; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage OptionalNestedMessage {
      get { return optionalNestedMessage_ ?? global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.DefaultInstance; }
    }
    
    public const int OptionalForeignMessageFieldNumber = 19;
    private bool hasOptionalForeignMessage;
    private global::Google.ProtocolBuffers.TestProtos.ForeignMessage optionalForeignMessage_;
    public bool HasOptionalForeignMessage {
      get { return hasOptionalForeignMessage; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ForeignMessage OptionalForeignMessage {
      get { return optionalForeignMessage_ ?? global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance; }
    }
    
    public const int OptionalImportMessageFieldNumber = 20;
    private bool hasOptionalImportMessage;
    private global::Google.ProtocolBuffers.TestProtos.ImportMessage optionalImportMessage_;
    public bool HasOptionalImportMessage {
      get { return hasOptionalImportMessage; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ImportMessage OptionalImportMessage {
      get { return optionalImportMessage_ ?? global::Google.ProtocolBuffers.TestProtos.ImportMessage.DefaultInstance; }
    }
    
    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) {
      CalcSerializedSize();
      string[] field_names = _testAllTypesFieldNames;
      if (hasOptionalInt32) {
        output.WriteInt32(1, field_names[31], OptionalInt32);
      }
      if (hasOptionalInt64) {
        output.WriteInt64(2, field_names[32], OptionalInt64);
      }
      if (hasOptionalUint32) {
        output.WriteUInt32(3, field_names[41], OptionalUint32);
      }
      if (hasOptionalUint64) {
        output.WriteUInt64(4, field_names[42], OptionalUint64);
      }
      if (hasOptionalSint32) {
        output.WriteSInt32(5, field_names[37], OptionalSint32);
      }
      if (hasOptionalSint64) {
        output.WriteSInt64(6, field_names[38], OptionalSint64);
      }
      if (hasOptionalFixed32) {
        output.WriteFixed32(7, field_names[24], OptionalFixed32);
      }
      if (hasOptionalFixed64) {
        output.WriteFixed64(8, field_names[25], OptionalFixed64);
      }
      if (hasOptionalSfixed32) {
        output.WriteSFixed32(9, field_names[35], OptionalSfixed32);
      }
      if (hasOptionalSfixed64) {
        output.WriteSFixed64(10, field_names[36], OptionalSfixed64);
      }
      if (hasOptionalFloat) {
        output.WriteFloat(11, field_names[26], OptionalFloat);
      }
      if (hasOptionalDouble) {
        output.WriteDouble(12, field_names[23], OptionalDouble);
      }
      if (hasOptionalBool) {
        output.WriteBool(13, field_names[20], OptionalBool);
      }
      if (hasOptionalString) {
        output.WriteString(14, field_names[39], OptionalString);
      }
      if (hasOptionalBytes) {
        output.WriteBytes(15, field_names[21], OptionalBytes);
      }
      if (hasOptionalGroup) {
        output.WriteGroup(16, field_names[43], OptionalGroup);
      }
      if (hasOptionalNestedMessage) {
        output.WriteMessage(18, field_names[34], OptionalNestedMessage);
      }
      if (hasOptionalForeignMessage) {
        output.WriteMessage(19, field_names[28], OptionalForeignMessage);
      }
      if (hasOptionalImportMessage) {
        output.WriteMessage(20, field_names[30], OptionalImportMessage);
      }
      if (hasOptionalNestedEnum) {
        output.WriteEnum(21, field_names[33], (int) OptionalNestedEnum, OptionalNestedEnum);
      }
      if (hasOptionalForeignEnum) {
        output.WriteEnum(22, field_names[27], (int) OptionalForeignEnum, OptionalForeignEnum);
      }
      if (hasOptionalImportEnum) {
        output.WriteEnum(23, field_names[29], (int) OptionalImportEnum, OptionalImportEnum);
      }
      if (hasOptionalStringPiece) {
        output.WriteString(24, field_names[40], OptionalStringPiece);
      }
      if (hasOptionalCord) {
        output.WriteString(25, field_names[22], OptionalCord);
      }
      if (repeatedInt32_.Count > 0) {
        output.WriteInt32Array(31, field_names[55], repeatedInt32_);
      }
      if (repeatedInt64_.Count > 0) {
        output.WriteInt64Array(32, field_names[56], repeatedInt64_);
      }
      if (repeatedUint32_.Count > 0) {
        output.WriteUInt32Array(33, field_names[65], repeatedUint32_);
      }
      if (repeatedUint64_.Count > 0) {
        output.WriteUInt64Array(34, field_names[66], repeatedUint64_);
      }
      if (repeatedSint32_.Count > 0) {
        output.WriteSInt32Array(35, field_names[61], repeatedSint32_);
      }
      if (repeatedSint64_.Count > 0) {
        output.WriteSInt64Array(36, field_names[62], repeatedSint64_);
      }
      if (repeatedFixed32_.Count > 0) {
        output.WriteFixed32Array(37, field_names[48], repeatedFixed32_);
      }
      if (repeatedFixed64_.Count > 0) {
        output.WriteFixed64Array(38, field_names[49], repeatedFixed64_);
      }
      if (repeatedSfixed32_.Count > 0) {
        output.WriteSFixed32Array(39, field_names[59], repeatedSfixed32_);
      }
      if (repeatedSfixed64_.Count > 0) {
        output.WriteSFixed64Array(40, field_names[60], repeatedSfixed64_);
      }
      if (repeatedFloat_.Count > 0) {
        output.WriteFloatArray(41, field_names[50], repeatedFloat_);
      }
      if (repeatedDouble_.Count > 0) {
        output.WriteDoubleArray(42, field_names[47], repeatedDouble_);
      }
      if (repeatedBool_.Count > 0) {
        output.WriteBoolArray(43, field_names[44], repeatedBool_);
      }
      if (repeatedString_.Count > 0) {
        output.WriteStringArray(44, field_names[63], repeatedString_);
      }
      if (repeatedBytes_.Count > 0) {
        output.WriteBytesArray(45, field_names[45], repeatedBytes_);
      }
      if (repeatedGroup_.Count > 0) {
        output.WriteGroupArray(46, field_names[67], repeatedGroup_);
      }
      if (repeatedNestedMessage_.Count > 0) {
        output.WriteMessageArray(48, field_names[58], repeatedNestedMessage_);
      }
      if (repeatedForeignMessage_.Count > 0) {
        output.WriteMessageArray(49, field_names[52], repeatedForeignMessage_);
      }
      if (repeatedImportMessage_.Count > 0) {
        output.WriteMessageArray(50, field_names[54], repeatedImportMessage_);
      }
      if (repeatedNestedEnum_.Count > 0) {
        output.WriteEnumArray(51, field_names[57], repeatedNestedEnum_);
      }
      if (repeatedForeignEnum_.Count > 0) {
        output.WriteEnumArray(52, field_names[51], repeatedForeignEnum_);
      }
      if (repeatedImportEnum_.Count > 0) {
        output.WriteEnumArray(53, field_names[53], repeatedImportEnum_);
      }
      if (repeatedStringPiece_.Count > 0) {
        output.WriteStringArray(54, field_names[64], repeatedStringPiece_);
      }
      if (repeatedCord_.Count > 0) {
        output.WriteStringArray(55, field_names[46], repeatedCord_);
      }
      if (hasDefaultInt32) {
        output.WriteInt32(61, field_names[9], DefaultInt32);
      }
      if (hasDefaultInt64) {
        output.WriteInt64(62, field_names[10], DefaultInt64);
      }
      if (hasDefaultUint32) {
        output.WriteUInt32(63, field_names[18], DefaultUint32);
      }
      if (hasDefaultUint64) {
        output.WriteUInt64(64, field_names[19], DefaultUint64);
      }
      if (hasDefaultSint32) {
        output.WriteSInt32(65, field_names[14], DefaultSint32);
      }
      if (hasDefaultSint64) {
        output.WriteSInt64(66, field_names[15], DefaultSint64);
      }
      if (hasDefaultFixed32) {
        output.WriteFixed32(67, field_names[4], DefaultFixed32);
      }
      if (hasDefaultFixed64) {
        output.WriteFixed64(68, field_names[5], DefaultFixed64);
      }
      if (hasDefaultSfixed32) {
        output.WriteSFixed32(69, field_names[12], DefaultSfixed32);
      }
      if (hasDefaultSfixed64) {
        output.WriteSFixed64(70, field_names[13], DefaultSfixed64);
      }
      if (hasDefaultFloat) {
        output.WriteFloat(71, field_names[6], DefaultFloat);
      }
      if (hasDefaultDouble) {
        output.WriteDouble(72, field_names[3], DefaultDouble);
      }
      if (hasDefaultBool) {
        output.WriteBool(73, field_names[0], DefaultBool);
      }
      if (hasDefaultString) {
        output.WriteString(74, field_names[16], DefaultString);
      }
      if (hasDefaultBytes) {
        output.WriteBytes(75, field_names[1], DefaultBytes);
      }
      if (hasDefaultNestedEnum) {
        output.WriteEnum(81, field_names[11], (int) DefaultNestedEnum, DefaultNestedEnum);
      }
      if (hasDefaultForeignEnum) {
        output.WriteEnum(82, field_names[7], (int) DefaultForeignEnum, DefaultForeignEnum);
      }
      if (hasDefaultImportEnum) {
        output.WriteEnum(83, field_names[8], (int) DefaultImportEnum, DefaultImportEnum);
      }
      if (hasDefaultStringPiece) {
        output.WriteString(84, field_names[17], DefaultStringPiece);
      }
      if (hasDefaultCord) {
        output.WriteString(85, field_names[2], DefaultCord);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestAllTypes ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestAllTypes MakeReadOnly() {
      repeatedInt32_.MakeReadOnly();
      repeatedInt64_.MakeReadOnly();
      repeatedUint32_.MakeReadOnly();
      repeatedUint64_.MakeReadOnly();
      repeatedSint32_.MakeReadOnly();
      repeatedSint64_.MakeReadOnly();
      repeatedFixed32_.MakeReadOnly();
      repeatedFixed64_.MakeReadOnly();
      repeatedSfixed32_.MakeReadOnly();
      repeatedSfixed64_.MakeReadOnly();
      repeatedFloat_.MakeReadOnly();
      repeatedDouble_.MakeReadOnly();
      repeatedBool_.MakeReadOnly();
      repeatedString_.MakeReadOnly();
      repeatedBytes_.MakeReadOnly();
      repeatedGroup_.MakeReadOnly();
      repeatedNestedMessage_.MakeReadOnly();
      repeatedForeignMessage_.MakeReadOnly();
      repeatedImportMessage_.MakeReadOnly();
      repeatedNestedEnum_.MakeReadOnly();
      repeatedForeignEnum_.MakeReadOnly();
      repeatedImportEnum_.MakeReadOnly();
      repeatedStringPiece_.MakeReadOnly();
      repeatedCord_.MakeReadOnly();
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestAllTypes, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestAllTypes cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestAllTypes result;
      
      private TestAllTypes PrepareBuilder() {
        if (resultIsReadOnly) {
          TestAllTypes original = result;
          result = new TestAllTypes();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestAllTypes MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        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) {
          result.repeatedInt32_.Add(other.repeatedInt32_);
        }
        if (other.repeatedInt64_.Count != 0) {
          result.repeatedInt64_.Add(other.repeatedInt64_);
        }
        if (other.repeatedUint32_.Count != 0) {
          result.repeatedUint32_.Add(other.repeatedUint32_);
        }
        if (other.repeatedUint64_.Count != 0) {
          result.repeatedUint64_.Add(other.repeatedUint64_);
        }
        if (other.repeatedSint32_.Count != 0) {
          result.repeatedSint32_.Add(other.repeatedSint32_);
        }
        if (other.repeatedSint64_.Count != 0) {
          result.repeatedSint64_.Add(other.repeatedSint64_);
        }
        if (other.repeatedFixed32_.Count != 0) {
          result.repeatedFixed32_.Add(other.repeatedFixed32_);
        }
        if (other.repeatedFixed64_.Count != 0) {
          result.repeatedFixed64_.Add(other.repeatedFixed64_);
        }
        if (other.repeatedSfixed32_.Count != 0) {
          result.repeatedSfixed32_.Add(other.repeatedSfixed32_);
        }
        if (other.repeatedSfixed64_.Count != 0) {
          result.repeatedSfixed64_.Add(other.repeatedSfixed64_);
        }
        if (other.repeatedFloat_.Count != 0) {
          result.repeatedFloat_.Add(other.repeatedFloat_);
        }
        if (other.repeatedDouble_.Count != 0) {
          result.repeatedDouble_.Add(other.repeatedDouble_);
        }
        if (other.repeatedBool_.Count != 0) {
          result.repeatedBool_.Add(other.repeatedBool_);
        }
        if (other.repeatedString_.Count != 0) {
          result.repeatedString_.Add(other.repeatedString_);
        }
        if (other.repeatedBytes_.Count != 0) {
          result.repeatedBytes_.Add(other.repeatedBytes_);
        }
        if (other.repeatedGroup_.Count != 0) {
          result.repeatedGroup_.Add(other.repeatedGroup_);
        }
        if (other.repeatedNestedMessage_.Count != 0) {
          result.repeatedNestedMessage_.Add(other.repeatedNestedMessage_);
        }
        if (other.repeatedForeignMessage_.Count != 0) {
          result.repeatedForeignMessage_.Add(other.repeatedForeignMessage_);
        }
        if (other.repeatedImportMessage_.Count != 0) {
          result.repeatedImportMessage_.Add(other.repeatedImportMessage_);
        }
        if (other.repeatedNestedEnum_.Count != 0) {
          result.repeatedNestedEnum_.Add(other.repeatedNestedEnum_);
        }
        if (other.repeatedForeignEnum_.Count != 0) {
          result.repeatedForeignEnum_.Add(other.repeatedForeignEnum_);
        }
        if (other.repeatedImportEnum_.Count != 0) {
          result.repeatedImportEnum_.Add(other.repeatedImportEnum_);
        }
        if (other.repeatedStringPiece_.Count != 0) {
          result.repeatedStringPiece_.Add(other.repeatedStringPiece_);
        }
        if (other.repeatedCord_.Count != 0) {
          result.repeatedCord_.Add(other.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::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testAllTypesFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testAllTypesFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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 (result.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 (result.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 (result.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 (result.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 250:
            case 248: {
              input.ReadInt32Array(tag, field_name, result.repeatedInt32_);
              break;
            }
            case 258:
            case 256: {
              input.ReadInt64Array(tag, field_name, result.repeatedInt64_);
              break;
            }
            case 266:
            case 264: {
              input.ReadUInt32Array(tag, field_name, result.repeatedUint32_);
              break;
            }
            case 274:
            case 272: {
              input.ReadUInt64Array(tag, field_name, result.repeatedUint64_);
              break;
            }
            case 282:
            case 280: {
              input.ReadSInt32Array(tag, field_name, result.repeatedSint32_);
              break;
            }
            case 290:
            case 288: {
              input.ReadSInt64Array(tag, field_name, result.repeatedSint64_);
              break;
            }
            case 298:
            case 301: {
              input.ReadFixed32Array(tag, field_name, result.repeatedFixed32_);
              break;
            }
            case 306:
            case 305: {
              input.ReadFixed64Array(tag, field_name, result.repeatedFixed64_);
              break;
            }
            case 314:
            case 317: {
              input.ReadSFixed32Array(tag, field_name, result.repeatedSfixed32_);
              break;
            }
            case 322:
            case 321: {
              input.ReadSFixed64Array(tag, field_name, result.repeatedSfixed64_);
              break;
            }
            case 330:
            case 333: {
              input.ReadFloatArray(tag, field_name, result.repeatedFloat_);
              break;
            }
            case 338:
            case 337: {
              input.ReadDoubleArray(tag, field_name, result.repeatedDouble_);
              break;
            }
            case 346:
            case 344: {
              input.ReadBoolArray(tag, field_name, result.repeatedBool_);
              break;
            }
            case 354: {
              input.ReadStringArray(tag, field_name, result.repeatedString_);
              break;
            }
            case 362: {
              input.ReadBytesArray(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 410:
            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 418:
            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 426:
            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.ReadStringArray(tag, field_name, result.repeatedStringPiece_);
              break;
            }
            case 442: {
              input.ReadStringArray(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) {
        PrepareBuilder();
        result.hasOptionalInt32 = true;
        result.optionalInt32_ = value;
        return this;
      }
      public Builder ClearOptionalInt32() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasOptionalInt64 = true;
        result.optionalInt64_ = value;
        return this;
      }
      public Builder ClearOptionalInt64() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasOptionalUint32 = true;
        result.optionalUint32_ = value;
        return this;
      }
      public Builder ClearOptionalUint32() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasOptionalUint64 = true;
        result.optionalUint64_ = value;
        return this;
      }
      public Builder ClearOptionalUint64() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasOptionalSint32 = true;
        result.optionalSint32_ = value;
        return this;
      }
      public Builder ClearOptionalSint32() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasOptionalSint64 = true;
        result.optionalSint64_ = value;
        return this;
      }
      public Builder ClearOptionalSint64() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasOptionalFixed32 = true;
        result.optionalFixed32_ = value;
        return this;
      }
      public Builder ClearOptionalFixed32() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasOptionalFixed64 = true;
        result.optionalFixed64_ = value;
        return this;
      }
      public Builder ClearOptionalFixed64() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasOptionalSfixed32 = true;
        result.optionalSfixed32_ = value;
        return this;
      }
      public Builder ClearOptionalSfixed32() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasOptionalSfixed64 = true;
        result.optionalSfixed64_ = value;
        return this;
      }
      public Builder ClearOptionalSfixed64() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasOptionalFloat = true;
        result.optionalFloat_ = value;
        return this;
      }
      public Builder ClearOptionalFloat() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasOptionalDouble = true;
        result.optionalDouble_ = value;
        return this;
      }
      public Builder ClearOptionalDouble() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasOptionalBool = true;
        result.optionalBool_ = value;
        return this;
      }
      public Builder ClearOptionalBool() {
        PrepareBuilder();
        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");
        PrepareBuilder();
        result.hasOptionalString = true;
        result.optionalString_ = value;
        return this;
      }
      public Builder ClearOptionalString() {
        PrepareBuilder();
        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");
        PrepareBuilder();
        result.hasOptionalBytes = true;
        result.optionalBytes_ = value;
        return this;
      }
      public Builder ClearOptionalBytes() {
        PrepareBuilder();
        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");
        PrepareBuilder();
        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");
        PrepareBuilder();
        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");
        PrepareBuilder();
        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() {
        PrepareBuilder();
        result.hasOptionalGroup = false;
        result.optionalGroup_ = null;
        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");
        PrepareBuilder();
        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");
        PrepareBuilder();
        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");
        PrepareBuilder();
        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() {
        PrepareBuilder();
        result.hasOptionalNestedMessage = false;
        result.optionalNestedMessage_ = null;
        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");
        PrepareBuilder();
        result.hasOptionalForeignMessage = true;
        result.optionalForeignMessage_ = value;
        return this;
      }
      public Builder SetOptionalForeignMessage(global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasOptionalForeignMessage = true;
        result.optionalForeignMessage_ = builderForValue.Build();
        return this;
      }
      public Builder MergeOptionalForeignMessage(global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        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() {
        PrepareBuilder();
        result.hasOptionalForeignMessage = false;
        result.optionalForeignMessage_ = null;
        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");
        PrepareBuilder();
        result.hasOptionalImportMessage = true;
        result.optionalImportMessage_ = value;
        return this;
      }
      public Builder SetOptionalImportMessage(global::Google.ProtocolBuffers.TestProtos.ImportMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasOptionalImportMessage = true;
        result.optionalImportMessage_ = builderForValue.Build();
        return this;
      }
      public Builder MergeOptionalImportMessage(global::Google.ProtocolBuffers.TestProtos.ImportMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        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() {
        PrepareBuilder();
        result.hasOptionalImportMessage = false;
        result.optionalImportMessage_ = null;
        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) {
        PrepareBuilder();
        result.hasOptionalNestedEnum = true;
        result.optionalNestedEnum_ = value;
        return this;
      }
      public Builder ClearOptionalNestedEnum() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasOptionalForeignEnum = true;
        result.optionalForeignEnum_ = value;
        return this;
      }
      public Builder ClearOptionalForeignEnum() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasOptionalImportEnum = true;
        result.optionalImportEnum_ = value;
        return this;
      }
      public Builder ClearOptionalImportEnum() {
        PrepareBuilder();
        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");
        PrepareBuilder();
        result.hasOptionalStringPiece = true;
        result.optionalStringPiece_ = value;
        return this;
      }
      public Builder ClearOptionalStringPiece() {
        PrepareBuilder();
        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");
        PrepareBuilder();
        result.hasOptionalCord = true;
        result.optionalCord_ = value;
        return this;
      }
      public Builder ClearOptionalCord() {
        PrepareBuilder();
        result.hasOptionalCord = false;
        result.optionalCord_ = "";
        return this;
      }
      
      public pbc::IPopsicleList<int> RepeatedInt32List {
        get { return PrepareBuilder().repeatedInt32_; }
      }
      public int RepeatedInt32Count {
        get { return result.RepeatedInt32Count; }
      }
      public int GetRepeatedInt32(int index) {
        return result.GetRepeatedInt32(index);
      }
      public Builder SetRepeatedInt32(int index, int value) {
        PrepareBuilder();
        result.repeatedInt32_[index] = value;
        return this;
      }
      public Builder AddRepeatedInt32(int value) {
        PrepareBuilder();
        result.repeatedInt32_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedInt32(scg::IEnumerable<int> values) {
        PrepareBuilder();
        result.repeatedInt32_.Add(values);
        return this;
      }
      public Builder ClearRepeatedInt32() {
        PrepareBuilder();
        result.repeatedInt32_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<long> RepeatedInt64List {
        get { return PrepareBuilder().repeatedInt64_; }
      }
      public int RepeatedInt64Count {
        get { return result.RepeatedInt64Count; }
      }
      public long GetRepeatedInt64(int index) {
        return result.GetRepeatedInt64(index);
      }
      public Builder SetRepeatedInt64(int index, long value) {
        PrepareBuilder();
        result.repeatedInt64_[index] = value;
        return this;
      }
      public Builder AddRepeatedInt64(long value) {
        PrepareBuilder();
        result.repeatedInt64_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedInt64(scg::IEnumerable<long> values) {
        PrepareBuilder();
        result.repeatedInt64_.Add(values);
        return this;
      }
      public Builder ClearRepeatedInt64() {
        PrepareBuilder();
        result.repeatedInt64_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<uint> RepeatedUint32List {
        get { return PrepareBuilder().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) {
        PrepareBuilder();
        result.repeatedUint32_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRepeatedUint32(uint value) {
        PrepareBuilder();
        result.repeatedUint32_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangeRepeatedUint32(scg::IEnumerable<uint> values) {
        PrepareBuilder();
        result.repeatedUint32_.Add(values);
        return this;
      }
      public Builder ClearRepeatedUint32() {
        PrepareBuilder();
        result.repeatedUint32_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<ulong> RepeatedUint64List {
        get { return PrepareBuilder().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) {
        PrepareBuilder();
        result.repeatedUint64_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRepeatedUint64(ulong value) {
        PrepareBuilder();
        result.repeatedUint64_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangeRepeatedUint64(scg::IEnumerable<ulong> values) {
        PrepareBuilder();
        result.repeatedUint64_.Add(values);
        return this;
      }
      public Builder ClearRepeatedUint64() {
        PrepareBuilder();
        result.repeatedUint64_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<int> RepeatedSint32List {
        get { return PrepareBuilder().repeatedSint32_; }
      }
      public int RepeatedSint32Count {
        get { return result.RepeatedSint32Count; }
      }
      public int GetRepeatedSint32(int index) {
        return result.GetRepeatedSint32(index);
      }
      public Builder SetRepeatedSint32(int index, int value) {
        PrepareBuilder();
        result.repeatedSint32_[index] = value;
        return this;
      }
      public Builder AddRepeatedSint32(int value) {
        PrepareBuilder();
        result.repeatedSint32_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedSint32(scg::IEnumerable<int> values) {
        PrepareBuilder();
        result.repeatedSint32_.Add(values);
        return this;
      }
      public Builder ClearRepeatedSint32() {
        PrepareBuilder();
        result.repeatedSint32_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<long> RepeatedSint64List {
        get { return PrepareBuilder().repeatedSint64_; }
      }
      public int RepeatedSint64Count {
        get { return result.RepeatedSint64Count; }
      }
      public long GetRepeatedSint64(int index) {
        return result.GetRepeatedSint64(index);
      }
      public Builder SetRepeatedSint64(int index, long value) {
        PrepareBuilder();
        result.repeatedSint64_[index] = value;
        return this;
      }
      public Builder AddRepeatedSint64(long value) {
        PrepareBuilder();
        result.repeatedSint64_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedSint64(scg::IEnumerable<long> values) {
        PrepareBuilder();
        result.repeatedSint64_.Add(values);
        return this;
      }
      public Builder ClearRepeatedSint64() {
        PrepareBuilder();
        result.repeatedSint64_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<uint> RepeatedFixed32List {
        get { return PrepareBuilder().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) {
        PrepareBuilder();
        result.repeatedFixed32_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRepeatedFixed32(uint value) {
        PrepareBuilder();
        result.repeatedFixed32_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangeRepeatedFixed32(scg::IEnumerable<uint> values) {
        PrepareBuilder();
        result.repeatedFixed32_.Add(values);
        return this;
      }
      public Builder ClearRepeatedFixed32() {
        PrepareBuilder();
        result.repeatedFixed32_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<ulong> RepeatedFixed64List {
        get { return PrepareBuilder().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) {
        PrepareBuilder();
        result.repeatedFixed64_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRepeatedFixed64(ulong value) {
        PrepareBuilder();
        result.repeatedFixed64_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangeRepeatedFixed64(scg::IEnumerable<ulong> values) {
        PrepareBuilder();
        result.repeatedFixed64_.Add(values);
        return this;
      }
      public Builder ClearRepeatedFixed64() {
        PrepareBuilder();
        result.repeatedFixed64_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<int> RepeatedSfixed32List {
        get { return PrepareBuilder().repeatedSfixed32_; }
      }
      public int RepeatedSfixed32Count {
        get { return result.RepeatedSfixed32Count; }
      }
      public int GetRepeatedSfixed32(int index) {
        return result.GetRepeatedSfixed32(index);
      }
      public Builder SetRepeatedSfixed32(int index, int value) {
        PrepareBuilder();
        result.repeatedSfixed32_[index] = value;
        return this;
      }
      public Builder AddRepeatedSfixed32(int value) {
        PrepareBuilder();
        result.repeatedSfixed32_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedSfixed32(scg::IEnumerable<int> values) {
        PrepareBuilder();
        result.repeatedSfixed32_.Add(values);
        return this;
      }
      public Builder ClearRepeatedSfixed32() {
        PrepareBuilder();
        result.repeatedSfixed32_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<long> RepeatedSfixed64List {
        get { return PrepareBuilder().repeatedSfixed64_; }
      }
      public int RepeatedSfixed64Count {
        get { return result.RepeatedSfixed64Count; }
      }
      public long GetRepeatedSfixed64(int index) {
        return result.GetRepeatedSfixed64(index);
      }
      public Builder SetRepeatedSfixed64(int index, long value) {
        PrepareBuilder();
        result.repeatedSfixed64_[index] = value;
        return this;
      }
      public Builder AddRepeatedSfixed64(long value) {
        PrepareBuilder();
        result.repeatedSfixed64_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedSfixed64(scg::IEnumerable<long> values) {
        PrepareBuilder();
        result.repeatedSfixed64_.Add(values);
        return this;
      }
      public Builder ClearRepeatedSfixed64() {
        PrepareBuilder();
        result.repeatedSfixed64_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<float> RepeatedFloatList {
        get { return PrepareBuilder().repeatedFloat_; }
      }
      public int RepeatedFloatCount {
        get { return result.RepeatedFloatCount; }
      }
      public float GetRepeatedFloat(int index) {
        return result.GetRepeatedFloat(index);
      }
      public Builder SetRepeatedFloat(int index, float value) {
        PrepareBuilder();
        result.repeatedFloat_[index] = value;
        return this;
      }
      public Builder AddRepeatedFloat(float value) {
        PrepareBuilder();
        result.repeatedFloat_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedFloat(scg::IEnumerable<float> values) {
        PrepareBuilder();
        result.repeatedFloat_.Add(values);
        return this;
      }
      public Builder ClearRepeatedFloat() {
        PrepareBuilder();
        result.repeatedFloat_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<double> RepeatedDoubleList {
        get { return PrepareBuilder().repeatedDouble_; }
      }
      public int RepeatedDoubleCount {
        get { return result.RepeatedDoubleCount; }
      }
      public double GetRepeatedDouble(int index) {
        return result.GetRepeatedDouble(index);
      }
      public Builder SetRepeatedDouble(int index, double value) {
        PrepareBuilder();
        result.repeatedDouble_[index] = value;
        return this;
      }
      public Builder AddRepeatedDouble(double value) {
        PrepareBuilder();
        result.repeatedDouble_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedDouble(scg::IEnumerable<double> values) {
        PrepareBuilder();
        result.repeatedDouble_.Add(values);
        return this;
      }
      public Builder ClearRepeatedDouble() {
        PrepareBuilder();
        result.repeatedDouble_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<bool> RepeatedBoolList {
        get { return PrepareBuilder().repeatedBool_; }
      }
      public int RepeatedBoolCount {
        get { return result.RepeatedBoolCount; }
      }
      public bool GetRepeatedBool(int index) {
        return result.GetRepeatedBool(index);
      }
      public Builder SetRepeatedBool(int index, bool value) {
        PrepareBuilder();
        result.repeatedBool_[index] = value;
        return this;
      }
      public Builder AddRepeatedBool(bool value) {
        PrepareBuilder();
        result.repeatedBool_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedBool(scg::IEnumerable<bool> values) {
        PrepareBuilder();
        result.repeatedBool_.Add(values);
        return this;
      }
      public Builder ClearRepeatedBool() {
        PrepareBuilder();
        result.repeatedBool_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<string> RepeatedStringList {
        get { return PrepareBuilder().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");
        PrepareBuilder();
        result.repeatedString_[index] = value;
        return this;
      }
      public Builder AddRepeatedString(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.repeatedString_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedString(scg::IEnumerable<string> values) {
        PrepareBuilder();
        result.repeatedString_.Add(values);
        return this;
      }
      public Builder ClearRepeatedString() {
        PrepareBuilder();
        result.repeatedString_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<pb::ByteString> RepeatedBytesList {
        get { return PrepareBuilder().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");
        PrepareBuilder();
        result.repeatedBytes_[index] = value;
        return this;
      }
      public Builder AddRepeatedBytes(pb::ByteString value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.repeatedBytes_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedBytes(scg::IEnumerable<pb::ByteString> values) {
        PrepareBuilder();
        result.repeatedBytes_.Add(values);
        return this;
      }
      public Builder ClearRepeatedBytes() {
        PrepareBuilder();
        result.repeatedBytes_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup> RepeatedGroupList {
        get { return PrepareBuilder().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");
        PrepareBuilder();
        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");
        PrepareBuilder();
        result.repeatedGroup_[index] = builderForValue.Build();
        return this;
      }
      public Builder AddRepeatedGroup(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.repeatedGroup_.Add(value);
        return this;
      }
      public Builder AddRepeatedGroup(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.repeatedGroup_.Add(builderForValue.Build());
        return this;
      }
      public Builder AddRangeRepeatedGroup(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup> values) {
        PrepareBuilder();
        result.repeatedGroup_.Add(values);
        return this;
      }
      public Builder ClearRepeatedGroup() {
        PrepareBuilder();
        result.repeatedGroup_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage> RepeatedNestedMessageList {
        get { return PrepareBuilder().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");
        PrepareBuilder();
        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");
        PrepareBuilder();
        result.repeatedNestedMessage_[index] = builderForValue.Build();
        return this;
      }
      public Builder AddRepeatedNestedMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.repeatedNestedMessage_.Add(value);
        return this;
      }
      public Builder AddRepeatedNestedMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.repeatedNestedMessage_.Add(builderForValue.Build());
        return this;
      }
      public Builder AddRangeRepeatedNestedMessage(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage> values) {
        PrepareBuilder();
        result.repeatedNestedMessage_.Add(values);
        return this;
      }
      public Builder ClearRepeatedNestedMessage() {
        PrepareBuilder();
        result.repeatedNestedMessage_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignMessage> RepeatedForeignMessageList {
        get { return PrepareBuilder().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");
        PrepareBuilder();
        result.repeatedForeignMessage_[index] = value;
        return this;
      }
      public Builder SetRepeatedForeignMessage(int index, global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.repeatedForeignMessage_[index] = builderForValue.Build();
        return this;
      }
      public Builder AddRepeatedForeignMessage(global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.repeatedForeignMessage_.Add(value);
        return this;
      }
      public Builder AddRepeatedForeignMessage(global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.repeatedForeignMessage_.Add(builderForValue.Build());
        return this;
      }
      public Builder AddRangeRepeatedForeignMessage(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.ForeignMessage> values) {
        PrepareBuilder();
        result.repeatedForeignMessage_.Add(values);
        return this;
      }
      public Builder ClearRepeatedForeignMessage() {
        PrepareBuilder();
        result.repeatedForeignMessage_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.ImportMessage> RepeatedImportMessageList {
        get { return PrepareBuilder().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");
        PrepareBuilder();
        result.repeatedImportMessage_[index] = value;
        return this;
      }
      public Builder SetRepeatedImportMessage(int index, global::Google.ProtocolBuffers.TestProtos.ImportMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.repeatedImportMessage_[index] = builderForValue.Build();
        return this;
      }
      public Builder AddRepeatedImportMessage(global::Google.ProtocolBuffers.TestProtos.ImportMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.repeatedImportMessage_.Add(value);
        return this;
      }
      public Builder AddRepeatedImportMessage(global::Google.ProtocolBuffers.TestProtos.ImportMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.repeatedImportMessage_.Add(builderForValue.Build());
        return this;
      }
      public Builder AddRangeRepeatedImportMessage(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.ImportMessage> values) {
        PrepareBuilder();
        result.repeatedImportMessage_.Add(values);
        return this;
      }
      public Builder ClearRepeatedImportMessage() {
        PrepareBuilder();
        result.repeatedImportMessage_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum> RepeatedNestedEnumList {
        get { return PrepareBuilder().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) {
        PrepareBuilder();
        result.repeatedNestedEnum_[index] = value;
        return this;
      }
      public Builder AddRepeatedNestedEnum(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum value) {
        PrepareBuilder();
        result.repeatedNestedEnum_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedNestedEnum(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum> values) {
        PrepareBuilder();
        result.repeatedNestedEnum_.Add(values);
        return this;
      }
      public Builder ClearRepeatedNestedEnum() {
        PrepareBuilder();
        result.repeatedNestedEnum_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> RepeatedForeignEnumList {
        get { return PrepareBuilder().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) {
        PrepareBuilder();
        result.repeatedForeignEnum_[index] = value;
        return this;
      }
      public Builder AddRepeatedForeignEnum(global::Google.ProtocolBuffers.TestProtos.ForeignEnum value) {
        PrepareBuilder();
        result.repeatedForeignEnum_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedForeignEnum(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> values) {
        PrepareBuilder();
        result.repeatedForeignEnum_.Add(values);
        return this;
      }
      public Builder ClearRepeatedForeignEnum() {
        PrepareBuilder();
        result.repeatedForeignEnum_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.ImportEnum> RepeatedImportEnumList {
        get { return PrepareBuilder().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) {
        PrepareBuilder();
        result.repeatedImportEnum_[index] = value;
        return this;
      }
      public Builder AddRepeatedImportEnum(global::Google.ProtocolBuffers.TestProtos.ImportEnum value) {
        PrepareBuilder();
        result.repeatedImportEnum_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedImportEnum(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.ImportEnum> values) {
        PrepareBuilder();
        result.repeatedImportEnum_.Add(values);
        return this;
      }
      public Builder ClearRepeatedImportEnum() {
        PrepareBuilder();
        result.repeatedImportEnum_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<string> RepeatedStringPieceList {
        get { return PrepareBuilder().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");
        PrepareBuilder();
        result.repeatedStringPiece_[index] = value;
        return this;
      }
      public Builder AddRepeatedStringPiece(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.repeatedStringPiece_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedStringPiece(scg::IEnumerable<string> values) {
        PrepareBuilder();
        result.repeatedStringPiece_.Add(values);
        return this;
      }
      public Builder ClearRepeatedStringPiece() {
        PrepareBuilder();
        result.repeatedStringPiece_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<string> RepeatedCordList {
        get { return PrepareBuilder().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");
        PrepareBuilder();
        result.repeatedCord_[index] = value;
        return this;
      }
      public Builder AddRepeatedCord(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.repeatedCord_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedCord(scg::IEnumerable<string> values) {
        PrepareBuilder();
        result.repeatedCord_.Add(values);
        return this;
      }
      public Builder ClearRepeatedCord() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDefaultInt32 = true;
        result.defaultInt32_ = value;
        return this;
      }
      public Builder ClearDefaultInt32() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDefaultInt64 = true;
        result.defaultInt64_ = value;
        return this;
      }
      public Builder ClearDefaultInt64() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDefaultUint32 = true;
        result.defaultUint32_ = value;
        return this;
      }
      public Builder ClearDefaultUint32() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDefaultUint64 = true;
        result.defaultUint64_ = value;
        return this;
      }
      public Builder ClearDefaultUint64() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDefaultSint32 = true;
        result.defaultSint32_ = value;
        return this;
      }
      public Builder ClearDefaultSint32() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDefaultSint64 = true;
        result.defaultSint64_ = value;
        return this;
      }
      public Builder ClearDefaultSint64() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDefaultFixed32 = true;
        result.defaultFixed32_ = value;
        return this;
      }
      public Builder ClearDefaultFixed32() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDefaultFixed64 = true;
        result.defaultFixed64_ = value;
        return this;
      }
      public Builder ClearDefaultFixed64() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDefaultSfixed32 = true;
        result.defaultSfixed32_ = value;
        return this;
      }
      public Builder ClearDefaultSfixed32() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDefaultSfixed64 = true;
        result.defaultSfixed64_ = value;
        return this;
      }
      public Builder ClearDefaultSfixed64() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDefaultFloat = true;
        result.defaultFloat_ = value;
        return this;
      }
      public Builder ClearDefaultFloat() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDefaultDouble = true;
        result.defaultDouble_ = value;
        return this;
      }
      public Builder ClearDefaultDouble() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDefaultBool = true;
        result.defaultBool_ = value;
        return this;
      }
      public Builder ClearDefaultBool() {
        PrepareBuilder();
        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");
        PrepareBuilder();
        result.hasDefaultString = true;
        result.defaultString_ = value;
        return this;
      }
      public Builder ClearDefaultString() {
        PrepareBuilder();
        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");
        PrepareBuilder();
        result.hasDefaultBytes = true;
        result.defaultBytes_ = value;
        return this;
      }
      public Builder ClearDefaultBytes() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDefaultNestedEnum = true;
        result.defaultNestedEnum_ = value;
        return this;
      }
      public Builder ClearDefaultNestedEnum() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDefaultForeignEnum = true;
        result.defaultForeignEnum_ = value;
        return this;
      }
      public Builder ClearDefaultForeignEnum() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDefaultImportEnum = true;
        result.defaultImportEnum_ = value;
        return this;
      }
      public Builder ClearDefaultImportEnum() {
        PrepareBuilder();
        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");
        PrepareBuilder();
        result.hasDefaultStringPiece = true;
        result.defaultStringPiece_ = value;
        return this;
      }
      public Builder ClearDefaultStringPiece() {
        PrepareBuilder();
        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");
        PrepareBuilder();
        result.hasDefaultCord = true;
        result.defaultCord_ = value;
        return this;
      }
      public Builder ClearDefaultCord() {
        PrepareBuilder();
        result.hasDefaultCord = false;
        result.defaultCord_ = "123";
        return this;
      }
    }
    static TestAllTypes() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestDeprecatedFields : pb::GeneratedMessage<TestDeprecatedFields, TestDeprecatedFields.Builder> {
    private TestDeprecatedFields() { }
    private static readonly TestDeprecatedFields defaultInstance = new TestDeprecatedFields().MakeReadOnly();
    private static readonly string[] _testDeprecatedFieldsFieldNames = new string[] { "deprecated_int32" };
    private static readonly uint[] _testDeprecatedFieldsFieldTags = new uint[] { 8 };
    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_;
    [global::System.ObsoleteAttribute()]
    public bool HasDeprecatedInt32 {
      get { return hasDeprecatedInt32; }
    }
    [global::System.ObsoleteAttribute()]
    public int DeprecatedInt32 {
      get { return deprecatedInt32_; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _testDeprecatedFieldsFieldNames;
      if (hasDeprecatedInt32) {
        output.WriteInt32(1, field_names[0], DeprecatedInt32);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestDeprecatedFields ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestDeprecatedFields MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestDeprecatedFields, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestDeprecatedFields cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestDeprecatedFields result;
      
      private TestDeprecatedFields PrepareBuilder() {
        if (resultIsReadOnly) {
          TestDeprecatedFields original = result;
          result = new TestDeprecatedFields();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestDeprecatedFields MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        if (other.HasDeprecatedInt32) {
          DeprecatedInt32 = other.DeprecatedInt32;
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testDeprecatedFieldsFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testDeprecatedFieldsFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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;
      }
      
      
      [global::System.ObsoleteAttribute()]
      public bool HasDeprecatedInt32 {
        get { return result.hasDeprecatedInt32; }
      }
      [global::System.ObsoleteAttribute()]
      public int DeprecatedInt32 {
        get { return result.DeprecatedInt32; }
        set { SetDeprecatedInt32(value); }
      }
      [global::System.ObsoleteAttribute()]
      public Builder SetDeprecatedInt32(int value) {
        PrepareBuilder();
        result.hasDeprecatedInt32 = true;
        result.deprecatedInt32_ = value;
        return this;
      }
      [global::System.ObsoleteAttribute()]
      public Builder ClearDeprecatedInt32() {
        PrepareBuilder();
        result.hasDeprecatedInt32 = false;
        result.deprecatedInt32_ = 0;
        return this;
      }
    }
    static TestDeprecatedFields() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class ForeignMessage : pb::GeneratedMessage<ForeignMessage, ForeignMessage.Builder> {
    private ForeignMessage() { }
    private static readonly ForeignMessage defaultInstance = new ForeignMessage().MakeReadOnly();
    private static readonly string[] _foreignMessageFieldNames = new string[] { "c" };
    private static readonly uint[] _foreignMessageFieldTags = new uint[] { 8 };
    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_;
    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) {
      CalcSerializedSize();
      string[] field_names = _foreignMessageFieldNames;
      if (hasC) {
        output.WriteInt32(1, field_names[0], C);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static ForeignMessage ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private ForeignMessage MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<ForeignMessage, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(ForeignMessage cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private ForeignMessage result;
      
      private ForeignMessage PrepareBuilder() {
        if (resultIsReadOnly) {
          ForeignMessage original = result;
          result = new ForeignMessage();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override ForeignMessage MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        if (other.HasC) {
          C = other.C;
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_foreignMessageFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _foreignMessageFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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) {
        PrepareBuilder();
        result.hasC = true;
        result.c_ = value;
        return this;
      }
      public Builder ClearC() {
        PrepareBuilder();
        result.hasC = false;
        result.c_ = 0;
        return this;
      }
    }
    static ForeignMessage() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestAllExtensions : pb::ExtendableMessage<TestAllExtensions, TestAllExtensions.Builder> {
    private TestAllExtensions() { }
    private static readonly TestAllExtensions defaultInstance = new TestAllExtensions().MakeReadOnly();
    private static readonly string[] _testAllExtensionsFieldNames = new string[] {  };
    private static readonly uint[] _testAllExtensionsFieldTags = new uint[] {  };
    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) {
      CalcSerializedSize();
      string[] field_names = _testAllExtensionsFieldNames;
      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;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestAllExtensions ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestAllExtensions MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::ExtendableBuilder<TestAllExtensions, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestAllExtensions cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestAllExtensions result;
      
      private TestAllExtensions PrepareBuilder() {
        if (resultIsReadOnly) {
          TestAllExtensions original = result;
          result = new TestAllExtensions();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestAllExtensions MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
          this.MergeExtensionFields(other);
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testAllExtensionsFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testAllExtensionsFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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()]
  public sealed partial class OptionalGroup_extension : pb::GeneratedMessage<OptionalGroup_extension, OptionalGroup_extension.Builder> {
    private OptionalGroup_extension() { }
    private static readonly OptionalGroup_extension defaultInstance = new OptionalGroup_extension().MakeReadOnly();
    private static readonly string[] _optionalGroupExtensionFieldNames = new string[] { "a" };
    private static readonly uint[] _optionalGroupExtensionFieldTags = new uint[] { 136 };
    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_;
    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) {
      CalcSerializedSize();
      string[] field_names = _optionalGroupExtensionFieldNames;
      if (hasA) {
        output.WriteInt32(17, field_names[0], A);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static OptionalGroup_extension ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private OptionalGroup_extension MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<OptionalGroup_extension, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(OptionalGroup_extension cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private OptionalGroup_extension result;
      
      private OptionalGroup_extension PrepareBuilder() {
        if (resultIsReadOnly) {
          OptionalGroup_extension original = result;
          result = new OptionalGroup_extension();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override OptionalGroup_extension MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        if (other.HasA) {
          A = other.A;
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_optionalGroupExtensionFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _optionalGroupExtensionFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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) {
        PrepareBuilder();
        result.hasA = true;
        result.a_ = value;
        return this;
      }
      public Builder ClearA() {
        PrepareBuilder();
        result.hasA = false;
        result.a_ = 0;
        return this;
      }
    }
    static OptionalGroup_extension() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class RepeatedGroup_extension : pb::GeneratedMessage<RepeatedGroup_extension, RepeatedGroup_extension.Builder> {
    private RepeatedGroup_extension() { }
    private static readonly RepeatedGroup_extension defaultInstance = new RepeatedGroup_extension().MakeReadOnly();
    private static readonly string[] _repeatedGroupExtensionFieldNames = new string[] { "a" };
    private static readonly uint[] _repeatedGroupExtensionFieldTags = new uint[] { 376 };
    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_;
    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) {
      CalcSerializedSize();
      string[] field_names = _repeatedGroupExtensionFieldNames;
      if (hasA) {
        output.WriteInt32(47, field_names[0], A);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static RepeatedGroup_extension ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private RepeatedGroup_extension MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<RepeatedGroup_extension, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(RepeatedGroup_extension cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private RepeatedGroup_extension result;
      
      private RepeatedGroup_extension PrepareBuilder() {
        if (resultIsReadOnly) {
          RepeatedGroup_extension original = result;
          result = new RepeatedGroup_extension();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override RepeatedGroup_extension MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        if (other.HasA) {
          A = other.A;
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_repeatedGroupExtensionFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _repeatedGroupExtensionFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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) {
        PrepareBuilder();
        result.hasA = true;
        result.a_ = value;
        return this;
      }
      public Builder ClearA() {
        PrepareBuilder();
        result.hasA = false;
        result.a_ = 0;
        return this;
      }
    }
    static RepeatedGroup_extension() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestNestedExtension : pb::GeneratedMessage<TestNestedExtension, TestNestedExtension.Builder> {
    private TestNestedExtension() { }
    private static readonly TestNestedExtension defaultInstance = new TestNestedExtension().MakeReadOnly();
    private static readonly string[] _testNestedExtensionFieldNames = new string[] {  };
    private static readonly uint[] _testNestedExtensionFieldTags = new uint[] {  };
    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) {
      CalcSerializedSize();
      string[] field_names = _testNestedExtensionFieldNames;
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestNestedExtension ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestNestedExtension MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestNestedExtension, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestNestedExtension cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestNestedExtension result;
      
      private TestNestedExtension PrepareBuilder() {
        if (resultIsReadOnly) {
          TestNestedExtension original = result;
          result = new TestNestedExtension();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestNestedExtension MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testNestedExtensionFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testNestedExtensionFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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()]
  public sealed partial class TestRequired : pb::GeneratedMessage<TestRequired, TestRequired.Builder> {
    private TestRequired() { }
    private static readonly TestRequired defaultInstance = new TestRequired().MakeReadOnly();
    private static readonly string[] _testRequiredFieldNames = new string[] { "a", "b", "c", "dummy10", "dummy11", "dummy12", "dummy13", "dummy14", "dummy15", "dummy16", "dummy17", "dummy18", "dummy19", "dummy2", "dummy20", "dummy21", "dummy22", "dummy23", "dummy24", "dummy25", "dummy26", "dummy27", "dummy28", "dummy29", "dummy30", "dummy31", "dummy32", "dummy4", "dummy5", "dummy6", "dummy7", "dummy8", "dummy9" };
    private static readonly uint[] _testRequiredFieldTags = new uint[] { 8, 24, 264, 80, 88, 96, 104, 112, 120, 128, 136, 144, 152, 16, 160, 168, 176, 184, 192, 200, 208, 216, 224, 232, 240, 248, 256, 32, 40, 48, 56, 64, 72 };
    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_;
    public bool HasA {
      get { return hasA; }
    }
    public int A {
      get { return a_; }
    }
    
    public const int Dummy2FieldNumber = 2;
    private bool hasDummy2;
    private int dummy2_;
    public bool HasDummy2 {
      get { return hasDummy2; }
    }
    public int Dummy2 {
      get { return dummy2_; }
    }
    
    public const int BFieldNumber = 3;
    private bool hasB;
    private int b_;
    public bool HasB {
      get { return hasB; }
    }
    public int B {
      get { return b_; }
    }
    
    public const int Dummy4FieldNumber = 4;
    private bool hasDummy4;
    private int dummy4_;
    public bool HasDummy4 {
      get { return hasDummy4; }
    }
    public int Dummy4 {
      get { return dummy4_; }
    }
    
    public const int Dummy5FieldNumber = 5;
    private bool hasDummy5;
    private int dummy5_;
    public bool HasDummy5 {
      get { return hasDummy5; }
    }
    public int Dummy5 {
      get { return dummy5_; }
    }
    
    public const int Dummy6FieldNumber = 6;
    private bool hasDummy6;
    private int dummy6_;
    public bool HasDummy6 {
      get { return hasDummy6; }
    }
    public int Dummy6 {
      get { return dummy6_; }
    }
    
    public const int Dummy7FieldNumber = 7;
    private bool hasDummy7;
    private int dummy7_;
    public bool HasDummy7 {
      get { return hasDummy7; }
    }
    public int Dummy7 {
      get { return dummy7_; }
    }
    
    public const int Dummy8FieldNumber = 8;
    private bool hasDummy8;
    private int dummy8_;
    public bool HasDummy8 {
      get { return hasDummy8; }
    }
    public int Dummy8 {
      get { return dummy8_; }
    }
    
    public const int Dummy9FieldNumber = 9;
    private bool hasDummy9;
    private int dummy9_;
    public bool HasDummy9 {
      get { return hasDummy9; }
    }
    public int Dummy9 {
      get { return dummy9_; }
    }
    
    public const int Dummy10FieldNumber = 10;
    private bool hasDummy10;
    private int dummy10_;
    public bool HasDummy10 {
      get { return hasDummy10; }
    }
    public int Dummy10 {
      get { return dummy10_; }
    }
    
    public const int Dummy11FieldNumber = 11;
    private bool hasDummy11;
    private int dummy11_;
    public bool HasDummy11 {
      get { return hasDummy11; }
    }
    public int Dummy11 {
      get { return dummy11_; }
    }
    
    public const int Dummy12FieldNumber = 12;
    private bool hasDummy12;
    private int dummy12_;
    public bool HasDummy12 {
      get { return hasDummy12; }
    }
    public int Dummy12 {
      get { return dummy12_; }
    }
    
    public const int Dummy13FieldNumber = 13;
    private bool hasDummy13;
    private int dummy13_;
    public bool HasDummy13 {
      get { return hasDummy13; }
    }
    public int Dummy13 {
      get { return dummy13_; }
    }
    
    public const int Dummy14FieldNumber = 14;
    private bool hasDummy14;
    private int dummy14_;
    public bool HasDummy14 {
      get { return hasDummy14; }
    }
    public int Dummy14 {
      get { return dummy14_; }
    }
    
    public const int Dummy15FieldNumber = 15;
    private bool hasDummy15;
    private int dummy15_;
    public bool HasDummy15 {
      get { return hasDummy15; }
    }
    public int Dummy15 {
      get { return dummy15_; }
    }
    
    public const int Dummy16FieldNumber = 16;
    private bool hasDummy16;
    private int dummy16_;
    public bool HasDummy16 {
      get { return hasDummy16; }
    }
    public int Dummy16 {
      get { return dummy16_; }
    }
    
    public const int Dummy17FieldNumber = 17;
    private bool hasDummy17;
    private int dummy17_;
    public bool HasDummy17 {
      get { return hasDummy17; }
    }
    public int Dummy17 {
      get { return dummy17_; }
    }
    
    public const int Dummy18FieldNumber = 18;
    private bool hasDummy18;
    private int dummy18_;
    public bool HasDummy18 {
      get { return hasDummy18; }
    }
    public int Dummy18 {
      get { return dummy18_; }
    }
    
    public const int Dummy19FieldNumber = 19;
    private bool hasDummy19;
    private int dummy19_;
    public bool HasDummy19 {
      get { return hasDummy19; }
    }
    public int Dummy19 {
      get { return dummy19_; }
    }
    
    public const int Dummy20FieldNumber = 20;
    private bool hasDummy20;
    private int dummy20_;
    public bool HasDummy20 {
      get { return hasDummy20; }
    }
    public int Dummy20 {
      get { return dummy20_; }
    }
    
    public const int Dummy21FieldNumber = 21;
    private bool hasDummy21;
    private int dummy21_;
    public bool HasDummy21 {
      get { return hasDummy21; }
    }
    public int Dummy21 {
      get { return dummy21_; }
    }
    
    public const int Dummy22FieldNumber = 22;
    private bool hasDummy22;
    private int dummy22_;
    public bool HasDummy22 {
      get { return hasDummy22; }
    }
    public int Dummy22 {
      get { return dummy22_; }
    }
    
    public const int Dummy23FieldNumber = 23;
    private bool hasDummy23;
    private int dummy23_;
    public bool HasDummy23 {
      get { return hasDummy23; }
    }
    public int Dummy23 {
      get { return dummy23_; }
    }
    
    public const int Dummy24FieldNumber = 24;
    private bool hasDummy24;
    private int dummy24_;
    public bool HasDummy24 {
      get { return hasDummy24; }
    }
    public int Dummy24 {
      get { return dummy24_; }
    }
    
    public const int Dummy25FieldNumber = 25;
    private bool hasDummy25;
    private int dummy25_;
    public bool HasDummy25 {
      get { return hasDummy25; }
    }
    public int Dummy25 {
      get { return dummy25_; }
    }
    
    public const int Dummy26FieldNumber = 26;
    private bool hasDummy26;
    private int dummy26_;
    public bool HasDummy26 {
      get { return hasDummy26; }
    }
    public int Dummy26 {
      get { return dummy26_; }
    }
    
    public const int Dummy27FieldNumber = 27;
    private bool hasDummy27;
    private int dummy27_;
    public bool HasDummy27 {
      get { return hasDummy27; }
    }
    public int Dummy27 {
      get { return dummy27_; }
    }
    
    public const int Dummy28FieldNumber = 28;
    private bool hasDummy28;
    private int dummy28_;
    public bool HasDummy28 {
      get { return hasDummy28; }
    }
    public int Dummy28 {
      get { return dummy28_; }
    }
    
    public const int Dummy29FieldNumber = 29;
    private bool hasDummy29;
    private int dummy29_;
    public bool HasDummy29 {
      get { return hasDummy29; }
    }
    public int Dummy29 {
      get { return dummy29_; }
    }
    
    public const int Dummy30FieldNumber = 30;
    private bool hasDummy30;
    private int dummy30_;
    public bool HasDummy30 {
      get { return hasDummy30; }
    }
    public int Dummy30 {
      get { return dummy30_; }
    }
    
    public const int Dummy31FieldNumber = 31;
    private bool hasDummy31;
    private int dummy31_;
    public bool HasDummy31 {
      get { return hasDummy31; }
    }
    public int Dummy31 {
      get { return dummy31_; }
    }
    
    public const int Dummy32FieldNumber = 32;
    private bool hasDummy32;
    private int dummy32_;
    public bool HasDummy32 {
      get { return hasDummy32; }
    }
    public int Dummy32 {
      get { return dummy32_; }
    }
    
    public const int CFieldNumber = 33;
    private bool hasC;
    private int c_;
    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) {
      CalcSerializedSize();
      string[] field_names = _testRequiredFieldNames;
      if (hasA) {
        output.WriteInt32(1, field_names[0], A);
      }
      if (hasDummy2) {
        output.WriteInt32(2, field_names[13], Dummy2);
      }
      if (hasB) {
        output.WriteInt32(3, field_names[1], B);
      }
      if (hasDummy4) {
        output.WriteInt32(4, field_names[27], Dummy4);
      }
      if (hasDummy5) {
        output.WriteInt32(5, field_names[28], Dummy5);
      }
      if (hasDummy6) {
        output.WriteInt32(6, field_names[29], Dummy6);
      }
      if (hasDummy7) {
        output.WriteInt32(7, field_names[30], Dummy7);
      }
      if (hasDummy8) {
        output.WriteInt32(8, field_names[31], Dummy8);
      }
      if (hasDummy9) {
        output.WriteInt32(9, field_names[32], Dummy9);
      }
      if (hasDummy10) {
        output.WriteInt32(10, field_names[3], Dummy10);
      }
      if (hasDummy11) {
        output.WriteInt32(11, field_names[4], Dummy11);
      }
      if (hasDummy12) {
        output.WriteInt32(12, field_names[5], Dummy12);
      }
      if (hasDummy13) {
        output.WriteInt32(13, field_names[6], Dummy13);
      }
      if (hasDummy14) {
        output.WriteInt32(14, field_names[7], Dummy14);
      }
      if (hasDummy15) {
        output.WriteInt32(15, field_names[8], Dummy15);
      }
      if (hasDummy16) {
        output.WriteInt32(16, field_names[9], Dummy16);
      }
      if (hasDummy17) {
        output.WriteInt32(17, field_names[10], Dummy17);
      }
      if (hasDummy18) {
        output.WriteInt32(18, field_names[11], Dummy18);
      }
      if (hasDummy19) {
        output.WriteInt32(19, field_names[12], Dummy19);
      }
      if (hasDummy20) {
        output.WriteInt32(20, field_names[14], Dummy20);
      }
      if (hasDummy21) {
        output.WriteInt32(21, field_names[15], Dummy21);
      }
      if (hasDummy22) {
        output.WriteInt32(22, field_names[16], Dummy22);
      }
      if (hasDummy23) {
        output.WriteInt32(23, field_names[17], Dummy23);
      }
      if (hasDummy24) {
        output.WriteInt32(24, field_names[18], Dummy24);
      }
      if (hasDummy25) {
        output.WriteInt32(25, field_names[19], Dummy25);
      }
      if (hasDummy26) {
        output.WriteInt32(26, field_names[20], Dummy26);
      }
      if (hasDummy27) {
        output.WriteInt32(27, field_names[21], Dummy27);
      }
      if (hasDummy28) {
        output.WriteInt32(28, field_names[22], Dummy28);
      }
      if (hasDummy29) {
        output.WriteInt32(29, field_names[23], Dummy29);
      }
      if (hasDummy30) {
        output.WriteInt32(30, field_names[24], Dummy30);
      }
      if (hasDummy31) {
        output.WriteInt32(31, field_names[25], Dummy31);
      }
      if (hasDummy32) {
        output.WriteInt32(32, field_names[26], Dummy32);
      }
      if (hasC) {
        output.WriteInt32(33, field_names[2], C);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestRequired ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestRequired MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestRequired, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestRequired cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestRequired result;
      
      private TestRequired PrepareBuilder() {
        if (resultIsReadOnly) {
          TestRequired original = result;
          result = new TestRequired();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestRequired MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        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::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testRequiredFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testRequiredFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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) {
        PrepareBuilder();
        result.hasA = true;
        result.a_ = value;
        return this;
      }
      public Builder ClearA() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy2 = true;
        result.dummy2_ = value;
        return this;
      }
      public Builder ClearDummy2() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasB = true;
        result.b_ = value;
        return this;
      }
      public Builder ClearB() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy4 = true;
        result.dummy4_ = value;
        return this;
      }
      public Builder ClearDummy4() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy5 = true;
        result.dummy5_ = value;
        return this;
      }
      public Builder ClearDummy5() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy6 = true;
        result.dummy6_ = value;
        return this;
      }
      public Builder ClearDummy6() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy7 = true;
        result.dummy7_ = value;
        return this;
      }
      public Builder ClearDummy7() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy8 = true;
        result.dummy8_ = value;
        return this;
      }
      public Builder ClearDummy8() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy9 = true;
        result.dummy9_ = value;
        return this;
      }
      public Builder ClearDummy9() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy10 = true;
        result.dummy10_ = value;
        return this;
      }
      public Builder ClearDummy10() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy11 = true;
        result.dummy11_ = value;
        return this;
      }
      public Builder ClearDummy11() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy12 = true;
        result.dummy12_ = value;
        return this;
      }
      public Builder ClearDummy12() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy13 = true;
        result.dummy13_ = value;
        return this;
      }
      public Builder ClearDummy13() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy14 = true;
        result.dummy14_ = value;
        return this;
      }
      public Builder ClearDummy14() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy15 = true;
        result.dummy15_ = value;
        return this;
      }
      public Builder ClearDummy15() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy16 = true;
        result.dummy16_ = value;
        return this;
      }
      public Builder ClearDummy16() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy17 = true;
        result.dummy17_ = value;
        return this;
      }
      public Builder ClearDummy17() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy18 = true;
        result.dummy18_ = value;
        return this;
      }
      public Builder ClearDummy18() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy19 = true;
        result.dummy19_ = value;
        return this;
      }
      public Builder ClearDummy19() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy20 = true;
        result.dummy20_ = value;
        return this;
      }
      public Builder ClearDummy20() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy21 = true;
        result.dummy21_ = value;
        return this;
      }
      public Builder ClearDummy21() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy22 = true;
        result.dummy22_ = value;
        return this;
      }
      public Builder ClearDummy22() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy23 = true;
        result.dummy23_ = value;
        return this;
      }
      public Builder ClearDummy23() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy24 = true;
        result.dummy24_ = value;
        return this;
      }
      public Builder ClearDummy24() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy25 = true;
        result.dummy25_ = value;
        return this;
      }
      public Builder ClearDummy25() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy26 = true;
        result.dummy26_ = value;
        return this;
      }
      public Builder ClearDummy26() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy27 = true;
        result.dummy27_ = value;
        return this;
      }
      public Builder ClearDummy27() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy28 = true;
        result.dummy28_ = value;
        return this;
      }
      public Builder ClearDummy28() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy29 = true;
        result.dummy29_ = value;
        return this;
      }
      public Builder ClearDummy29() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy30 = true;
        result.dummy30_ = value;
        return this;
      }
      public Builder ClearDummy30() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy31 = true;
        result.dummy31_ = value;
        return this;
      }
      public Builder ClearDummy31() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy32 = true;
        result.dummy32_ = value;
        return this;
      }
      public Builder ClearDummy32() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasC = true;
        result.c_ = value;
        return this;
      }
      public Builder ClearC() {
        PrepareBuilder();
        result.hasC = false;
        result.c_ = 0;
        return this;
      }
    }
    static TestRequired() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestRequiredForeign : pb::GeneratedMessage<TestRequiredForeign, TestRequiredForeign.Builder> {
    private TestRequiredForeign() { }
    private static readonly TestRequiredForeign defaultInstance = new TestRequiredForeign().MakeReadOnly();
    private static readonly string[] _testRequiredForeignFieldNames = new string[] { "dummy", "optional_message", "repeated_message" };
    private static readonly uint[] _testRequiredForeignFieldTags = new uint[] { 24, 10, 18 };
    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_;
    public bool HasOptionalMessage {
      get { return hasOptionalMessage; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestRequired OptionalMessage {
      get { return optionalMessage_ ?? global::Google.ProtocolBuffers.TestProtos.TestRequired.DefaultInstance; }
    }
    
    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_;
    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) {
      CalcSerializedSize();
      string[] field_names = _testRequiredForeignFieldNames;
      if (hasOptionalMessage) {
        output.WriteMessage(1, field_names[1], OptionalMessage);
      }
      if (repeatedMessage_.Count > 0) {
        output.WriteMessageArray(2, field_names[2], repeatedMessage_);
      }
      if (hasDummy) {
        output.WriteInt32(3, field_names[0], Dummy);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestRequiredForeign ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestRequiredForeign MakeReadOnly() {
      repeatedMessage_.MakeReadOnly();
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestRequiredForeign, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestRequiredForeign cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestRequiredForeign result;
      
      private TestRequiredForeign PrepareBuilder() {
        if (resultIsReadOnly) {
          TestRequiredForeign original = result;
          result = new TestRequiredForeign();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestRequiredForeign MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        if (other.HasOptionalMessage) {
          MergeOptionalMessage(other.OptionalMessage);
        }
        if (other.repeatedMessage_.Count != 0) {
          result.repeatedMessage_.Add(other.repeatedMessage_);
        }
        if (other.HasDummy) {
          Dummy = other.Dummy;
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testRequiredForeignFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testRequiredForeignFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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 (result.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");
        PrepareBuilder();
        result.hasOptionalMessage = true;
        result.optionalMessage_ = value;
        return this;
      }
      public Builder SetOptionalMessage(global::Google.ProtocolBuffers.TestProtos.TestRequired.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasOptionalMessage = true;
        result.optionalMessage_ = builderForValue.Build();
        return this;
      }
      public Builder MergeOptionalMessage(global::Google.ProtocolBuffers.TestProtos.TestRequired value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        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() {
        PrepareBuilder();
        result.hasOptionalMessage = false;
        result.optionalMessage_ = null;
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestRequired> RepeatedMessageList {
        get { return PrepareBuilder().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");
        PrepareBuilder();
        result.repeatedMessage_[index] = value;
        return this;
      }
      public Builder SetRepeatedMessage(int index, global::Google.ProtocolBuffers.TestProtos.TestRequired.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.repeatedMessage_[index] = builderForValue.Build();
        return this;
      }
      public Builder AddRepeatedMessage(global::Google.ProtocolBuffers.TestProtos.TestRequired value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.repeatedMessage_.Add(value);
        return this;
      }
      public Builder AddRepeatedMessage(global::Google.ProtocolBuffers.TestProtos.TestRequired.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.repeatedMessage_.Add(builderForValue.Build());
        return this;
      }
      public Builder AddRangeRepeatedMessage(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestRequired> values) {
        PrepareBuilder();
        result.repeatedMessage_.Add(values);
        return this;
      }
      public Builder ClearRepeatedMessage() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDummy = true;
        result.dummy_ = value;
        return this;
      }
      public Builder ClearDummy() {
        PrepareBuilder();
        result.hasDummy = false;
        result.dummy_ = 0;
        return this;
      }
    }
    static TestRequiredForeign() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestForeignNested : pb::GeneratedMessage<TestForeignNested, TestForeignNested.Builder> {
    private TestForeignNested() { }
    private static readonly TestForeignNested defaultInstance = new TestForeignNested().MakeReadOnly();
    private static readonly string[] _testForeignNestedFieldNames = new string[] { "foreign_nested" };
    private static readonly uint[] _testForeignNestedFieldTags = new uint[] { 10 };
    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_;
    public bool HasForeignNested {
      get { return hasForeignNested; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage ForeignNested {
      get { return foreignNested_ ?? global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.DefaultInstance; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _testForeignNestedFieldNames;
      if (hasForeignNested) {
        output.WriteMessage(1, field_names[0], ForeignNested);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestForeignNested ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestForeignNested MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestForeignNested, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestForeignNested cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestForeignNested result;
      
      private TestForeignNested PrepareBuilder() {
        if (resultIsReadOnly) {
          TestForeignNested original = result;
          result = new TestForeignNested();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestForeignNested MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        if (other.HasForeignNested) {
          MergeForeignNested(other.ForeignNested);
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testForeignNestedFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testForeignNestedFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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 (result.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");
        PrepareBuilder();
        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");
        PrepareBuilder();
        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");
        PrepareBuilder();
        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() {
        PrepareBuilder();
        result.hasForeignNested = false;
        result.foreignNested_ = null;
        return this;
      }
    }
    static TestForeignNested() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestEmptyMessage : pb::GeneratedMessage<TestEmptyMessage, TestEmptyMessage.Builder> {
    private TestEmptyMessage() { }
    private static readonly TestEmptyMessage defaultInstance = new TestEmptyMessage().MakeReadOnly();
    private static readonly string[] _testEmptyMessageFieldNames = new string[] {  };
    private static readonly uint[] _testEmptyMessageFieldTags = new uint[] {  };
    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) {
      CalcSerializedSize();
      string[] field_names = _testEmptyMessageFieldNames;
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestEmptyMessage ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestEmptyMessage MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestEmptyMessage, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestEmptyMessage cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestEmptyMessage result;
      
      private TestEmptyMessage PrepareBuilder() {
        if (resultIsReadOnly) {
          TestEmptyMessage original = result;
          result = new TestEmptyMessage();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestEmptyMessage MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testEmptyMessageFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testEmptyMessageFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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()]
  public sealed partial class TestEmptyMessageWithExtensions : pb::ExtendableMessage<TestEmptyMessageWithExtensions, TestEmptyMessageWithExtensions.Builder> {
    private TestEmptyMessageWithExtensions() { }
    private static readonly TestEmptyMessageWithExtensions defaultInstance = new TestEmptyMessageWithExtensions().MakeReadOnly();
    private static readonly string[] _testEmptyMessageWithExtensionsFieldNames = new string[] {  };
    private static readonly uint[] _testEmptyMessageWithExtensionsFieldTags = new uint[] {  };
    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) {
      CalcSerializedSize();
      string[] field_names = _testEmptyMessageWithExtensionsFieldNames;
      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;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestEmptyMessageWithExtensions ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestEmptyMessageWithExtensions MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::ExtendableBuilder<TestEmptyMessageWithExtensions, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestEmptyMessageWithExtensions cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestEmptyMessageWithExtensions result;
      
      private TestEmptyMessageWithExtensions PrepareBuilder() {
        if (resultIsReadOnly) {
          TestEmptyMessageWithExtensions original = result;
          result = new TestEmptyMessageWithExtensions();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestEmptyMessageWithExtensions MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
          this.MergeExtensionFields(other);
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testEmptyMessageWithExtensionsFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testEmptyMessageWithExtensionsFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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()]
  public sealed partial class TestMultipleExtensionRanges : pb::ExtendableMessage<TestMultipleExtensionRanges, TestMultipleExtensionRanges.Builder> {
    private TestMultipleExtensionRanges() { }
    private static readonly TestMultipleExtensionRanges defaultInstance = new TestMultipleExtensionRanges().MakeReadOnly();
    private static readonly string[] _testMultipleExtensionRangesFieldNames = new string[] {  };
    private static readonly uint[] _testMultipleExtensionRangesFieldTags = new uint[] {  };
    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) {
      CalcSerializedSize();
      string[] field_names = _testMultipleExtensionRangesFieldNames;
      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;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestMultipleExtensionRanges ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestMultipleExtensionRanges MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::ExtendableBuilder<TestMultipleExtensionRanges, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestMultipleExtensionRanges cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestMultipleExtensionRanges result;
      
      private TestMultipleExtensionRanges PrepareBuilder() {
        if (resultIsReadOnly) {
          TestMultipleExtensionRanges original = result;
          result = new TestMultipleExtensionRanges();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestMultipleExtensionRanges MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
          this.MergeExtensionFields(other);
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testMultipleExtensionRangesFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testMultipleExtensionRangesFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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()]
  public sealed partial class TestReallyLargeTagNumber : pb::GeneratedMessage<TestReallyLargeTagNumber, TestReallyLargeTagNumber.Builder> {
    private TestReallyLargeTagNumber() { }
    private static readonly TestReallyLargeTagNumber defaultInstance = new TestReallyLargeTagNumber().MakeReadOnly();
    private static readonly string[] _testReallyLargeTagNumberFieldNames = new string[] { "a", "bb" };
    private static readonly uint[] _testReallyLargeTagNumberFieldTags = new uint[] { 8, 2147483640 };
    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_;
    public bool HasA {
      get { return hasA; }
    }
    public int A {
      get { return a_; }
    }
    
    public const int BbFieldNumber = 268435455;
    private bool hasBb;
    private int bb_;
    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) {
      CalcSerializedSize();
      string[] field_names = _testReallyLargeTagNumberFieldNames;
      if (hasA) {
        output.WriteInt32(1, field_names[0], A);
      }
      if (hasBb) {
        output.WriteInt32(268435455, field_names[1], Bb);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestReallyLargeTagNumber ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestReallyLargeTagNumber MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestReallyLargeTagNumber, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestReallyLargeTagNumber cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestReallyLargeTagNumber result;
      
      private TestReallyLargeTagNumber PrepareBuilder() {
        if (resultIsReadOnly) {
          TestReallyLargeTagNumber original = result;
          result = new TestReallyLargeTagNumber();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestReallyLargeTagNumber MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        if (other.HasA) {
          A = other.A;
        }
        if (other.HasBb) {
          Bb = other.Bb;
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testReallyLargeTagNumberFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testReallyLargeTagNumberFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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) {
        PrepareBuilder();
        result.hasA = true;
        result.a_ = value;
        return this;
      }
      public Builder ClearA() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasBb = true;
        result.bb_ = value;
        return this;
      }
      public Builder ClearBb() {
        PrepareBuilder();
        result.hasBb = false;
        result.bb_ = 0;
        return this;
      }
    }
    static TestReallyLargeTagNumber() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestRecursiveMessage : pb::GeneratedMessage<TestRecursiveMessage, TestRecursiveMessage.Builder> {
    private TestRecursiveMessage() { }
    private static readonly TestRecursiveMessage defaultInstance = new TestRecursiveMessage().MakeReadOnly();
    private static readonly string[] _testRecursiveMessageFieldNames = new string[] { "a", "i" };
    private static readonly uint[] _testRecursiveMessageFieldTags = new uint[] { 10, 16 };
    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_;
    public bool HasA {
      get { return hasA; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestRecursiveMessage A {
      get { return a_ ?? global::Google.ProtocolBuffers.TestProtos.TestRecursiveMessage.DefaultInstance; }
    }
    
    public const int IFieldNumber = 2;
    private bool hasI;
    private int i_;
    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) {
      CalcSerializedSize();
      string[] field_names = _testRecursiveMessageFieldNames;
      if (hasA) {
        output.WriteMessage(1, field_names[0], A);
      }
      if (hasI) {
        output.WriteInt32(2, field_names[1], I);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestRecursiveMessage ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestRecursiveMessage MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestRecursiveMessage, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestRecursiveMessage cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestRecursiveMessage result;
      
      private TestRecursiveMessage PrepareBuilder() {
        if (resultIsReadOnly) {
          TestRecursiveMessage original = result;
          result = new TestRecursiveMessage();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestRecursiveMessage MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        if (other.HasA) {
          MergeA(other.A);
        }
        if (other.HasI) {
          I = other.I;
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testRecursiveMessageFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testRecursiveMessageFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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 (result.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");
        PrepareBuilder();
        result.hasA = true;
        result.a_ = value;
        return this;
      }
      public Builder SetA(global::Google.ProtocolBuffers.TestProtos.TestRecursiveMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasA = true;
        result.a_ = builderForValue.Build();
        return this;
      }
      public Builder MergeA(global::Google.ProtocolBuffers.TestProtos.TestRecursiveMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        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() {
        PrepareBuilder();
        result.hasA = false;
        result.a_ = null;
        return this;
      }
      
      public bool HasI {
        get { return result.hasI; }
      }
      public int I {
        get { return result.I; }
        set { SetI(value); }
      }
      public Builder SetI(int value) {
        PrepareBuilder();
        result.hasI = true;
        result.i_ = value;
        return this;
      }
      public Builder ClearI() {
        PrepareBuilder();
        result.hasI = false;
        result.i_ = 0;
        return this;
      }
    }
    static TestRecursiveMessage() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestMutualRecursionA : pb::GeneratedMessage<TestMutualRecursionA, TestMutualRecursionA.Builder> {
    private TestMutualRecursionA() { }
    private static readonly TestMutualRecursionA defaultInstance = new TestMutualRecursionA().MakeReadOnly();
    private static readonly string[] _testMutualRecursionAFieldNames = new string[] { "bb" };
    private static readonly uint[] _testMutualRecursionAFieldTags = new uint[] { 10 };
    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_;
    public bool HasBb {
      get { return hasBb; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionB Bb {
      get { return bb_ ?? global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionB.DefaultInstance; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _testMutualRecursionAFieldNames;
      if (hasBb) {
        output.WriteMessage(1, field_names[0], Bb);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestMutualRecursionA ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestMutualRecursionA MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestMutualRecursionA, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestMutualRecursionA cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestMutualRecursionA result;
      
      private TestMutualRecursionA PrepareBuilder() {
        if (resultIsReadOnly) {
          TestMutualRecursionA original = result;
          result = new TestMutualRecursionA();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestMutualRecursionA MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        if (other.HasBb) {
          MergeBb(other.Bb);
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testMutualRecursionAFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testMutualRecursionAFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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 (result.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");
        PrepareBuilder();
        result.hasBb = true;
        result.bb_ = value;
        return this;
      }
      public Builder SetBb(global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionB.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasBb = true;
        result.bb_ = builderForValue.Build();
        return this;
      }
      public Builder MergeBb(global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionB value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        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() {
        PrepareBuilder();
        result.hasBb = false;
        result.bb_ = null;
        return this;
      }
    }
    static TestMutualRecursionA() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestMutualRecursionB : pb::GeneratedMessage<TestMutualRecursionB, TestMutualRecursionB.Builder> {
    private TestMutualRecursionB() { }
    private static readonly TestMutualRecursionB defaultInstance = new TestMutualRecursionB().MakeReadOnly();
    private static readonly string[] _testMutualRecursionBFieldNames = new string[] { "a", "optional_int32" };
    private static readonly uint[] _testMutualRecursionBFieldTags = new uint[] { 10, 16 };
    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_;
    public bool HasA {
      get { return hasA; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionA A {
      get { return a_ ?? global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionA.DefaultInstance; }
    }
    
    public const int OptionalInt32FieldNumber = 2;
    private bool hasOptionalInt32;
    private int optionalInt32_;
    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) {
      CalcSerializedSize();
      string[] field_names = _testMutualRecursionBFieldNames;
      if (hasA) {
        output.WriteMessage(1, field_names[0], A);
      }
      if (hasOptionalInt32) {
        output.WriteInt32(2, field_names[1], OptionalInt32);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestMutualRecursionB ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestMutualRecursionB MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestMutualRecursionB, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestMutualRecursionB cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestMutualRecursionB result;
      
      private TestMutualRecursionB PrepareBuilder() {
        if (resultIsReadOnly) {
          TestMutualRecursionB original = result;
          result = new TestMutualRecursionB();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestMutualRecursionB MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        if (other.HasA) {
          MergeA(other.A);
        }
        if (other.HasOptionalInt32) {
          OptionalInt32 = other.OptionalInt32;
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testMutualRecursionBFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testMutualRecursionBFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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 (result.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");
        PrepareBuilder();
        result.hasA = true;
        result.a_ = value;
        return this;
      }
      public Builder SetA(global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionA.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasA = true;
        result.a_ = builderForValue.Build();
        return this;
      }
      public Builder MergeA(global::Google.ProtocolBuffers.TestProtos.TestMutualRecursionA value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        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() {
        PrepareBuilder();
        result.hasA = false;
        result.a_ = null;
        return this;
      }
      
      public bool HasOptionalInt32 {
        get { return result.hasOptionalInt32; }
      }
      public int OptionalInt32 {
        get { return result.OptionalInt32; }
        set { SetOptionalInt32(value); }
      }
      public Builder SetOptionalInt32(int value) {
        PrepareBuilder();
        result.hasOptionalInt32 = true;
        result.optionalInt32_ = value;
        return this;
      }
      public Builder ClearOptionalInt32() {
        PrepareBuilder();
        result.hasOptionalInt32 = false;
        result.optionalInt32_ = 0;
        return this;
      }
    }
    static TestMutualRecursionB() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestDupFieldNumber : pb::GeneratedMessage<TestDupFieldNumber, TestDupFieldNumber.Builder> {
    private TestDupFieldNumber() { }
    private static readonly TestDupFieldNumber defaultInstance = new TestDupFieldNumber().MakeReadOnly();
    private static readonly string[] _testDupFieldNumberFieldNames = new string[] { "a", "bar", "foo" };
    private static readonly uint[] _testDupFieldNumberFieldTags = new uint[] { 8, 27, 19 };
    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()]
    public static partial class Types {
      [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
      public sealed partial class Foo : pb::GeneratedMessage<Foo, Foo.Builder> {
        private Foo() { }
        private static readonly Foo defaultInstance = new Foo().MakeReadOnly();
        private static readonly string[] _fooFieldNames = new string[] { "a" };
        private static readonly uint[] _fooFieldTags = new uint[] { 8 };
        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_;
        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) {
          CalcSerializedSize();
          string[] field_names = _fooFieldNames;
          if (hasA) {
            output.WriteInt32(1, field_names[0], A);
          }
          UnknownFields.WriteTo(output);
        }
        
        private int memoizedSerializedSize = -1;
        public override int SerializedSize {
          get {
            int size = memoizedSerializedSize;
            if (size != -1) return size;
            return CalcSerializedSize();
          }
        }
        
        private int CalcSerializedSize() {
          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::ICodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static Foo ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        private Foo MakeReadOnly() {
          return this;
        }
        
        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 new Builder(prototype);
        }
        
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public sealed partial class Builder : pb::GeneratedBuilder<Foo, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {
            result = DefaultInstance;
            resultIsReadOnly = true;
          }
          internal Builder(Foo cloneFrom) {
            result = cloneFrom;
            resultIsReadOnly = true;
          }
          
          private bool resultIsReadOnly;
          private Foo result;
          
          private Foo PrepareBuilder() {
            if (resultIsReadOnly) {
              Foo original = result;
              result = new Foo();
              resultIsReadOnly = false;
              MergeFrom(original);
            }
            return result;
          }
          
          public override bool IsInitialized {
            get { return result.IsInitialized; }
          }
          
          protected override Foo MessageBeingBuilt {
            get { return PrepareBuilder(); }
          }
          
          public override Builder Clear() {
            result = DefaultInstance;
            resultIsReadOnly = true;
            return this;
          }
          
          public override Builder Clone() {
            if (resultIsReadOnly) {
              return new Builder(result);
            } else {
              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 (resultIsReadOnly) {
              return result;
            }
            resultIsReadOnly = true;
            return result.MakeReadOnly();
          }
          
          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;
            PrepareBuilder();
            if (other.HasA) {
              A = other.A;
            }
            this.MergeUnknownFields(other.UnknownFields);
            return this;
          }
          
          public override Builder MergeFrom(pb::ICodedInputStream input) {
            return MergeFrom(input, pb::ExtensionRegistry.Empty);
          }
          
          public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
            PrepareBuilder();
            pb::UnknownFieldSet.Builder unknownFields = null;
            uint tag;
            string field_name;
            while (input.ReadTag(out tag, out field_name)) {
              if(tag == 0 && field_name != null) {
                int field_ordinal = global::System.Array.BinarySearch(_fooFieldNames, field_name, global::System.StringComparer.Ordinal);
                if(field_ordinal >= 0)
                  tag = _fooFieldTags[field_ordinal];
                else {
                  if (unknownFields == null) {
                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                  }
                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
                  continue;
                }
              }
              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) {
            PrepareBuilder();
            result.hasA = true;
            result.a_ = value;
            return this;
          }
          public Builder ClearA() {
            PrepareBuilder();
            result.hasA = false;
            result.a_ = 0;
            return this;
          }
        }
        static Foo() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
        }
      }
      
      [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
      public sealed partial class Bar : pb::GeneratedMessage<Bar, Bar.Builder> {
        private Bar() { }
        private static readonly Bar defaultInstance = new Bar().MakeReadOnly();
        private static readonly string[] _barFieldNames = new string[] { "a" };
        private static readonly uint[] _barFieldTags = new uint[] { 8 };
        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_;
        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) {
          CalcSerializedSize();
          string[] field_names = _barFieldNames;
          if (hasA) {
            output.WriteInt32(1, field_names[0], A);
          }
          UnknownFields.WriteTo(output);
        }
        
        private int memoizedSerializedSize = -1;
        public override int SerializedSize {
          get {
            int size = memoizedSerializedSize;
            if (size != -1) return size;
            return CalcSerializedSize();
          }
        }
        
        private int CalcSerializedSize() {
          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::ICodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static Bar ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        private Bar MakeReadOnly() {
          return this;
        }
        
        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 new Builder(prototype);
        }
        
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public sealed partial class Builder : pb::GeneratedBuilder<Bar, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {
            result = DefaultInstance;
            resultIsReadOnly = true;
          }
          internal Builder(Bar cloneFrom) {
            result = cloneFrom;
            resultIsReadOnly = true;
          }
          
          private bool resultIsReadOnly;
          private Bar result;
          
          private Bar PrepareBuilder() {
            if (resultIsReadOnly) {
              Bar original = result;
              result = new Bar();
              resultIsReadOnly = false;
              MergeFrom(original);
            }
            return result;
          }
          
          public override bool IsInitialized {
            get { return result.IsInitialized; }
          }
          
          protected override Bar MessageBeingBuilt {
            get { return PrepareBuilder(); }
          }
          
          public override Builder Clear() {
            result = DefaultInstance;
            resultIsReadOnly = true;
            return this;
          }
          
          public override Builder Clone() {
            if (resultIsReadOnly) {
              return new Builder(result);
            } else {
              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 (resultIsReadOnly) {
              return result;
            }
            resultIsReadOnly = true;
            return result.MakeReadOnly();
          }
          
          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;
            PrepareBuilder();
            if (other.HasA) {
              A = other.A;
            }
            this.MergeUnknownFields(other.UnknownFields);
            return this;
          }
          
          public override Builder MergeFrom(pb::ICodedInputStream input) {
            return MergeFrom(input, pb::ExtensionRegistry.Empty);
          }
          
          public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
            PrepareBuilder();
            pb::UnknownFieldSet.Builder unknownFields = null;
            uint tag;
            string field_name;
            while (input.ReadTag(out tag, out field_name)) {
              if(tag == 0 && field_name != null) {
                int field_ordinal = global::System.Array.BinarySearch(_barFieldNames, field_name, global::System.StringComparer.Ordinal);
                if(field_ordinal >= 0)
                  tag = _barFieldTags[field_ordinal];
                else {
                  if (unknownFields == null) {
                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                  }
                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
                  continue;
                }
              }
              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) {
            PrepareBuilder();
            result.hasA = true;
            result.a_ = value;
            return this;
          }
          public Builder ClearA() {
            PrepareBuilder();
            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_;
    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_;
    public bool HasFoo {
      get { return hasFoo; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Foo Foo {
      get { return foo_ ?? global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Foo.DefaultInstance; }
    }
    
    public const int BarFieldNumber = 3;
    private bool hasBar;
    private global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Bar bar_;
    public bool HasBar {
      get { return hasBar; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Bar Bar {
      get { return bar_ ?? global::Google.ProtocolBuffers.TestProtos.TestDupFieldNumber.Types.Bar.DefaultInstance; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _testDupFieldNumberFieldNames;
      if (hasA) {
        output.WriteInt32(1, field_names[0], A);
      }
      if (hasFoo) {
        output.WriteGroup(2, field_names[2], Foo);
      }
      if (hasBar) {
        output.WriteGroup(3, field_names[1], Bar);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestDupFieldNumber ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestDupFieldNumber MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestDupFieldNumber, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestDupFieldNumber cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestDupFieldNumber result;
      
      private TestDupFieldNumber PrepareBuilder() {
        if (resultIsReadOnly) {
          TestDupFieldNumber original = result;
          result = new TestDupFieldNumber();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestDupFieldNumber MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        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::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testDupFieldNumberFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testDupFieldNumberFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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 (result.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 (result.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) {
        PrepareBuilder();
        result.hasA = true;
        result.a_ = value;
        return this;
      }
      public Builder ClearA() {
        PrepareBuilder();
        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");
        PrepareBuilder();
        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");
        PrepareBuilder();
        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");
        PrepareBuilder();
        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() {
        PrepareBuilder();
        result.hasFoo = false;
        result.foo_ = null;
        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");
        PrepareBuilder();
        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");
        PrepareBuilder();
        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");
        PrepareBuilder();
        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() {
        PrepareBuilder();
        result.hasBar = false;
        result.bar_ = null;
        return this;
      }
    }
    static TestDupFieldNumber() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestNestedMessageHasBits : pb::GeneratedMessage<TestNestedMessageHasBits, TestNestedMessageHasBits.Builder> {
    private TestNestedMessageHasBits() { }
    private static readonly TestNestedMessageHasBits defaultInstance = new TestNestedMessageHasBits().MakeReadOnly();
    private static readonly string[] _testNestedMessageHasBitsFieldNames = new string[] { "optional_nested_message" };
    private static readonly uint[] _testNestedMessageHasBitsFieldTags = new uint[] { 10 };
    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()]
    public static partial class Types {
      [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
      public sealed partial class NestedMessage : pb::GeneratedMessage<NestedMessage, NestedMessage.Builder> {
        private NestedMessage() { }
        private static readonly NestedMessage defaultInstance = new NestedMessage().MakeReadOnly();
        private static readonly string[] _nestedMessageFieldNames = new string[] { "nestedmessage_repeated_foreignmessage", "nestedmessage_repeated_int32" };
        private static readonly uint[] _nestedMessageFieldTags = new uint[] { 18, 8 };
        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) {
          CalcSerializedSize();
          string[] field_names = _nestedMessageFieldNames;
          if (nestedmessageRepeatedInt32_.Count > 0) {
            output.WriteInt32Array(1, field_names[1], nestedmessageRepeatedInt32_);
          }
          if (nestedmessageRepeatedForeignmessage_.Count > 0) {
            output.WriteMessageArray(2, field_names[0], nestedmessageRepeatedForeignmessage_);
          }
          UnknownFields.WriteTo(output);
        }
        
        private int memoizedSerializedSize = -1;
        public override int SerializedSize {
          get {
            int size = memoizedSerializedSize;
            if (size != -1) return size;
            return CalcSerializedSize();
          }
        }
        
        private int CalcSerializedSize() {
          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::ICodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static NestedMessage ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        private NestedMessage MakeReadOnly() {
          nestedmessageRepeatedInt32_.MakeReadOnly();
          nestedmessageRepeatedForeignmessage_.MakeReadOnly();
          return this;
        }
        
        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 new Builder(prototype);
        }
        
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public sealed partial class Builder : pb::GeneratedBuilder<NestedMessage, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {
            result = DefaultInstance;
            resultIsReadOnly = true;
          }
          internal Builder(NestedMessage cloneFrom) {
            result = cloneFrom;
            resultIsReadOnly = true;
          }
          
          private bool resultIsReadOnly;
          private NestedMessage result;
          
          private NestedMessage PrepareBuilder() {
            if (resultIsReadOnly) {
              NestedMessage original = result;
              result = new NestedMessage();
              resultIsReadOnly = false;
              MergeFrom(original);
            }
            return result;
          }
          
          public override bool IsInitialized {
            get { return result.IsInitialized; }
          }
          
          protected override NestedMessage MessageBeingBuilt {
            get { return PrepareBuilder(); }
          }
          
          public override Builder Clear() {
            result = DefaultInstance;
            resultIsReadOnly = true;
            return this;
          }
          
          public override Builder Clone() {
            if (resultIsReadOnly) {
              return new Builder(result);
            } else {
              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 (resultIsReadOnly) {
              return result;
            }
            resultIsReadOnly = true;
            return result.MakeReadOnly();
          }
          
          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;
            PrepareBuilder();
            if (other.nestedmessageRepeatedInt32_.Count != 0) {
              result.nestedmessageRepeatedInt32_.Add(other.nestedmessageRepeatedInt32_);
            }
            if (other.nestedmessageRepeatedForeignmessage_.Count != 0) {
              result.nestedmessageRepeatedForeignmessage_.Add(other.nestedmessageRepeatedForeignmessage_);
            }
            this.MergeUnknownFields(other.UnknownFields);
            return this;
          }
          
          public override Builder MergeFrom(pb::ICodedInputStream input) {
            return MergeFrom(input, pb::ExtensionRegistry.Empty);
          }
          
          public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
            PrepareBuilder();
            pb::UnknownFieldSet.Builder unknownFields = null;
            uint tag;
            string field_name;
            while (input.ReadTag(out tag, out field_name)) {
              if(tag == 0 && field_name != null) {
                int field_ordinal = global::System.Array.BinarySearch(_nestedMessageFieldNames, field_name, global::System.StringComparer.Ordinal);
                if(field_ordinal >= 0)
                  tag = _nestedMessageFieldTags[field_ordinal];
                else {
                  if (unknownFields == null) {
                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                  }
                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
                  continue;
                }
              }
              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:
                case 8: {
                  input.ReadInt32Array(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 PrepareBuilder().nestedmessageRepeatedInt32_; }
          }
          public int NestedmessageRepeatedInt32Count {
            get { return result.NestedmessageRepeatedInt32Count; }
          }
          public int GetNestedmessageRepeatedInt32(int index) {
            return result.GetNestedmessageRepeatedInt32(index);
          }
          public Builder SetNestedmessageRepeatedInt32(int index, int value) {
            PrepareBuilder();
            result.nestedmessageRepeatedInt32_[index] = value;
            return this;
          }
          public Builder AddNestedmessageRepeatedInt32(int value) {
            PrepareBuilder();
            result.nestedmessageRepeatedInt32_.Add(value);
            return this;
          }
          public Builder AddRangeNestedmessageRepeatedInt32(scg::IEnumerable<int> values) {
            PrepareBuilder();
            result.nestedmessageRepeatedInt32_.Add(values);
            return this;
          }
          public Builder ClearNestedmessageRepeatedInt32() {
            PrepareBuilder();
            result.nestedmessageRepeatedInt32_.Clear();
            return this;
          }
          
          public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignMessage> NestedmessageRepeatedForeignmessageList {
            get { return PrepareBuilder().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");
            PrepareBuilder();
            result.nestedmessageRepeatedForeignmessage_[index] = value;
            return this;
          }
          public Builder SetNestedmessageRepeatedForeignmessage(int index, global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder builderForValue) {
            pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
            PrepareBuilder();
            result.nestedmessageRepeatedForeignmessage_[index] = builderForValue.Build();
            return this;
          }
          public Builder AddNestedmessageRepeatedForeignmessage(global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            result.nestedmessageRepeatedForeignmessage_.Add(value);
            return this;
          }
          public Builder AddNestedmessageRepeatedForeignmessage(global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder builderForValue) {
            pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
            PrepareBuilder();
            result.nestedmessageRepeatedForeignmessage_.Add(builderForValue.Build());
            return this;
          }
          public Builder AddRangeNestedmessageRepeatedForeignmessage(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.ForeignMessage> values) {
            PrepareBuilder();
            result.nestedmessageRepeatedForeignmessage_.Add(values);
            return this;
          }
          public Builder ClearNestedmessageRepeatedForeignmessage() {
            PrepareBuilder();
            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_;
    public bool HasOptionalNestedMessage {
      get { return hasOptionalNestedMessage; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Types.NestedMessage OptionalNestedMessage {
      get { return optionalNestedMessage_ ?? global::Google.ProtocolBuffers.TestProtos.TestNestedMessageHasBits.Types.NestedMessage.DefaultInstance; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _testNestedMessageHasBitsFieldNames;
      if (hasOptionalNestedMessage) {
        output.WriteMessage(1, field_names[0], OptionalNestedMessage);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestNestedMessageHasBits ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestNestedMessageHasBits MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestNestedMessageHasBits, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestNestedMessageHasBits cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestNestedMessageHasBits result;
      
      private TestNestedMessageHasBits PrepareBuilder() {
        if (resultIsReadOnly) {
          TestNestedMessageHasBits original = result;
          result = new TestNestedMessageHasBits();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestNestedMessageHasBits MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        if (other.HasOptionalNestedMessage) {
          MergeOptionalNestedMessage(other.OptionalNestedMessage);
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testNestedMessageHasBitsFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testNestedMessageHasBitsFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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 (result.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");
        PrepareBuilder();
        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");
        PrepareBuilder();
        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");
        PrepareBuilder();
        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() {
        PrepareBuilder();
        result.hasOptionalNestedMessage = false;
        result.optionalNestedMessage_ = null;
        return this;
      }
    }
    static TestNestedMessageHasBits() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestCamelCaseFieldNames : pb::GeneratedMessage<TestCamelCaseFieldNames, TestCamelCaseFieldNames.Builder> {
    private TestCamelCaseFieldNames() { }
    private static readonly TestCamelCaseFieldNames defaultInstance = new TestCamelCaseFieldNames().MakeReadOnly();
    private static readonly string[] _testCamelCaseFieldNamesFieldNames = new string[] { "CordField", "EnumField", "MessageField", "PrimitiveField", "RepeatedCordField", "RepeatedEnumField", "RepeatedMessageField", "RepeatedPrimitiveField", "RepeatedStringField", "RepeatedStringPieceField", "StringField", "StringPieceField" };
    private static readonly uint[] _testCamelCaseFieldNamesFieldTags = new uint[] { 50, 24, 34, 8, 98, 72, 82, 56, 66, 90, 18, 42 };
    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_;
    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_;
    public bool HasMessageField {
      get { return hasMessageField; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ForeignMessage MessageField {
      get { return messageField_ ?? global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance; }
    }
    
    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) {
      CalcSerializedSize();
      string[] field_names = _testCamelCaseFieldNamesFieldNames;
      if (hasPrimitiveField) {
        output.WriteInt32(1, field_names[3], PrimitiveField);
      }
      if (hasStringField) {
        output.WriteString(2, field_names[10], StringField);
      }
      if (hasEnumField) {
        output.WriteEnum(3, field_names[1], (int) EnumField, EnumField);
      }
      if (hasMessageField) {
        output.WriteMessage(4, field_names[2], MessageField);
      }
      if (hasStringPieceField) {
        output.WriteString(5, field_names[11], StringPieceField);
      }
      if (hasCordField) {
        output.WriteString(6, field_names[0], CordField);
      }
      if (repeatedPrimitiveField_.Count > 0) {
        output.WriteInt32Array(7, field_names[7], repeatedPrimitiveField_);
      }
      if (repeatedStringField_.Count > 0) {
        output.WriteStringArray(8, field_names[8], repeatedStringField_);
      }
      if (repeatedEnumField_.Count > 0) {
        output.WriteEnumArray(9, field_names[5], repeatedEnumField_);
      }
      if (repeatedMessageField_.Count > 0) {
        output.WriteMessageArray(10, field_names[6], repeatedMessageField_);
      }
      if (repeatedStringPieceField_.Count > 0) {
        output.WriteStringArray(11, field_names[9], repeatedStringPieceField_);
      }
      if (repeatedCordField_.Count > 0) {
        output.WriteStringArray(12, field_names[4], repeatedCordField_);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestCamelCaseFieldNames ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestCamelCaseFieldNames MakeReadOnly() {
      repeatedPrimitiveField_.MakeReadOnly();
      repeatedStringField_.MakeReadOnly();
      repeatedEnumField_.MakeReadOnly();
      repeatedMessageField_.MakeReadOnly();
      repeatedStringPieceField_.MakeReadOnly();
      repeatedCordField_.MakeReadOnly();
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestCamelCaseFieldNames, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestCamelCaseFieldNames cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestCamelCaseFieldNames result;
      
      private TestCamelCaseFieldNames PrepareBuilder() {
        if (resultIsReadOnly) {
          TestCamelCaseFieldNames original = result;
          result = new TestCamelCaseFieldNames();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestCamelCaseFieldNames MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        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) {
          result.repeatedPrimitiveField_.Add(other.repeatedPrimitiveField_);
        }
        if (other.repeatedStringField_.Count != 0) {
          result.repeatedStringField_.Add(other.repeatedStringField_);
        }
        if (other.repeatedEnumField_.Count != 0) {
          result.repeatedEnumField_.Add(other.repeatedEnumField_);
        }
        if (other.repeatedMessageField_.Count != 0) {
          result.repeatedMessageField_.Add(other.repeatedMessageField_);
        }
        if (other.repeatedStringPieceField_.Count != 0) {
          result.repeatedStringPieceField_.Add(other.repeatedStringPieceField_);
        }
        if (other.repeatedCordField_.Count != 0) {
          result.repeatedCordField_.Add(other.repeatedCordField_);
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testCamelCaseFieldNamesFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testCamelCaseFieldNamesFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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 (result.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 58:
            case 56: {
              input.ReadInt32Array(tag, field_name, result.repeatedPrimitiveField_);
              break;
            }
            case 66: {
              input.ReadStringArray(tag, field_name, result.repeatedStringField_);
              break;
            }
            case 74:
            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.ReadStringArray(tag, field_name, result.repeatedStringPieceField_);
              break;
            }
            case 98: {
              input.ReadStringArray(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) {
        PrepareBuilder();
        result.hasPrimitiveField = true;
        result.primitiveField_ = value;
        return this;
      }
      public Builder ClearPrimitiveField() {
        PrepareBuilder();
        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");
        PrepareBuilder();
        result.hasStringField = true;
        result.stringField_ = value;
        return this;
      }
      public Builder ClearStringField() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasEnumField = true;
        result.enumField_ = value;
        return this;
      }
      public Builder ClearEnumField() {
        PrepareBuilder();
        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");
        PrepareBuilder();
        result.hasMessageField = true;
        result.messageField_ = value;
        return this;
      }
      public Builder SetMessageField(global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasMessageField = true;
        result.messageField_ = builderForValue.Build();
        return this;
      }
      public Builder MergeMessageField(global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        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() {
        PrepareBuilder();
        result.hasMessageField = false;
        result.messageField_ = null;
        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");
        PrepareBuilder();
        result.hasStringPieceField = true;
        result.stringPieceField_ = value;
        return this;
      }
      public Builder ClearStringPieceField() {
        PrepareBuilder();
        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");
        PrepareBuilder();
        result.hasCordField = true;
        result.cordField_ = value;
        return this;
      }
      public Builder ClearCordField() {
        PrepareBuilder();
        result.hasCordField = false;
        result.cordField_ = "";
        return this;
      }
      
      public pbc::IPopsicleList<int> RepeatedPrimitiveFieldList {
        get { return PrepareBuilder().repeatedPrimitiveField_; }
      }
      public int RepeatedPrimitiveFieldCount {
        get { return result.RepeatedPrimitiveFieldCount; }
      }
      public int GetRepeatedPrimitiveField(int index) {
        return result.GetRepeatedPrimitiveField(index);
      }
      public Builder SetRepeatedPrimitiveField(int index, int value) {
        PrepareBuilder();
        result.repeatedPrimitiveField_[index] = value;
        return this;
      }
      public Builder AddRepeatedPrimitiveField(int value) {
        PrepareBuilder();
        result.repeatedPrimitiveField_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedPrimitiveField(scg::IEnumerable<int> values) {
        PrepareBuilder();
        result.repeatedPrimitiveField_.Add(values);
        return this;
      }
      public Builder ClearRepeatedPrimitiveField() {
        PrepareBuilder();
        result.repeatedPrimitiveField_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<string> RepeatedStringFieldList {
        get { return PrepareBuilder().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");
        PrepareBuilder();
        result.repeatedStringField_[index] = value;
        return this;
      }
      public Builder AddRepeatedStringField(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.repeatedStringField_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedStringField(scg::IEnumerable<string> values) {
        PrepareBuilder();
        result.repeatedStringField_.Add(values);
        return this;
      }
      public Builder ClearRepeatedStringField() {
        PrepareBuilder();
        result.repeatedStringField_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> RepeatedEnumFieldList {
        get { return PrepareBuilder().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) {
        PrepareBuilder();
        result.repeatedEnumField_[index] = value;
        return this;
      }
      public Builder AddRepeatedEnumField(global::Google.ProtocolBuffers.TestProtos.ForeignEnum value) {
        PrepareBuilder();
        result.repeatedEnumField_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedEnumField(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> values) {
        PrepareBuilder();
        result.repeatedEnumField_.Add(values);
        return this;
      }
      public Builder ClearRepeatedEnumField() {
        PrepareBuilder();
        result.repeatedEnumField_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignMessage> RepeatedMessageFieldList {
        get { return PrepareBuilder().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");
        PrepareBuilder();
        result.repeatedMessageField_[index] = value;
        return this;
      }
      public Builder SetRepeatedMessageField(int index, global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.repeatedMessageField_[index] = builderForValue.Build();
        return this;
      }
      public Builder AddRepeatedMessageField(global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.repeatedMessageField_.Add(value);
        return this;
      }
      public Builder AddRepeatedMessageField(global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.repeatedMessageField_.Add(builderForValue.Build());
        return this;
      }
      public Builder AddRangeRepeatedMessageField(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.ForeignMessage> values) {
        PrepareBuilder();
        result.repeatedMessageField_.Add(values);
        return this;
      }
      public Builder ClearRepeatedMessageField() {
        PrepareBuilder();
        result.repeatedMessageField_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<string> RepeatedStringPieceFieldList {
        get { return PrepareBuilder().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");
        PrepareBuilder();
        result.repeatedStringPieceField_[index] = value;
        return this;
      }
      public Builder AddRepeatedStringPieceField(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.repeatedStringPieceField_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedStringPieceField(scg::IEnumerable<string> values) {
        PrepareBuilder();
        result.repeatedStringPieceField_.Add(values);
        return this;
      }
      public Builder ClearRepeatedStringPieceField() {
        PrepareBuilder();
        result.repeatedStringPieceField_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<string> RepeatedCordFieldList {
        get { return PrepareBuilder().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");
        PrepareBuilder();
        result.repeatedCordField_[index] = value;
        return this;
      }
      public Builder AddRepeatedCordField(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.repeatedCordField_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedCordField(scg::IEnumerable<string> values) {
        PrepareBuilder();
        result.repeatedCordField_.Add(values);
        return this;
      }
      public Builder ClearRepeatedCordField() {
        PrepareBuilder();
        result.repeatedCordField_.Clear();
        return this;
      }
    }
    static TestCamelCaseFieldNames() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestFieldOrderings : pb::ExtendableMessage<TestFieldOrderings, TestFieldOrderings.Builder> {
    private TestFieldOrderings() { }
    private static readonly TestFieldOrderings defaultInstance = new TestFieldOrderings().MakeReadOnly();
    private static readonly string[] _testFieldOrderingsFieldNames = new string[] { "my_float", "my_int", "my_string" };
    private static readonly uint[] _testFieldOrderingsFieldTags = new uint[] { 813, 8, 90 };
    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_;
    public bool HasMyInt {
      get { return hasMyInt; }
    }
    public long MyInt {
      get { return myInt_; }
    }
    
    public const int MyFloatFieldNumber = 101;
    private bool hasMyFloat;
    private float myFloat_;
    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) {
      CalcSerializedSize();
      string[] field_names = _testFieldOrderingsFieldNames;
      pb::ExtendableMessage<TestFieldOrderings, TestFieldOrderings.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
      if (hasMyInt) {
        output.WriteInt64(1, field_names[1], MyInt);
      }
      extensionWriter.WriteUntil(11, output);
      if (hasMyString) {
        output.WriteString(11, field_names[2], MyString);
      }
      extensionWriter.WriteUntil(101, output);
      if (hasMyFloat) {
        output.WriteFloat(101, field_names[0], MyFloat);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestFieldOrderings ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestFieldOrderings MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::ExtendableBuilder<TestFieldOrderings, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestFieldOrderings cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestFieldOrderings result;
      
      private TestFieldOrderings PrepareBuilder() {
        if (resultIsReadOnly) {
          TestFieldOrderings original = result;
          result = new TestFieldOrderings();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestFieldOrderings MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        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::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testFieldOrderingsFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testFieldOrderingsFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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");
        PrepareBuilder();
        result.hasMyString = true;
        result.myString_ = value;
        return this;
      }
      public Builder ClearMyString() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasMyInt = true;
        result.myInt_ = value;
        return this;
      }
      public Builder ClearMyInt() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasMyFloat = true;
        result.myFloat_ = value;
        return this;
      }
      public Builder ClearMyFloat() {
        PrepareBuilder();
        result.hasMyFloat = false;
        result.myFloat_ = 0F;
        return this;
      }
    }
    static TestFieldOrderings() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestExtremeDefaultValues : pb::GeneratedMessage<TestExtremeDefaultValues, TestExtremeDefaultValues.Builder> {
    private TestExtremeDefaultValues() { }
    private static readonly TestExtremeDefaultValues defaultInstance = new TestExtremeDefaultValues().MakeReadOnly();
    private static readonly string[] _testExtremeDefaultValuesFieldNames = new string[] { "cpp_trigraph", "escaped_bytes", "inf_double", "inf_float", "large_float", "large_uint32", "large_uint64", "nan_double", "nan_float", "neg_inf_double", "neg_inf_float", "negative_float", "negative_one_float", "one_float", "small_float", "small_int32", "small_int64", "small_negative_float", "utf8_string", "zero_float" };
    private static readonly uint[] _testExtremeDefaultValuesFieldTags = new uint[] { 162, 10, 113, 141, 101, 16, 24, 129, 157, 121, 149, 93, 85, 69, 77, 32, 40, 109, 50, 61 };
    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_;
    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 const int CppTrigraphFieldNumber = 20;
    private bool hasCppTrigraph;
    private string cppTrigraph_ = "? ? ?? ?? ??? ??/ ??-";
    public bool HasCppTrigraph {
      get { return hasCppTrigraph; }
    }
    public string CppTrigraph {
      get { return cppTrigraph_; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _testExtremeDefaultValuesFieldNames;
      if (hasEscapedBytes) {
        output.WriteBytes(1, field_names[1], EscapedBytes);
      }
      if (hasLargeUint32) {
        output.WriteUInt32(2, field_names[5], LargeUint32);
      }
      if (hasLargeUint64) {
        output.WriteUInt64(3, field_names[6], LargeUint64);
      }
      if (hasSmallInt32) {
        output.WriteInt32(4, field_names[15], SmallInt32);
      }
      if (hasSmallInt64) {
        output.WriteInt64(5, field_names[16], SmallInt64);
      }
      if (hasUtf8String) {
        output.WriteString(6, field_names[18], Utf8String);
      }
      if (hasZeroFloat) {
        output.WriteFloat(7, field_names[19], ZeroFloat);
      }
      if (hasOneFloat) {
        output.WriteFloat(8, field_names[13], OneFloat);
      }
      if (hasSmallFloat) {
        output.WriteFloat(9, field_names[14], SmallFloat);
      }
      if (hasNegativeOneFloat) {
        output.WriteFloat(10, field_names[12], NegativeOneFloat);
      }
      if (hasNegativeFloat) {
        output.WriteFloat(11, field_names[11], NegativeFloat);
      }
      if (hasLargeFloat) {
        output.WriteFloat(12, field_names[4], LargeFloat);
      }
      if (hasSmallNegativeFloat) {
        output.WriteFloat(13, field_names[17], SmallNegativeFloat);
      }
      if (hasInfDouble) {
        output.WriteDouble(14, field_names[2], InfDouble);
      }
      if (hasNegInfDouble) {
        output.WriteDouble(15, field_names[9], NegInfDouble);
      }
      if (hasNanDouble) {
        output.WriteDouble(16, field_names[7], NanDouble);
      }
      if (hasInfFloat) {
        output.WriteFloat(17, field_names[3], InfFloat);
      }
      if (hasNegInfFloat) {
        output.WriteFloat(18, field_names[10], NegInfFloat);
      }
      if (hasNanFloat) {
        output.WriteFloat(19, field_names[8], NanFloat);
      }
      if (hasCppTrigraph) {
        output.WriteString(20, field_names[0], CppTrigraph);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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);
      }
      if (hasCppTrigraph) {
        size += pb::CodedOutputStream.ComputeStringSize(20, CppTrigraph);
      }
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestExtremeDefaultValues ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestExtremeDefaultValues MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestExtremeDefaultValues, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestExtremeDefaultValues cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestExtremeDefaultValues result;
      
      private TestExtremeDefaultValues PrepareBuilder() {
        if (resultIsReadOnly) {
          TestExtremeDefaultValues original = result;
          result = new TestExtremeDefaultValues();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestExtremeDefaultValues MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        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;
        }
        if (other.HasCppTrigraph) {
          CppTrigraph = other.CppTrigraph;
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testExtremeDefaultValuesFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testExtremeDefaultValuesFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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;
            }
            case 162: {
              result.hasCppTrigraph = input.ReadString(ref result.cppTrigraph_);
              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");
        PrepareBuilder();
        result.hasEscapedBytes = true;
        result.escapedBytes_ = value;
        return this;
      }
      public Builder ClearEscapedBytes() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasLargeUint32 = true;
        result.largeUint32_ = value;
        return this;
      }
      public Builder ClearLargeUint32() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasLargeUint64 = true;
        result.largeUint64_ = value;
        return this;
      }
      public Builder ClearLargeUint64() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasSmallInt32 = true;
        result.smallInt32_ = value;
        return this;
      }
      public Builder ClearSmallInt32() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasSmallInt64 = true;
        result.smallInt64_ = value;
        return this;
      }
      public Builder ClearSmallInt64() {
        PrepareBuilder();
        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");
        PrepareBuilder();
        result.hasUtf8String = true;
        result.utf8String_ = value;
        return this;
      }
      public Builder ClearUtf8String() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasZeroFloat = true;
        result.zeroFloat_ = value;
        return this;
      }
      public Builder ClearZeroFloat() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasOneFloat = true;
        result.oneFloat_ = value;
        return this;
      }
      public Builder ClearOneFloat() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasSmallFloat = true;
        result.smallFloat_ = value;
        return this;
      }
      public Builder ClearSmallFloat() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasNegativeOneFloat = true;
        result.negativeOneFloat_ = value;
        return this;
      }
      public Builder ClearNegativeOneFloat() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasNegativeFloat = true;
        result.negativeFloat_ = value;
        return this;
      }
      public Builder ClearNegativeFloat() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasLargeFloat = true;
        result.largeFloat_ = value;
        return this;
      }
      public Builder ClearLargeFloat() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasSmallNegativeFloat = true;
        result.smallNegativeFloat_ = value;
        return this;
      }
      public Builder ClearSmallNegativeFloat() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasInfDouble = true;
        result.infDouble_ = value;
        return this;
      }
      public Builder ClearInfDouble() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasNegInfDouble = true;
        result.negInfDouble_ = value;
        return this;
      }
      public Builder ClearNegInfDouble() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasNanDouble = true;
        result.nanDouble_ = value;
        return this;
      }
      public Builder ClearNanDouble() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasInfFloat = true;
        result.infFloat_ = value;
        return this;
      }
      public Builder ClearInfFloat() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasNegInfFloat = true;
        result.negInfFloat_ = value;
        return this;
      }
      public Builder ClearNegInfFloat() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasNanFloat = true;
        result.nanFloat_ = value;
        return this;
      }
      public Builder ClearNanFloat() {
        PrepareBuilder();
        result.hasNanFloat = false;
        result.nanFloat_ = float.NaN;
        return this;
      }
      
      public bool HasCppTrigraph {
        get { return result.hasCppTrigraph; }
      }
      public string CppTrigraph {
        get { return result.CppTrigraph; }
        set { SetCppTrigraph(value); }
      }
      public Builder SetCppTrigraph(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasCppTrigraph = true;
        result.cppTrigraph_ = value;
        return this;
      }
      public Builder ClearCppTrigraph() {
        PrepareBuilder();
        result.hasCppTrigraph = false;
        result.cppTrigraph_ = "? ? ?? ?? ??? ??/ ??-";
        return this;
      }
    }
    static TestExtremeDefaultValues() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class SparseEnumMessage : pb::GeneratedMessage<SparseEnumMessage, SparseEnumMessage.Builder> {
    private SparseEnumMessage() { }
    private static readonly SparseEnumMessage defaultInstance = new SparseEnumMessage().MakeReadOnly();
    private static readonly string[] _sparseEnumMessageFieldNames = new string[] { "sparse_enum" };
    private static readonly uint[] _sparseEnumMessageFieldTags = new uint[] { 8 };
    public static SparseEnumMessage DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override SparseEnumMessage DefaultInstanceForType {
      get { return DefaultInstance; }
    }
    
    protected override SparseEnumMessage ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_SparseEnumMessage__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<SparseEnumMessage, SparseEnumMessage.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.internal__static_protobuf_unittest_SparseEnumMessage__FieldAccessorTable; }
    }
    
    public const int SparseEnumFieldNumber = 1;
    private bool hasSparseEnum;
    private global::Google.ProtocolBuffers.TestProtos.TestSparseEnum sparseEnum_ = global::Google.ProtocolBuffers.TestProtos.TestSparseEnum.SPARSE_A;
    public bool HasSparseEnum {
      get { return hasSparseEnum; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestSparseEnum SparseEnum {
      get { return sparseEnum_; }
    }
    
    public override bool IsInitialized {
      get {
        return true;
      }
    }
    
    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _sparseEnumMessageFieldNames;
      if (hasSparseEnum) {
        output.WriteEnum(1, field_names[0], (int) SparseEnum, SparseEnum);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      int size = memoizedSerializedSize;
      if (size != -1) return size;
      
      size = 0;
      if (hasSparseEnum) {
        size += pb::CodedOutputStream.ComputeEnumSize(1, (int) SparseEnum);
      }
      size += UnknownFields.SerializedSize;
      memoizedSerializedSize = size;
      return size;
    }
    public static SparseEnumMessage ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static SparseEnumMessage ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static SparseEnumMessage ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static SparseEnumMessage ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static SparseEnumMessage ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static SparseEnumMessage ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static SparseEnumMessage ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static SparseEnumMessage ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static SparseEnumMessage ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static SparseEnumMessage ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private SparseEnumMessage MakeReadOnly() {
      return this;
    }
    
    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(SparseEnumMessage prototype) {
      return new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<SparseEnumMessage, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(SparseEnumMessage cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private SparseEnumMessage result;
      
      private SparseEnumMessage PrepareBuilder() {
        if (resultIsReadOnly) {
          SparseEnumMessage original = result;
          result = new SparseEnumMessage();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override SparseEnumMessage MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          return new Builder().MergeFrom(result);
        }
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.SparseEnumMessage.Descriptor; }
      }
      
      public override SparseEnumMessage DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.SparseEnumMessage.DefaultInstance; }
      }
      
      public override SparseEnumMessage BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      public override Builder MergeFrom(pb::IMessage other) {
        if (other is SparseEnumMessage) {
          return MergeFrom((SparseEnumMessage) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }
      
      public override Builder MergeFrom(SparseEnumMessage other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.SparseEnumMessage.DefaultInstance) return this;
        PrepareBuilder();
        if (other.HasSparseEnum) {
          SparseEnum = other.SparseEnum;
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_sparseEnumMessageFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _sparseEnumMessageFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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: {
              object unknown;
              if(input.ReadEnum(ref result.sparseEnum_, out unknown)) {
                result.hasSparseEnum = true;
              } else if(unknown is int) {
                if (unknownFields == null) {
                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                }
                unknownFields.MergeVarintField(1, (ulong)(int)unknown);
              }
              break;
            }
          }
        }
        
        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }
      
      
      public bool HasSparseEnum {
       get { return result.hasSparseEnum; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestSparseEnum SparseEnum {
        get { return result.SparseEnum; }
        set { SetSparseEnum(value); }
      }
      public Builder SetSparseEnum(global::Google.ProtocolBuffers.TestProtos.TestSparseEnum value) {
        PrepareBuilder();
        result.hasSparseEnum = true;
        result.sparseEnum_ = value;
        return this;
      }
      public Builder ClearSparseEnum() {
        PrepareBuilder();
        result.hasSparseEnum = false;
        result.sparseEnum_ = global::Google.ProtocolBuffers.TestProtos.TestSparseEnum.SPARSE_A;
        return this;
      }
    }
    static SparseEnumMessage() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class OneString : pb::GeneratedMessage<OneString, OneString.Builder> {
    private OneString() { }
    private static readonly OneString defaultInstance = new OneString().MakeReadOnly();
    private static readonly string[] _oneStringFieldNames = new string[] { "data" };
    private static readonly uint[] _oneStringFieldTags = new uint[] { 10 };
    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) {
      CalcSerializedSize();
      string[] field_names = _oneStringFieldNames;
      if (hasData) {
        output.WriteString(1, field_names[0], Data);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static OneString ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private OneString MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<OneString, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(OneString cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private OneString result;
      
      private OneString PrepareBuilder() {
        if (resultIsReadOnly) {
          OneString original = result;
          result = new OneString();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override OneString MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        if (other.HasData) {
          Data = other.Data;
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_oneStringFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _oneStringFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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");
        PrepareBuilder();
        result.hasData = true;
        result.data_ = value;
        return this;
      }
      public Builder ClearData() {
        PrepareBuilder();
        result.hasData = false;
        result.data_ = "";
        return this;
      }
    }
    static OneString() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class OneBytes : pb::GeneratedMessage<OneBytes, OneBytes.Builder> {
    private OneBytes() { }
    private static readonly OneBytes defaultInstance = new OneBytes().MakeReadOnly();
    private static readonly string[] _oneBytesFieldNames = new string[] { "data" };
    private static readonly uint[] _oneBytesFieldTags = new uint[] { 10 };
    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) {
      CalcSerializedSize();
      string[] field_names = _oneBytesFieldNames;
      if (hasData) {
        output.WriteBytes(1, field_names[0], Data);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static OneBytes ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private OneBytes MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<OneBytes, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(OneBytes cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private OneBytes result;
      
      private OneBytes PrepareBuilder() {
        if (resultIsReadOnly) {
          OneBytes original = result;
          result = new OneBytes();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override OneBytes MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        if (other.HasData) {
          Data = other.Data;
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_oneBytesFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _oneBytesFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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");
        PrepareBuilder();
        result.hasData = true;
        result.data_ = value;
        return this;
      }
      public Builder ClearData() {
        PrepareBuilder();
        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()]
  public sealed partial class TestPackedTypes : pb::GeneratedMessage<TestPackedTypes, TestPackedTypes.Builder> {
    private TestPackedTypes() { }
    private static readonly TestPackedTypes defaultInstance = new TestPackedTypes().MakeReadOnly();
    private static readonly string[] _testPackedTypesFieldNames = new string[] { "packed_bool", "packed_double", "packed_enum", "packed_fixed32", "packed_fixed64", "packed_float", "packed_int32", "packed_int64", "packed_sfixed32", "packed_sfixed64", "packed_sint32", "packed_sint64", "packed_uint32", "packed_uint64" };
    private static readonly uint[] _testPackedTypesFieldTags = new uint[] { 818, 810, 826, 770, 778, 802, 722, 730, 786, 794, 754, 762, 738, 746 };
    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) {
      CalcSerializedSize();
      string[] field_names = _testPackedTypesFieldNames;
      if (packedInt32_.Count > 0) {
        output.WritePackedInt32Array(90, field_names[6], packedInt32MemoizedSerializedSize, packedInt32_);
      }
      if (packedInt64_.Count > 0) {
        output.WritePackedInt64Array(91, field_names[7], packedInt64MemoizedSerializedSize, packedInt64_);
      }
      if (packedUint32_.Count > 0) {
        output.WritePackedUInt32Array(92, field_names[12], packedUint32MemoizedSerializedSize, packedUint32_);
      }
      if (packedUint64_.Count > 0) {
        output.WritePackedUInt64Array(93, field_names[13], packedUint64MemoizedSerializedSize, packedUint64_);
      }
      if (packedSint32_.Count > 0) {
        output.WritePackedSInt32Array(94, field_names[10], packedSint32MemoizedSerializedSize, packedSint32_);
      }
      if (packedSint64_.Count > 0) {
        output.WritePackedSInt64Array(95, field_names[11], packedSint64MemoizedSerializedSize, packedSint64_);
      }
      if (packedFixed32_.Count > 0) {
        output.WritePackedFixed32Array(96, field_names[3], packedFixed32MemoizedSerializedSize, packedFixed32_);
      }
      if (packedFixed64_.Count > 0) {
        output.WritePackedFixed64Array(97, field_names[4], packedFixed64MemoizedSerializedSize, packedFixed64_);
      }
      if (packedSfixed32_.Count > 0) {
        output.WritePackedSFixed32Array(98, field_names[8], packedSfixed32MemoizedSerializedSize, packedSfixed32_);
      }
      if (packedSfixed64_.Count > 0) {
        output.WritePackedSFixed64Array(99, field_names[9], packedSfixed64MemoizedSerializedSize, packedSfixed64_);
      }
      if (packedFloat_.Count > 0) {
        output.WritePackedFloatArray(100, field_names[5], packedFloatMemoizedSerializedSize, packedFloat_);
      }
      if (packedDouble_.Count > 0) {
        output.WritePackedDoubleArray(101, field_names[1], packedDoubleMemoizedSerializedSize, packedDouble_);
      }
      if (packedBool_.Count > 0) {
        output.WritePackedBoolArray(102, field_names[0], packedBoolMemoizedSerializedSize, packedBool_);
      }
      if (packedEnum_.Count > 0) {
        output.WritePackedEnumArray(103, field_names[2], packedEnumMemoizedSerializedSize, packedEnum_);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestPackedTypes ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestPackedTypes MakeReadOnly() {
      packedInt32_.MakeReadOnly();
      packedInt64_.MakeReadOnly();
      packedUint32_.MakeReadOnly();
      packedUint64_.MakeReadOnly();
      packedSint32_.MakeReadOnly();
      packedSint64_.MakeReadOnly();
      packedFixed32_.MakeReadOnly();
      packedFixed64_.MakeReadOnly();
      packedSfixed32_.MakeReadOnly();
      packedSfixed64_.MakeReadOnly();
      packedFloat_.MakeReadOnly();
      packedDouble_.MakeReadOnly();
      packedBool_.MakeReadOnly();
      packedEnum_.MakeReadOnly();
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestPackedTypes, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestPackedTypes cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestPackedTypes result;
      
      private TestPackedTypes PrepareBuilder() {
        if (resultIsReadOnly) {
          TestPackedTypes original = result;
          result = new TestPackedTypes();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestPackedTypes MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        if (other.packedInt32_.Count != 0) {
          result.packedInt32_.Add(other.packedInt32_);
        }
        if (other.packedInt64_.Count != 0) {
          result.packedInt64_.Add(other.packedInt64_);
        }
        if (other.packedUint32_.Count != 0) {
          result.packedUint32_.Add(other.packedUint32_);
        }
        if (other.packedUint64_.Count != 0) {
          result.packedUint64_.Add(other.packedUint64_);
        }
        if (other.packedSint32_.Count != 0) {
          result.packedSint32_.Add(other.packedSint32_);
        }
        if (other.packedSint64_.Count != 0) {
          result.packedSint64_.Add(other.packedSint64_);
        }
        if (other.packedFixed32_.Count != 0) {
          result.packedFixed32_.Add(other.packedFixed32_);
        }
        if (other.packedFixed64_.Count != 0) {
          result.packedFixed64_.Add(other.packedFixed64_);
        }
        if (other.packedSfixed32_.Count != 0) {
          result.packedSfixed32_.Add(other.packedSfixed32_);
        }
        if (other.packedSfixed64_.Count != 0) {
          result.packedSfixed64_.Add(other.packedSfixed64_);
        }
        if (other.packedFloat_.Count != 0) {
          result.packedFloat_.Add(other.packedFloat_);
        }
        if (other.packedDouble_.Count != 0) {
          result.packedDouble_.Add(other.packedDouble_);
        }
        if (other.packedBool_.Count != 0) {
          result.packedBool_.Add(other.packedBool_);
        }
        if (other.packedEnum_.Count != 0) {
          result.packedEnum_.Add(other.packedEnum_);
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testPackedTypesFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testPackedTypesFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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:
            case 720: {
              input.ReadInt32Array(tag, field_name, result.packedInt32_);
              break;
            }
            case 730:
            case 728: {
              input.ReadInt64Array(tag, field_name, result.packedInt64_);
              break;
            }
            case 738:
            case 736: {
              input.ReadUInt32Array(tag, field_name, result.packedUint32_);
              break;
            }
            case 746:
            case 744: {
              input.ReadUInt64Array(tag, field_name, result.packedUint64_);
              break;
            }
            case 754:
            case 752: {
              input.ReadSInt32Array(tag, field_name, result.packedSint32_);
              break;
            }
            case 762:
            case 760: {
              input.ReadSInt64Array(tag, field_name, result.packedSint64_);
              break;
            }
            case 770:
            case 773: {
              input.ReadFixed32Array(tag, field_name, result.packedFixed32_);
              break;
            }
            case 778:
            case 777: {
              input.ReadFixed64Array(tag, field_name, result.packedFixed64_);
              break;
            }
            case 786:
            case 789: {
              input.ReadSFixed32Array(tag, field_name, result.packedSfixed32_);
              break;
            }
            case 794:
            case 793: {
              input.ReadSFixed64Array(tag, field_name, result.packedSfixed64_);
              break;
            }
            case 802:
            case 805: {
              input.ReadFloatArray(tag, field_name, result.packedFloat_);
              break;
            }
            case 810:
            case 809: {
              input.ReadDoubleArray(tag, field_name, result.packedDouble_);
              break;
            }
            case 818:
            case 816: {
              input.ReadBoolArray(tag, field_name, result.packedBool_);
              break;
            }
            case 826:
            case 824: {
              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 PrepareBuilder().packedInt32_; }
      }
      public int PackedInt32Count {
        get { return result.PackedInt32Count; }
      }
      public int GetPackedInt32(int index) {
        return result.GetPackedInt32(index);
      }
      public Builder SetPackedInt32(int index, int value) {
        PrepareBuilder();
        result.packedInt32_[index] = value;
        return this;
      }
      public Builder AddPackedInt32(int value) {
        PrepareBuilder();
        result.packedInt32_.Add(value);
        return this;
      }
      public Builder AddRangePackedInt32(scg::IEnumerable<int> values) {
        PrepareBuilder();
        result.packedInt32_.Add(values);
        return this;
      }
      public Builder ClearPackedInt32() {
        PrepareBuilder();
        result.packedInt32_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<long> PackedInt64List {
        get { return PrepareBuilder().packedInt64_; }
      }
      public int PackedInt64Count {
        get { return result.PackedInt64Count; }
      }
      public long GetPackedInt64(int index) {
        return result.GetPackedInt64(index);
      }
      public Builder SetPackedInt64(int index, long value) {
        PrepareBuilder();
        result.packedInt64_[index] = value;
        return this;
      }
      public Builder AddPackedInt64(long value) {
        PrepareBuilder();
        result.packedInt64_.Add(value);
        return this;
      }
      public Builder AddRangePackedInt64(scg::IEnumerable<long> values) {
        PrepareBuilder();
        result.packedInt64_.Add(values);
        return this;
      }
      public Builder ClearPackedInt64() {
        PrepareBuilder();
        result.packedInt64_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<uint> PackedUint32List {
        get { return PrepareBuilder().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) {
        PrepareBuilder();
        result.packedUint32_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddPackedUint32(uint value) {
        PrepareBuilder();
        result.packedUint32_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangePackedUint32(scg::IEnumerable<uint> values) {
        PrepareBuilder();
        result.packedUint32_.Add(values);
        return this;
      }
      public Builder ClearPackedUint32() {
        PrepareBuilder();
        result.packedUint32_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<ulong> PackedUint64List {
        get { return PrepareBuilder().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) {
        PrepareBuilder();
        result.packedUint64_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddPackedUint64(ulong value) {
        PrepareBuilder();
        result.packedUint64_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangePackedUint64(scg::IEnumerable<ulong> values) {
        PrepareBuilder();
        result.packedUint64_.Add(values);
        return this;
      }
      public Builder ClearPackedUint64() {
        PrepareBuilder();
        result.packedUint64_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<int> PackedSint32List {
        get { return PrepareBuilder().packedSint32_; }
      }
      public int PackedSint32Count {
        get { return result.PackedSint32Count; }
      }
      public int GetPackedSint32(int index) {
        return result.GetPackedSint32(index);
      }
      public Builder SetPackedSint32(int index, int value) {
        PrepareBuilder();
        result.packedSint32_[index] = value;
        return this;
      }
      public Builder AddPackedSint32(int value) {
        PrepareBuilder();
        result.packedSint32_.Add(value);
        return this;
      }
      public Builder AddRangePackedSint32(scg::IEnumerable<int> values) {
        PrepareBuilder();
        result.packedSint32_.Add(values);
        return this;
      }
      public Builder ClearPackedSint32() {
        PrepareBuilder();
        result.packedSint32_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<long> PackedSint64List {
        get { return PrepareBuilder().packedSint64_; }
      }
      public int PackedSint64Count {
        get { return result.PackedSint64Count; }
      }
      public long GetPackedSint64(int index) {
        return result.GetPackedSint64(index);
      }
      public Builder SetPackedSint64(int index, long value) {
        PrepareBuilder();
        result.packedSint64_[index] = value;
        return this;
      }
      public Builder AddPackedSint64(long value) {
        PrepareBuilder();
        result.packedSint64_.Add(value);
        return this;
      }
      public Builder AddRangePackedSint64(scg::IEnumerable<long> values) {
        PrepareBuilder();
        result.packedSint64_.Add(values);
        return this;
      }
      public Builder ClearPackedSint64() {
        PrepareBuilder();
        result.packedSint64_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<uint> PackedFixed32List {
        get { return PrepareBuilder().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) {
        PrepareBuilder();
        result.packedFixed32_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddPackedFixed32(uint value) {
        PrepareBuilder();
        result.packedFixed32_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangePackedFixed32(scg::IEnumerable<uint> values) {
        PrepareBuilder();
        result.packedFixed32_.Add(values);
        return this;
      }
      public Builder ClearPackedFixed32() {
        PrepareBuilder();
        result.packedFixed32_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<ulong> PackedFixed64List {
        get { return PrepareBuilder().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) {
        PrepareBuilder();
        result.packedFixed64_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddPackedFixed64(ulong value) {
        PrepareBuilder();
        result.packedFixed64_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangePackedFixed64(scg::IEnumerable<ulong> values) {
        PrepareBuilder();
        result.packedFixed64_.Add(values);
        return this;
      }
      public Builder ClearPackedFixed64() {
        PrepareBuilder();
        result.packedFixed64_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<int> PackedSfixed32List {
        get { return PrepareBuilder().packedSfixed32_; }
      }
      public int PackedSfixed32Count {
        get { return result.PackedSfixed32Count; }
      }
      public int GetPackedSfixed32(int index) {
        return result.GetPackedSfixed32(index);
      }
      public Builder SetPackedSfixed32(int index, int value) {
        PrepareBuilder();
        result.packedSfixed32_[index] = value;
        return this;
      }
      public Builder AddPackedSfixed32(int value) {
        PrepareBuilder();
        result.packedSfixed32_.Add(value);
        return this;
      }
      public Builder AddRangePackedSfixed32(scg::IEnumerable<int> values) {
        PrepareBuilder();
        result.packedSfixed32_.Add(values);
        return this;
      }
      public Builder ClearPackedSfixed32() {
        PrepareBuilder();
        result.packedSfixed32_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<long> PackedSfixed64List {
        get { return PrepareBuilder().packedSfixed64_; }
      }
      public int PackedSfixed64Count {
        get { return result.PackedSfixed64Count; }
      }
      public long GetPackedSfixed64(int index) {
        return result.GetPackedSfixed64(index);
      }
      public Builder SetPackedSfixed64(int index, long value) {
        PrepareBuilder();
        result.packedSfixed64_[index] = value;
        return this;
      }
      public Builder AddPackedSfixed64(long value) {
        PrepareBuilder();
        result.packedSfixed64_.Add(value);
        return this;
      }
      public Builder AddRangePackedSfixed64(scg::IEnumerable<long> values) {
        PrepareBuilder();
        result.packedSfixed64_.Add(values);
        return this;
      }
      public Builder ClearPackedSfixed64() {
        PrepareBuilder();
        result.packedSfixed64_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<float> PackedFloatList {
        get { return PrepareBuilder().packedFloat_; }
      }
      public int PackedFloatCount {
        get { return result.PackedFloatCount; }
      }
      public float GetPackedFloat(int index) {
        return result.GetPackedFloat(index);
      }
      public Builder SetPackedFloat(int index, float value) {
        PrepareBuilder();
        result.packedFloat_[index] = value;
        return this;
      }
      public Builder AddPackedFloat(float value) {
        PrepareBuilder();
        result.packedFloat_.Add(value);
        return this;
      }
      public Builder AddRangePackedFloat(scg::IEnumerable<float> values) {
        PrepareBuilder();
        result.packedFloat_.Add(values);
        return this;
      }
      public Builder ClearPackedFloat() {
        PrepareBuilder();
        result.packedFloat_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<double> PackedDoubleList {
        get { return PrepareBuilder().packedDouble_; }
      }
      public int PackedDoubleCount {
        get { return result.PackedDoubleCount; }
      }
      public double GetPackedDouble(int index) {
        return result.GetPackedDouble(index);
      }
      public Builder SetPackedDouble(int index, double value) {
        PrepareBuilder();
        result.packedDouble_[index] = value;
        return this;
      }
      public Builder AddPackedDouble(double value) {
        PrepareBuilder();
        result.packedDouble_.Add(value);
        return this;
      }
      public Builder AddRangePackedDouble(scg::IEnumerable<double> values) {
        PrepareBuilder();
        result.packedDouble_.Add(values);
        return this;
      }
      public Builder ClearPackedDouble() {
        PrepareBuilder();
        result.packedDouble_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<bool> PackedBoolList {
        get { return PrepareBuilder().packedBool_; }
      }
      public int PackedBoolCount {
        get { return result.PackedBoolCount; }
      }
      public bool GetPackedBool(int index) {
        return result.GetPackedBool(index);
      }
      public Builder SetPackedBool(int index, bool value) {
        PrepareBuilder();
        result.packedBool_[index] = value;
        return this;
      }
      public Builder AddPackedBool(bool value) {
        PrepareBuilder();
        result.packedBool_.Add(value);
        return this;
      }
      public Builder AddRangePackedBool(scg::IEnumerable<bool> values) {
        PrepareBuilder();
        result.packedBool_.Add(values);
        return this;
      }
      public Builder ClearPackedBool() {
        PrepareBuilder();
        result.packedBool_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> PackedEnumList {
        get { return PrepareBuilder().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) {
        PrepareBuilder();
        result.packedEnum_[index] = value;
        return this;
      }
      public Builder AddPackedEnum(global::Google.ProtocolBuffers.TestProtos.ForeignEnum value) {
        PrepareBuilder();
        result.packedEnum_.Add(value);
        return this;
      }
      public Builder AddRangePackedEnum(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> values) {
        PrepareBuilder();
        result.packedEnum_.Add(values);
        return this;
      }
      public Builder ClearPackedEnum() {
        PrepareBuilder();
        result.packedEnum_.Clear();
        return this;
      }
    }
    static TestPackedTypes() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestUnpackedTypes : pb::GeneratedMessage<TestUnpackedTypes, TestUnpackedTypes.Builder> {
    private TestUnpackedTypes() { }
    private static readonly TestUnpackedTypes defaultInstance = new TestUnpackedTypes().MakeReadOnly();
    private static readonly string[] _testUnpackedTypesFieldNames = new string[] { "unpacked_bool", "unpacked_double", "unpacked_enum", "unpacked_fixed32", "unpacked_fixed64", "unpacked_float", "unpacked_int32", "unpacked_int64", "unpacked_sfixed32", "unpacked_sfixed64", "unpacked_sint32", "unpacked_sint64", "unpacked_uint32", "unpacked_uint64" };
    private static readonly uint[] _testUnpackedTypesFieldTags = new uint[] { 816, 809, 824, 773, 777, 805, 720, 728, 789, 793, 752, 760, 736, 744 };
    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) {
      CalcSerializedSize();
      string[] field_names = _testUnpackedTypesFieldNames;
      if (unpackedInt32_.Count > 0) {
        output.WriteInt32Array(90, field_names[6], unpackedInt32_);
      }
      if (unpackedInt64_.Count > 0) {
        output.WriteInt64Array(91, field_names[7], unpackedInt64_);
      }
      if (unpackedUint32_.Count > 0) {
        output.WriteUInt32Array(92, field_names[12], unpackedUint32_);
      }
      if (unpackedUint64_.Count > 0) {
        output.WriteUInt64Array(93, field_names[13], unpackedUint64_);
      }
      if (unpackedSint32_.Count > 0) {
        output.WriteSInt32Array(94, field_names[10], unpackedSint32_);
      }
      if (unpackedSint64_.Count > 0) {
        output.WriteSInt64Array(95, field_names[11], unpackedSint64_);
      }
      if (unpackedFixed32_.Count > 0) {
        output.WriteFixed32Array(96, field_names[3], unpackedFixed32_);
      }
      if (unpackedFixed64_.Count > 0) {
        output.WriteFixed64Array(97, field_names[4], unpackedFixed64_);
      }
      if (unpackedSfixed32_.Count > 0) {
        output.WriteSFixed32Array(98, field_names[8], unpackedSfixed32_);
      }
      if (unpackedSfixed64_.Count > 0) {
        output.WriteSFixed64Array(99, field_names[9], unpackedSfixed64_);
      }
      if (unpackedFloat_.Count > 0) {
        output.WriteFloatArray(100, field_names[5], unpackedFloat_);
      }
      if (unpackedDouble_.Count > 0) {
        output.WriteDoubleArray(101, field_names[1], unpackedDouble_);
      }
      if (unpackedBool_.Count > 0) {
        output.WriteBoolArray(102, field_names[0], unpackedBool_);
      }
      if (unpackedEnum_.Count > 0) {
        output.WriteEnumArray(103, field_names[2], unpackedEnum_);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestUnpackedTypes ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestUnpackedTypes MakeReadOnly() {
      unpackedInt32_.MakeReadOnly();
      unpackedInt64_.MakeReadOnly();
      unpackedUint32_.MakeReadOnly();
      unpackedUint64_.MakeReadOnly();
      unpackedSint32_.MakeReadOnly();
      unpackedSint64_.MakeReadOnly();
      unpackedFixed32_.MakeReadOnly();
      unpackedFixed64_.MakeReadOnly();
      unpackedSfixed32_.MakeReadOnly();
      unpackedSfixed64_.MakeReadOnly();
      unpackedFloat_.MakeReadOnly();
      unpackedDouble_.MakeReadOnly();
      unpackedBool_.MakeReadOnly();
      unpackedEnum_.MakeReadOnly();
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestUnpackedTypes, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestUnpackedTypes cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestUnpackedTypes result;
      
      private TestUnpackedTypes PrepareBuilder() {
        if (resultIsReadOnly) {
          TestUnpackedTypes original = result;
          result = new TestUnpackedTypes();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestUnpackedTypes MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        if (other.unpackedInt32_.Count != 0) {
          result.unpackedInt32_.Add(other.unpackedInt32_);
        }
        if (other.unpackedInt64_.Count != 0) {
          result.unpackedInt64_.Add(other.unpackedInt64_);
        }
        if (other.unpackedUint32_.Count != 0) {
          result.unpackedUint32_.Add(other.unpackedUint32_);
        }
        if (other.unpackedUint64_.Count != 0) {
          result.unpackedUint64_.Add(other.unpackedUint64_);
        }
        if (other.unpackedSint32_.Count != 0) {
          result.unpackedSint32_.Add(other.unpackedSint32_);
        }
        if (other.unpackedSint64_.Count != 0) {
          result.unpackedSint64_.Add(other.unpackedSint64_);
        }
        if (other.unpackedFixed32_.Count != 0) {
          result.unpackedFixed32_.Add(other.unpackedFixed32_);
        }
        if (other.unpackedFixed64_.Count != 0) {
          result.unpackedFixed64_.Add(other.unpackedFixed64_);
        }
        if (other.unpackedSfixed32_.Count != 0) {
          result.unpackedSfixed32_.Add(other.unpackedSfixed32_);
        }
        if (other.unpackedSfixed64_.Count != 0) {
          result.unpackedSfixed64_.Add(other.unpackedSfixed64_);
        }
        if (other.unpackedFloat_.Count != 0) {
          result.unpackedFloat_.Add(other.unpackedFloat_);
        }
        if (other.unpackedDouble_.Count != 0) {
          result.unpackedDouble_.Add(other.unpackedDouble_);
        }
        if (other.unpackedBool_.Count != 0) {
          result.unpackedBool_.Add(other.unpackedBool_);
        }
        if (other.unpackedEnum_.Count != 0) {
          result.unpackedEnum_.Add(other.unpackedEnum_);
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testUnpackedTypesFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testUnpackedTypesFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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:
            case 720: {
              input.ReadInt32Array(tag, field_name, result.unpackedInt32_);
              break;
            }
            case 730:
            case 728: {
              input.ReadInt64Array(tag, field_name, result.unpackedInt64_);
              break;
            }
            case 738:
            case 736: {
              input.ReadUInt32Array(tag, field_name, result.unpackedUint32_);
              break;
            }
            case 746:
            case 744: {
              input.ReadUInt64Array(tag, field_name, result.unpackedUint64_);
              break;
            }
            case 754:
            case 752: {
              input.ReadSInt32Array(tag, field_name, result.unpackedSint32_);
              break;
            }
            case 762:
            case 760: {
              input.ReadSInt64Array(tag, field_name, result.unpackedSint64_);
              break;
            }
            case 770:
            case 773: {
              input.ReadFixed32Array(tag, field_name, result.unpackedFixed32_);
              break;
            }
            case 778:
            case 777: {
              input.ReadFixed64Array(tag, field_name, result.unpackedFixed64_);
              break;
            }
            case 786:
            case 789: {
              input.ReadSFixed32Array(tag, field_name, result.unpackedSfixed32_);
              break;
            }
            case 794:
            case 793: {
              input.ReadSFixed64Array(tag, field_name, result.unpackedSfixed64_);
              break;
            }
            case 802:
            case 805: {
              input.ReadFloatArray(tag, field_name, result.unpackedFloat_);
              break;
            }
            case 810:
            case 809: {
              input.ReadDoubleArray(tag, field_name, result.unpackedDouble_);
              break;
            }
            case 818:
            case 816: {
              input.ReadBoolArray(tag, field_name, result.unpackedBool_);
              break;
            }
            case 826:
            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 PrepareBuilder().unpackedInt32_; }
      }
      public int UnpackedInt32Count {
        get { return result.UnpackedInt32Count; }
      }
      public int GetUnpackedInt32(int index) {
        return result.GetUnpackedInt32(index);
      }
      public Builder SetUnpackedInt32(int index, int value) {
        PrepareBuilder();
        result.unpackedInt32_[index] = value;
        return this;
      }
      public Builder AddUnpackedInt32(int value) {
        PrepareBuilder();
        result.unpackedInt32_.Add(value);
        return this;
      }
      public Builder AddRangeUnpackedInt32(scg::IEnumerable<int> values) {
        PrepareBuilder();
        result.unpackedInt32_.Add(values);
        return this;
      }
      public Builder ClearUnpackedInt32() {
        PrepareBuilder();
        result.unpackedInt32_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<long> UnpackedInt64List {
        get { return PrepareBuilder().unpackedInt64_; }
      }
      public int UnpackedInt64Count {
        get { return result.UnpackedInt64Count; }
      }
      public long GetUnpackedInt64(int index) {
        return result.GetUnpackedInt64(index);
      }
      public Builder SetUnpackedInt64(int index, long value) {
        PrepareBuilder();
        result.unpackedInt64_[index] = value;
        return this;
      }
      public Builder AddUnpackedInt64(long value) {
        PrepareBuilder();
        result.unpackedInt64_.Add(value);
        return this;
      }
      public Builder AddRangeUnpackedInt64(scg::IEnumerable<long> values) {
        PrepareBuilder();
        result.unpackedInt64_.Add(values);
        return this;
      }
      public Builder ClearUnpackedInt64() {
        PrepareBuilder();
        result.unpackedInt64_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<uint> UnpackedUint32List {
        get { return PrepareBuilder().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) {
        PrepareBuilder();
        result.unpackedUint32_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddUnpackedUint32(uint value) {
        PrepareBuilder();
        result.unpackedUint32_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangeUnpackedUint32(scg::IEnumerable<uint> values) {
        PrepareBuilder();
        result.unpackedUint32_.Add(values);
        return this;
      }
      public Builder ClearUnpackedUint32() {
        PrepareBuilder();
        result.unpackedUint32_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<ulong> UnpackedUint64List {
        get { return PrepareBuilder().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) {
        PrepareBuilder();
        result.unpackedUint64_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddUnpackedUint64(ulong value) {
        PrepareBuilder();
        result.unpackedUint64_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangeUnpackedUint64(scg::IEnumerable<ulong> values) {
        PrepareBuilder();
        result.unpackedUint64_.Add(values);
        return this;
      }
      public Builder ClearUnpackedUint64() {
        PrepareBuilder();
        result.unpackedUint64_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<int> UnpackedSint32List {
        get { return PrepareBuilder().unpackedSint32_; }
      }
      public int UnpackedSint32Count {
        get { return result.UnpackedSint32Count; }
      }
      public int GetUnpackedSint32(int index) {
        return result.GetUnpackedSint32(index);
      }
      public Builder SetUnpackedSint32(int index, int value) {
        PrepareBuilder();
        result.unpackedSint32_[index] = value;
        return this;
      }
      public Builder AddUnpackedSint32(int value) {
        PrepareBuilder();
        result.unpackedSint32_.Add(value);
        return this;
      }
      public Builder AddRangeUnpackedSint32(scg::IEnumerable<int> values) {
        PrepareBuilder();
        result.unpackedSint32_.Add(values);
        return this;
      }
      public Builder ClearUnpackedSint32() {
        PrepareBuilder();
        result.unpackedSint32_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<long> UnpackedSint64List {
        get { return PrepareBuilder().unpackedSint64_; }
      }
      public int UnpackedSint64Count {
        get { return result.UnpackedSint64Count; }
      }
      public long GetUnpackedSint64(int index) {
        return result.GetUnpackedSint64(index);
      }
      public Builder SetUnpackedSint64(int index, long value) {
        PrepareBuilder();
        result.unpackedSint64_[index] = value;
        return this;
      }
      public Builder AddUnpackedSint64(long value) {
        PrepareBuilder();
        result.unpackedSint64_.Add(value);
        return this;
      }
      public Builder AddRangeUnpackedSint64(scg::IEnumerable<long> values) {
        PrepareBuilder();
        result.unpackedSint64_.Add(values);
        return this;
      }
      public Builder ClearUnpackedSint64() {
        PrepareBuilder();
        result.unpackedSint64_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<uint> UnpackedFixed32List {
        get { return PrepareBuilder().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) {
        PrepareBuilder();
        result.unpackedFixed32_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddUnpackedFixed32(uint value) {
        PrepareBuilder();
        result.unpackedFixed32_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangeUnpackedFixed32(scg::IEnumerable<uint> values) {
        PrepareBuilder();
        result.unpackedFixed32_.Add(values);
        return this;
      }
      public Builder ClearUnpackedFixed32() {
        PrepareBuilder();
        result.unpackedFixed32_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<ulong> UnpackedFixed64List {
        get { return PrepareBuilder().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) {
        PrepareBuilder();
        result.unpackedFixed64_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddUnpackedFixed64(ulong value) {
        PrepareBuilder();
        result.unpackedFixed64_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangeUnpackedFixed64(scg::IEnumerable<ulong> values) {
        PrepareBuilder();
        result.unpackedFixed64_.Add(values);
        return this;
      }
      public Builder ClearUnpackedFixed64() {
        PrepareBuilder();
        result.unpackedFixed64_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<int> UnpackedSfixed32List {
        get { return PrepareBuilder().unpackedSfixed32_; }
      }
      public int UnpackedSfixed32Count {
        get { return result.UnpackedSfixed32Count; }
      }
      public int GetUnpackedSfixed32(int index) {
        return result.GetUnpackedSfixed32(index);
      }
      public Builder SetUnpackedSfixed32(int index, int value) {
        PrepareBuilder();
        result.unpackedSfixed32_[index] = value;
        return this;
      }
      public Builder AddUnpackedSfixed32(int value) {
        PrepareBuilder();
        result.unpackedSfixed32_.Add(value);
        return this;
      }
      public Builder AddRangeUnpackedSfixed32(scg::IEnumerable<int> values) {
        PrepareBuilder();
        result.unpackedSfixed32_.Add(values);
        return this;
      }
      public Builder ClearUnpackedSfixed32() {
        PrepareBuilder();
        result.unpackedSfixed32_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<long> UnpackedSfixed64List {
        get { return PrepareBuilder().unpackedSfixed64_; }
      }
      public int UnpackedSfixed64Count {
        get { return result.UnpackedSfixed64Count; }
      }
      public long GetUnpackedSfixed64(int index) {
        return result.GetUnpackedSfixed64(index);
      }
      public Builder SetUnpackedSfixed64(int index, long value) {
        PrepareBuilder();
        result.unpackedSfixed64_[index] = value;
        return this;
      }
      public Builder AddUnpackedSfixed64(long value) {
        PrepareBuilder();
        result.unpackedSfixed64_.Add(value);
        return this;
      }
      public Builder AddRangeUnpackedSfixed64(scg::IEnumerable<long> values) {
        PrepareBuilder();
        result.unpackedSfixed64_.Add(values);
        return this;
      }
      public Builder ClearUnpackedSfixed64() {
        PrepareBuilder();
        result.unpackedSfixed64_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<float> UnpackedFloatList {
        get { return PrepareBuilder().unpackedFloat_; }
      }
      public int UnpackedFloatCount {
        get { return result.UnpackedFloatCount; }
      }
      public float GetUnpackedFloat(int index) {
        return result.GetUnpackedFloat(index);
      }
      public Builder SetUnpackedFloat(int index, float value) {
        PrepareBuilder();
        result.unpackedFloat_[index] = value;
        return this;
      }
      public Builder AddUnpackedFloat(float value) {
        PrepareBuilder();
        result.unpackedFloat_.Add(value);
        return this;
      }
      public Builder AddRangeUnpackedFloat(scg::IEnumerable<float> values) {
        PrepareBuilder();
        result.unpackedFloat_.Add(values);
        return this;
      }
      public Builder ClearUnpackedFloat() {
        PrepareBuilder();
        result.unpackedFloat_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<double> UnpackedDoubleList {
        get { return PrepareBuilder().unpackedDouble_; }
      }
      public int UnpackedDoubleCount {
        get { return result.UnpackedDoubleCount; }
      }
      public double GetUnpackedDouble(int index) {
        return result.GetUnpackedDouble(index);
      }
      public Builder SetUnpackedDouble(int index, double value) {
        PrepareBuilder();
        result.unpackedDouble_[index] = value;
        return this;
      }
      public Builder AddUnpackedDouble(double value) {
        PrepareBuilder();
        result.unpackedDouble_.Add(value);
        return this;
      }
      public Builder AddRangeUnpackedDouble(scg::IEnumerable<double> values) {
        PrepareBuilder();
        result.unpackedDouble_.Add(values);
        return this;
      }
      public Builder ClearUnpackedDouble() {
        PrepareBuilder();
        result.unpackedDouble_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<bool> UnpackedBoolList {
        get { return PrepareBuilder().unpackedBool_; }
      }
      public int UnpackedBoolCount {
        get { return result.UnpackedBoolCount; }
      }
      public bool GetUnpackedBool(int index) {
        return result.GetUnpackedBool(index);
      }
      public Builder SetUnpackedBool(int index, bool value) {
        PrepareBuilder();
        result.unpackedBool_[index] = value;
        return this;
      }
      public Builder AddUnpackedBool(bool value) {
        PrepareBuilder();
        result.unpackedBool_.Add(value);
        return this;
      }
      public Builder AddRangeUnpackedBool(scg::IEnumerable<bool> values) {
        PrepareBuilder();
        result.unpackedBool_.Add(values);
        return this;
      }
      public Builder ClearUnpackedBool() {
        PrepareBuilder();
        result.unpackedBool_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> UnpackedEnumList {
        get { return PrepareBuilder().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) {
        PrepareBuilder();
        result.unpackedEnum_[index] = value;
        return this;
      }
      public Builder AddUnpackedEnum(global::Google.ProtocolBuffers.TestProtos.ForeignEnum value) {
        PrepareBuilder();
        result.unpackedEnum_.Add(value);
        return this;
      }
      public Builder AddRangeUnpackedEnum(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.ForeignEnum> values) {
        PrepareBuilder();
        result.unpackedEnum_.Add(values);
        return this;
      }
      public Builder ClearUnpackedEnum() {
        PrepareBuilder();
        result.unpackedEnum_.Clear();
        return this;
      }
    }
    static TestUnpackedTypes() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestPackedExtensions : pb::ExtendableMessage<TestPackedExtensions, TestPackedExtensions.Builder> {
    private TestPackedExtensions() { }
    private static readonly TestPackedExtensions defaultInstance = new TestPackedExtensions().MakeReadOnly();
    private static readonly string[] _testPackedExtensionsFieldNames = new string[] {  };
    private static readonly uint[] _testPackedExtensionsFieldTags = new uint[] {  };
    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) {
      CalcSerializedSize();
      string[] field_names = _testPackedExtensionsFieldNames;
      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;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestPackedExtensions ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestPackedExtensions MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::ExtendableBuilder<TestPackedExtensions, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestPackedExtensions cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestPackedExtensions result;
      
      private TestPackedExtensions PrepareBuilder() {
        if (resultIsReadOnly) {
          TestPackedExtensions original = result;
          result = new TestPackedExtensions();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestPackedExtensions MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
          this.MergeExtensionFields(other);
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testPackedExtensionsFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testPackedExtensionsFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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()]
  public sealed partial class TestDynamicExtensions : pb::GeneratedMessage<TestDynamicExtensions, TestDynamicExtensions.Builder> {
    private TestDynamicExtensions() { }
    private static readonly TestDynamicExtensions defaultInstance = new TestDynamicExtensions().MakeReadOnly();
    private static readonly string[] _testDynamicExtensionsFieldNames = new string[] { "dynamic_enum_extension", "dynamic_message_extension", "enum_extension", "message_extension", "packed_extension", "repeated_extension", "scalar_extension" };
    private static readonly uint[] _testDynamicExtensionsFieldTags = new uint[] { 16016, 16034, 16008, 16026, 16050, 16042, 16005 };
    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()]
    public static partial class Types {
      public enum DynamicEnumType {
        DYNAMIC_FOO = 2200,
        DYNAMIC_BAR = 2201,
        DYNAMIC_BAZ = 2202,
      }
      
      [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
      public sealed partial class DynamicMessageType : pb::GeneratedMessage<DynamicMessageType, DynamicMessageType.Builder> {
        private DynamicMessageType() { }
        private static readonly DynamicMessageType defaultInstance = new DynamicMessageType().MakeReadOnly();
        private static readonly string[] _dynamicMessageTypeFieldNames = new string[] { "dynamic_field" };
        private static readonly uint[] _dynamicMessageTypeFieldTags = new uint[] { 16800 };
        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_;
        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) {
          CalcSerializedSize();
          string[] field_names = _dynamicMessageTypeFieldNames;
          if (hasDynamicField) {
            output.WriteInt32(2100, field_names[0], DynamicField);
          }
          UnknownFields.WriteTo(output);
        }
        
        private int memoizedSerializedSize = -1;
        public override int SerializedSize {
          get {
            int size = memoizedSerializedSize;
            if (size != -1) return size;
            return CalcSerializedSize();
          }
        }
        
        private int CalcSerializedSize() {
          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::ICodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static DynamicMessageType ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        private DynamicMessageType MakeReadOnly() {
          return this;
        }
        
        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 new Builder(prototype);
        }
        
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public sealed partial class Builder : pb::GeneratedBuilder<DynamicMessageType, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {
            result = DefaultInstance;
            resultIsReadOnly = true;
          }
          internal Builder(DynamicMessageType cloneFrom) {
            result = cloneFrom;
            resultIsReadOnly = true;
          }
          
          private bool resultIsReadOnly;
          private DynamicMessageType result;
          
          private DynamicMessageType PrepareBuilder() {
            if (resultIsReadOnly) {
              DynamicMessageType original = result;
              result = new DynamicMessageType();
              resultIsReadOnly = false;
              MergeFrom(original);
            }
            return result;
          }
          
          public override bool IsInitialized {
            get { return result.IsInitialized; }
          }
          
          protected override DynamicMessageType MessageBeingBuilt {
            get { return PrepareBuilder(); }
          }
          
          public override Builder Clear() {
            result = DefaultInstance;
            resultIsReadOnly = true;
            return this;
          }
          
          public override Builder Clone() {
            if (resultIsReadOnly) {
              return new Builder(result);
            } else {
              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 (resultIsReadOnly) {
              return result;
            }
            resultIsReadOnly = true;
            return result.MakeReadOnly();
          }
          
          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;
            PrepareBuilder();
            if (other.HasDynamicField) {
              DynamicField = other.DynamicField;
            }
            this.MergeUnknownFields(other.UnknownFields);
            return this;
          }
          
          public override Builder MergeFrom(pb::ICodedInputStream input) {
            return MergeFrom(input, pb::ExtensionRegistry.Empty);
          }
          
          public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
            PrepareBuilder();
            pb::UnknownFieldSet.Builder unknownFields = null;
            uint tag;
            string field_name;
            while (input.ReadTag(out tag, out field_name)) {
              if(tag == 0 && field_name != null) {
                int field_ordinal = global::System.Array.BinarySearch(_dynamicMessageTypeFieldNames, field_name, global::System.StringComparer.Ordinal);
                if(field_ordinal >= 0)
                  tag = _dynamicMessageTypeFieldTags[field_ordinal];
                else {
                  if (unknownFields == null) {
                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                  }
                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
                  continue;
                }
              }
              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) {
            PrepareBuilder();
            result.hasDynamicField = true;
            result.dynamicField_ = value;
            return this;
          }
          public Builder ClearDynamicField() {
            PrepareBuilder();
            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_;
    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_;
    public bool HasMessageExtension {
      get { return hasMessageExtension; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ForeignMessage MessageExtension {
      get { return messageExtension_ ?? global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance; }
    }
    
    public const int DynamicMessageExtensionFieldNumber = 2004;
    private bool hasDynamicMessageExtension;
    private global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicMessageType dynamicMessageExtension_;
    public bool HasDynamicMessageExtension {
      get { return hasDynamicMessageExtension; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicMessageType DynamicMessageExtension {
      get { return dynamicMessageExtension_ ?? global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicMessageType.DefaultInstance; }
    }
    
    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) {
      CalcSerializedSize();
      string[] field_names = _testDynamicExtensionsFieldNames;
      if (hasScalarExtension) {
        output.WriteFixed32(2000, field_names[6], ScalarExtension);
      }
      if (hasEnumExtension) {
        output.WriteEnum(2001, field_names[2], (int) EnumExtension, EnumExtension);
      }
      if (hasDynamicEnumExtension) {
        output.WriteEnum(2002, field_names[0], (int) DynamicEnumExtension, DynamicEnumExtension);
      }
      if (hasMessageExtension) {
        output.WriteMessage(2003, field_names[3], MessageExtension);
      }
      if (hasDynamicMessageExtension) {
        output.WriteMessage(2004, field_names[1], DynamicMessageExtension);
      }
      if (repeatedExtension_.Count > 0) {
        output.WriteStringArray(2005, field_names[5], repeatedExtension_);
      }
      if (packedExtension_.Count > 0) {
        output.WritePackedSInt32Array(2006, field_names[4], packedExtensionMemoizedSerializedSize, packedExtension_);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestDynamicExtensions ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestDynamicExtensions MakeReadOnly() {
      repeatedExtension_.MakeReadOnly();
      packedExtension_.MakeReadOnly();
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestDynamicExtensions, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestDynamicExtensions cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestDynamicExtensions result;
      
      private TestDynamicExtensions PrepareBuilder() {
        if (resultIsReadOnly) {
          TestDynamicExtensions original = result;
          result = new TestDynamicExtensions();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestDynamicExtensions MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        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) {
          result.repeatedExtension_.Add(other.repeatedExtension_);
        }
        if (other.packedExtension_.Count != 0) {
          result.packedExtension_.Add(other.packedExtension_);
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testDynamicExtensionsFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testDynamicExtensionsFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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 (result.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 (result.hasDynamicMessageExtension) {
                subBuilder.MergeFrom(DynamicMessageExtension);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              DynamicMessageExtension = subBuilder.BuildPartial();
              break;
            }
            case 16042: {
              input.ReadStringArray(tag, field_name, result.repeatedExtension_);
              break;
            }
            case 16050:
            case 16048: {
              input.ReadSInt32Array(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) {
        PrepareBuilder();
        result.hasScalarExtension = true;
        result.scalarExtension_ = value;
        return this;
      }
      public Builder ClearScalarExtension() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasEnumExtension = true;
        result.enumExtension_ = value;
        return this;
      }
      public Builder ClearEnumExtension() {
        PrepareBuilder();
        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) {
        PrepareBuilder();
        result.hasDynamicEnumExtension = true;
        result.dynamicEnumExtension_ = value;
        return this;
      }
      public Builder ClearDynamicEnumExtension() {
        PrepareBuilder();
        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");
        PrepareBuilder();
        result.hasMessageExtension = true;
        result.messageExtension_ = value;
        return this;
      }
      public Builder SetMessageExtension(global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasMessageExtension = true;
        result.messageExtension_ = builderForValue.Build();
        return this;
      }
      public Builder MergeMessageExtension(global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        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() {
        PrepareBuilder();
        result.hasMessageExtension = false;
        result.messageExtension_ = null;
        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");
        PrepareBuilder();
        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");
        PrepareBuilder();
        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");
        PrepareBuilder();
        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() {
        PrepareBuilder();
        result.hasDynamicMessageExtension = false;
        result.dynamicMessageExtension_ = null;
        return this;
      }
      
      public pbc::IPopsicleList<string> RepeatedExtensionList {
        get { return PrepareBuilder().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");
        PrepareBuilder();
        result.repeatedExtension_[index] = value;
        return this;
      }
      public Builder AddRepeatedExtension(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.repeatedExtension_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedExtension(scg::IEnumerable<string> values) {
        PrepareBuilder();
        result.repeatedExtension_.Add(values);
        return this;
      }
      public Builder ClearRepeatedExtension() {
        PrepareBuilder();
        result.repeatedExtension_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<int> PackedExtensionList {
        get { return PrepareBuilder().packedExtension_; }
      }
      public int PackedExtensionCount {
        get { return result.PackedExtensionCount; }
      }
      public int GetPackedExtension(int index) {
        return result.GetPackedExtension(index);
      }
      public Builder SetPackedExtension(int index, int value) {
        PrepareBuilder();
        result.packedExtension_[index] = value;
        return this;
      }
      public Builder AddPackedExtension(int value) {
        PrepareBuilder();
        result.packedExtension_.Add(value);
        return this;
      }
      public Builder AddRangePackedExtension(scg::IEnumerable<int> values) {
        PrepareBuilder();
        result.packedExtension_.Add(values);
        return this;
      }
      public Builder ClearPackedExtension() {
        PrepareBuilder();
        result.packedExtension_.Clear();
        return this;
      }
    }
    static TestDynamicExtensions() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestRepeatedScalarDifferentTagSizes : pb::GeneratedMessage<TestRepeatedScalarDifferentTagSizes, TestRepeatedScalarDifferentTagSizes.Builder> {
    private TestRepeatedScalarDifferentTagSizes() { }
    private static readonly TestRepeatedScalarDifferentTagSizes defaultInstance = new TestRepeatedScalarDifferentTagSizes().MakeReadOnly();
    private static readonly string[] _testRepeatedScalarDifferentTagSizesFieldNames = new string[] { "repeated_fixed32", "repeated_fixed64", "repeated_float", "repeated_int32", "repeated_int64", "repeated_uint64" };
    private static readonly uint[] _testRepeatedScalarDifferentTagSizesFieldTags = new uint[] { 101, 16369, 2097141, 104, 16376, 2097144 };
    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) {
      CalcSerializedSize();
      string[] field_names = _testRepeatedScalarDifferentTagSizesFieldNames;
      if (repeatedFixed32_.Count > 0) {
        output.WriteFixed32Array(12, field_names[0], repeatedFixed32_);
      }
      if (repeatedInt32_.Count > 0) {
        output.WriteInt32Array(13, field_names[3], repeatedInt32_);
      }
      if (repeatedFixed64_.Count > 0) {
        output.WriteFixed64Array(2046, field_names[1], repeatedFixed64_);
      }
      if (repeatedInt64_.Count > 0) {
        output.WriteInt64Array(2047, field_names[4], repeatedInt64_);
      }
      if (repeatedFloat_.Count > 0) {
        output.WriteFloatArray(262142, field_names[2], repeatedFloat_);
      }
      if (repeatedUint64_.Count > 0) {
        output.WriteUInt64Array(262143, field_names[5], repeatedUint64_);
      }
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestRepeatedScalarDifferentTagSizes ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestRepeatedScalarDifferentTagSizes MakeReadOnly() {
      repeatedFixed32_.MakeReadOnly();
      repeatedInt32_.MakeReadOnly();
      repeatedFixed64_.MakeReadOnly();
      repeatedInt64_.MakeReadOnly();
      repeatedFloat_.MakeReadOnly();
      repeatedUint64_.MakeReadOnly();
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestRepeatedScalarDifferentTagSizes, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestRepeatedScalarDifferentTagSizes cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestRepeatedScalarDifferentTagSizes result;
      
      private TestRepeatedScalarDifferentTagSizes PrepareBuilder() {
        if (resultIsReadOnly) {
          TestRepeatedScalarDifferentTagSizes original = result;
          result = new TestRepeatedScalarDifferentTagSizes();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestRepeatedScalarDifferentTagSizes MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        if (other.repeatedFixed32_.Count != 0) {
          result.repeatedFixed32_.Add(other.repeatedFixed32_);
        }
        if (other.repeatedInt32_.Count != 0) {
          result.repeatedInt32_.Add(other.repeatedInt32_);
        }
        if (other.repeatedFixed64_.Count != 0) {
          result.repeatedFixed64_.Add(other.repeatedFixed64_);
        }
        if (other.repeatedInt64_.Count != 0) {
          result.repeatedInt64_.Add(other.repeatedInt64_);
        }
        if (other.repeatedFloat_.Count != 0) {
          result.repeatedFloat_.Add(other.repeatedFloat_);
        }
        if (other.repeatedUint64_.Count != 0) {
          result.repeatedUint64_.Add(other.repeatedUint64_);
        }
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_testRepeatedScalarDifferentTagSizesFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testRepeatedScalarDifferentTagSizesFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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 98:
            case 101: {
              input.ReadFixed32Array(tag, field_name, result.repeatedFixed32_);
              break;
            }
            case 106:
            case 104: {
              input.ReadInt32Array(tag, field_name, result.repeatedInt32_);
              break;
            }
            case 16370:
            case 16369: {
              input.ReadFixed64Array(tag, field_name, result.repeatedFixed64_);
              break;
            }
            case 16378:
            case 16376: {
              input.ReadInt64Array(tag, field_name, result.repeatedInt64_);
              break;
            }
            case 2097138:
            case 2097141: {
              input.ReadFloatArray(tag, field_name, result.repeatedFloat_);
              break;
            }
            case 2097146:
            case 2097144: {
              input.ReadUInt64Array(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 PrepareBuilder().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) {
        PrepareBuilder();
        result.repeatedFixed32_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRepeatedFixed32(uint value) {
        PrepareBuilder();
        result.repeatedFixed32_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangeRepeatedFixed32(scg::IEnumerable<uint> values) {
        PrepareBuilder();
        result.repeatedFixed32_.Add(values);
        return this;
      }
      public Builder ClearRepeatedFixed32() {
        PrepareBuilder();
        result.repeatedFixed32_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<int> RepeatedInt32List {
        get { return PrepareBuilder().repeatedInt32_; }
      }
      public int RepeatedInt32Count {
        get { return result.RepeatedInt32Count; }
      }
      public int GetRepeatedInt32(int index) {
        return result.GetRepeatedInt32(index);
      }
      public Builder SetRepeatedInt32(int index, int value) {
        PrepareBuilder();
        result.repeatedInt32_[index] = value;
        return this;
      }
      public Builder AddRepeatedInt32(int value) {
        PrepareBuilder();
        result.repeatedInt32_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedInt32(scg::IEnumerable<int> values) {
        PrepareBuilder();
        result.repeatedInt32_.Add(values);
        return this;
      }
      public Builder ClearRepeatedInt32() {
        PrepareBuilder();
        result.repeatedInt32_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<ulong> RepeatedFixed64List {
        get { return PrepareBuilder().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) {
        PrepareBuilder();
        result.repeatedFixed64_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRepeatedFixed64(ulong value) {
        PrepareBuilder();
        result.repeatedFixed64_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangeRepeatedFixed64(scg::IEnumerable<ulong> values) {
        PrepareBuilder();
        result.repeatedFixed64_.Add(values);
        return this;
      }
      public Builder ClearRepeatedFixed64() {
        PrepareBuilder();
        result.repeatedFixed64_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<long> RepeatedInt64List {
        get { return PrepareBuilder().repeatedInt64_; }
      }
      public int RepeatedInt64Count {
        get { return result.RepeatedInt64Count; }
      }
      public long GetRepeatedInt64(int index) {
        return result.GetRepeatedInt64(index);
      }
      public Builder SetRepeatedInt64(int index, long value) {
        PrepareBuilder();
        result.repeatedInt64_[index] = value;
        return this;
      }
      public Builder AddRepeatedInt64(long value) {
        PrepareBuilder();
        result.repeatedInt64_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedInt64(scg::IEnumerable<long> values) {
        PrepareBuilder();
        result.repeatedInt64_.Add(values);
        return this;
      }
      public Builder ClearRepeatedInt64() {
        PrepareBuilder();
        result.repeatedInt64_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<float> RepeatedFloatList {
        get { return PrepareBuilder().repeatedFloat_; }
      }
      public int RepeatedFloatCount {
        get { return result.RepeatedFloatCount; }
      }
      public float GetRepeatedFloat(int index) {
        return result.GetRepeatedFloat(index);
      }
      public Builder SetRepeatedFloat(int index, float value) {
        PrepareBuilder();
        result.repeatedFloat_[index] = value;
        return this;
      }
      public Builder AddRepeatedFloat(float value) {
        PrepareBuilder();
        result.repeatedFloat_.Add(value);
        return this;
      }
      public Builder AddRangeRepeatedFloat(scg::IEnumerable<float> values) {
        PrepareBuilder();
        result.repeatedFloat_.Add(values);
        return this;
      }
      public Builder ClearRepeatedFloat() {
        PrepareBuilder();
        result.repeatedFloat_.Clear();
        return this;
      }
      
      [global::System.CLSCompliant(false)]
      public pbc::IPopsicleList<ulong> RepeatedUint64List {
        get { return PrepareBuilder().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) {
        PrepareBuilder();
        result.repeatedUint64_[index] = value;
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRepeatedUint64(ulong value) {
        PrepareBuilder();
        result.repeatedUint64_.Add(value);
        return this;
      }
      [global::System.CLSCompliant(false)]
      public Builder AddRangeRepeatedUint64(scg::IEnumerable<ulong> values) {
        PrepareBuilder();
        result.repeatedUint64_.Add(values);
        return this;
      }
      public Builder ClearRepeatedUint64() {
        PrepareBuilder();
        result.repeatedUint64_.Clear();
        return this;
      }
    }
    static TestRepeatedScalarDifferentTagSizes() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class FooRequest : pb::GeneratedMessage<FooRequest, FooRequest.Builder> {
    private FooRequest() { }
    private static readonly FooRequest defaultInstance = new FooRequest().MakeReadOnly();
    private static readonly string[] _fooRequestFieldNames = new string[] {  };
    private static readonly uint[] _fooRequestFieldTags = new uint[] {  };
    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) {
      CalcSerializedSize();
      string[] field_names = _fooRequestFieldNames;
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static FooRequest ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private FooRequest MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<FooRequest, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(FooRequest cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private FooRequest result;
      
      private FooRequest PrepareBuilder() {
        if (resultIsReadOnly) {
          FooRequest original = result;
          result = new FooRequest();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override FooRequest MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_fooRequestFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _fooRequestFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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()]
  public sealed partial class FooResponse : pb::GeneratedMessage<FooResponse, FooResponse.Builder> {
    private FooResponse() { }
    private static readonly FooResponse defaultInstance = new FooResponse().MakeReadOnly();
    private static readonly string[] _fooResponseFieldNames = new string[] {  };
    private static readonly uint[] _fooResponseFieldTags = new uint[] {  };
    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) {
      CalcSerializedSize();
      string[] field_names = _fooResponseFieldNames;
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static FooResponse ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private FooResponse MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<FooResponse, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(FooResponse cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private FooResponse result;
      
      private FooResponse PrepareBuilder() {
        if (resultIsReadOnly) {
          FooResponse original = result;
          result = new FooResponse();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override FooResponse MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_fooResponseFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _fooResponseFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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()]
  public sealed partial class BarRequest : pb::GeneratedMessage<BarRequest, BarRequest.Builder> {
    private BarRequest() { }
    private static readonly BarRequest defaultInstance = new BarRequest().MakeReadOnly();
    private static readonly string[] _barRequestFieldNames = new string[] {  };
    private static readonly uint[] _barRequestFieldTags = new uint[] {  };
    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) {
      CalcSerializedSize();
      string[] field_names = _barRequestFieldNames;
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static BarRequest ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private BarRequest MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<BarRequest, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(BarRequest cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private BarRequest result;
      
      private BarRequest PrepareBuilder() {
        if (resultIsReadOnly) {
          BarRequest original = result;
          result = new BarRequest();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override BarRequest MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_barRequestFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _barRequestFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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()]
  public sealed partial class BarResponse : pb::GeneratedMessage<BarResponse, BarResponse.Builder> {
    private BarResponse() { }
    private static readonly BarResponse defaultInstance = new BarResponse().MakeReadOnly();
    private static readonly string[] _barResponseFieldNames = new string[] {  };
    private static readonly uint[] _barResponseFieldTags = new uint[] {  };
    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) {
      CalcSerializedSize();
      string[] field_names = _barResponseFieldNames;
      UnknownFields.WriteTo(output);
    }
    
    private int memoizedSerializedSize = -1;
    public override int SerializedSize {
      get {
        int size = memoizedSerializedSize;
        if (size != -1) return size;
        return CalcSerializedSize();
      }
    }
    
    private int CalcSerializedSize() {
      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::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static BarResponse ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private BarResponse MakeReadOnly() {
      return this;
    }
    
    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 new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<BarResponse, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(BarResponse cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private BarResponse result;
      
      private BarResponse PrepareBuilder() {
        if (resultIsReadOnly) {
          BarResponse original = result;
          result = new BarResponse();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override BarResponse MessageBeingBuilt {
        get { return PrepareBuilder(); }
      }
      
      public override Builder Clear() {
        result = DefaultInstance;
        resultIsReadOnly = true;
        return this;
      }
      
      public override Builder Clone() {
        if (resultIsReadOnly) {
          return new Builder(result);
        } else {
          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 (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      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;
        PrepareBuilder();
        this.MergeUnknownFields(other.UnknownFields);
        return this;
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input) {
        return MergeFrom(input, pb::ExtensionRegistry.Empty);
      }
      
      public override Builder MergeFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
        PrepareBuilder();
        pb::UnknownFieldSet.Builder unknownFields = null;
        uint tag;
        string field_name;
        while (input.ReadTag(out tag, out field_name)) {
          if(tag == 0 && field_name != null) {
            int field_ordinal = global::System.Array.BinarySearch(_barResponseFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _barResponseFieldTags[field_ordinal];
            else {
              if (unknownFields == null) {
                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
              }
              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
              continue;
            }
          }
          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
  
}

#endregion Designer generated code
