// Manual changes:
// - Search and replace of RepeatedFieldsGenerator.Group to RepeatedFieldsGenerator.Types.Group
//
// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: google/protobuf/unittest.proto
#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 Unittest {

    #region Extension registration
    public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalInt32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalInt64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalUint32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalUint64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalSint32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalSint64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalFixed32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalFixed64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalSfixed32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalSfixed64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalFloatExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalDoubleExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalBoolExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalStringExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalBytesExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalGroupExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalNestedMessageExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalForeignMessageExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalImportMessageExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalNestedEnumExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalForeignEnumExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalImportEnumExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalStringPieceExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalCordExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalPublicImportMessageExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalLazyMessageExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedInt32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedInt64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedUint32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedUint64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedSint32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedSint64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedFixed32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedFixed64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedSfixed32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedSfixed64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedFloatExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedDoubleExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedBoolExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedStringExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedBytesExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedGroupExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedNestedMessageExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedForeignMessageExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedImportMessageExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedNestedEnumExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedForeignEnumExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedImportEnumExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedStringPieceExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedCordExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedLazyMessageExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultInt32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultInt64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultUint32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultUint64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultSint32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultSint64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultFixed32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultFixed64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultSfixed32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultSfixed64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultFloatExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultDoubleExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultBoolExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultStringExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultBytesExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultNestedEnumExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultForeignEnumExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultImportEnumExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultStringPieceExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultCordExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OneofUint32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OneofNestedMessageExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OneofStringExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.OneofBytesExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.MyExtensionString);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.MyExtensionInt);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.PackedInt32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.PackedInt64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.PackedUint32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.PackedUint64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.PackedSint32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.PackedSint64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.PackedFixed32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.PackedFixed64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.PackedSfixed32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.PackedSfixed64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.PackedFloatExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.PackedDoubleExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.PackedBoolExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.PackedEnumExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedInt32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedInt64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedUint32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedUint64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedSint32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedSint64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedFixed32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedFixed64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedSfixed32Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedSfixed64Extension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedFloatExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedDoubleExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedBoolExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedEnumExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.TestNestedExtension.Test);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.TestNestedExtension.NestedStringExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.TestRequired.Single);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.TestRequired.Multi);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.OptionalExt);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.RepeatedExt);
    }
    #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 OptionalPublicImportMessageExtensionFieldNumber = 26;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.PublicImportMessage> OptionalPublicImportMessageExtension;
    public const int OptionalLazyMessageExtensionFieldNumber = 27;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage> OptionalLazyMessageExtension;
    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 RepeatedLazyMessageExtensionFieldNumber = 57;
    public static pb::GeneratedExtensionBase<scg::IList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage>> RepeatedLazyMessageExtension;
    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 OneofUint32ExtensionFieldNumber = 111;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<uint> OneofUint32Extension;
    public const int OneofNestedMessageExtensionFieldNumber = 112;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage> OneofNestedMessageExtension;
    public const int OneofStringExtensionFieldNumber = 113;
    public static pb::GeneratedExtensionBase<string> OneofStringExtension;
    public const int OneofBytesExtensionFieldNumber = 114;
    public static pb::GeneratedExtensionBase<pb::ByteString> OneofBytesExtension;
    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;
    public const int UnpackedInt32ExtensionFieldNumber = 90;
    public static pb::GeneratedExtensionBase<scg::IList<int>> UnpackedInt32Extension;
    public const int UnpackedInt64ExtensionFieldNumber = 91;
    public static pb::GeneratedExtensionBase<scg::IList<long>> UnpackedInt64Extension;
    public const int UnpackedUint32ExtensionFieldNumber = 92;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<scg::IList<uint>> UnpackedUint32Extension;
    public const int UnpackedUint64ExtensionFieldNumber = 93;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<scg::IList<ulong>> UnpackedUint64Extension;
    public const int UnpackedSint32ExtensionFieldNumber = 94;
    public static pb::GeneratedExtensionBase<scg::IList<int>> UnpackedSint32Extension;
    public const int UnpackedSint64ExtensionFieldNumber = 95;
    public static pb::GeneratedExtensionBase<scg::IList<long>> UnpackedSint64Extension;
    public const int UnpackedFixed32ExtensionFieldNumber = 96;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<scg::IList<uint>> UnpackedFixed32Extension;
    public const int UnpackedFixed64ExtensionFieldNumber = 97;
    [global::System.CLSCompliant(false)]
    public static pb::GeneratedExtensionBase<scg::IList<ulong>> UnpackedFixed64Extension;
    public const int UnpackedSfixed32ExtensionFieldNumber = 98;
    public static pb::GeneratedExtensionBase<scg::IList<int>> UnpackedSfixed32Extension;
    public const int UnpackedSfixed64ExtensionFieldNumber = 99;
    public static pb::GeneratedExtensionBase<scg::IList<long>> UnpackedSfixed64Extension;
    public const int UnpackedFloatExtensionFieldNumber = 100;
    public static pb::GeneratedExtensionBase<scg::IList<float>> UnpackedFloatExtension;
    public const int UnpackedDoubleExtensionFieldNumber = 101;
    public static pb::GeneratedExtensionBase<scg::IList<double>> UnpackedDoubleExtension;
    public const int UnpackedBoolExtensionFieldNumber = 102;
    public static pb::GeneratedExtensionBase<scg::IList<bool>> UnpackedBoolExtension;
    public const int UnpackedEnumExtensionFieldNumber = 103;
    public static pb::GeneratedExtensionBase<scg::IList<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>> UnpackedEnumExtension;
    #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_NestedTestAllTypes__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.NestedTestAllTypes, global::Google.ProtocolBuffers.TestProtos.NestedTestAllTypes.Builder> internal__static_protobuf_unittest_NestedTestAllTypes__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_TestEagerMessage__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestEagerMessage, global::Google.ProtocolBuffers.TestProtos.TestEagerMessage.Builder> internal__static_protobuf_unittest_TestEagerMessage__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestLazyMessage__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestLazyMessage, global::Google.ProtocolBuffers.TestProtos.TestLazyMessage.Builder> internal__static_protobuf_unittest_TestLazyMessage__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_TestFieldOrderings_NestedMessage__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestFieldOrderings.Types.NestedMessage, global::Google.ProtocolBuffers.TestProtos.TestFieldOrderings.Types.NestedMessage.Builder> internal__static_protobuf_unittest_TestFieldOrderings_NestedMessage__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_MoreString__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.MoreString, global::Google.ProtocolBuffers.TestProtos.MoreString.Builder> internal__static_protobuf_unittest_MoreString__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_MoreBytes__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.MoreBytes, global::Google.ProtocolBuffers.TestProtos.MoreBytes.Builder> internal__static_protobuf_unittest_MoreBytes__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_Int32Message__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.Int32Message, global::Google.ProtocolBuffers.TestProtos.Int32Message.Builder> internal__static_protobuf_unittest_Int32Message__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_Uint32Message__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.Uint32Message, global::Google.ProtocolBuffers.TestProtos.Uint32Message.Builder> internal__static_protobuf_unittest_Uint32Message__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_Int64Message__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.Int64Message, global::Google.ProtocolBuffers.TestProtos.Int64Message.Builder> internal__static_protobuf_unittest_Int64Message__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_Uint64Message__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.Uint64Message, global::Google.ProtocolBuffers.TestProtos.Uint64Message.Builder> internal__static_protobuf_unittest_Uint64Message__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_BoolMessage__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.BoolMessage, global::Google.ProtocolBuffers.TestProtos.BoolMessage.Builder> internal__static_protobuf_unittest_BoolMessage__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestOneof__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestOneof, global::Google.ProtocolBuffers.TestProtos.TestOneof.Builder> internal__static_protobuf_unittest_TestOneof__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestOneof_FooGroup__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestOneof.Types.FooGroup, global::Google.ProtocolBuffers.TestProtos.TestOneof.Types.FooGroup.Builder> internal__static_protobuf_unittest_TestOneof_FooGroup__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestOneofBackwardsCompatible__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestOneofBackwardsCompatible, global::Google.ProtocolBuffers.TestProtos.TestOneofBackwardsCompatible.Builder> internal__static_protobuf_unittest_TestOneofBackwardsCompatible__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestOneofBackwardsCompatible_FooGroup__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestOneofBackwardsCompatible.Types.FooGroup, global::Google.ProtocolBuffers.TestProtos.TestOneofBackwardsCompatible.Types.FooGroup.Builder> internal__static_protobuf_unittest_TestOneofBackwardsCompatible_FooGroup__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestOneof2__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestOneof2, global::Google.ProtocolBuffers.TestProtos.TestOneof2.Builder> internal__static_protobuf_unittest_TestOneof2__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestOneof2_FooGroup__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.FooGroup, global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.FooGroup.Builder> internal__static_protobuf_unittest_TestOneof2_FooGroup__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestOneof2_NestedMessage__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage, global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage.Builder> internal__static_protobuf_unittest_TestOneof2_NestedMessage__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestRequiredOneof__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof, global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.Builder> internal__static_protobuf_unittest_TestRequiredOneof__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestRequiredOneof_NestedMessage__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.Types.NestedMessage, global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.Types.NestedMessage.Builder> internal__static_protobuf_unittest_TestRequiredOneof_NestedMessage__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_TestUnpackedExtensions__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestUnpackedExtensions, global::Google.ProtocolBuffers.TestProtos.TestUnpackedExtensions.Builder> internal__static_protobuf_unittest_TestUnpackedExtensions__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_TestParsingMerge__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge, global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Builder> internal__static_protobuf_unittest_TestParsingMerge__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestParsingMerge_RepeatedFieldsGenerator__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator, global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Builder> internal__static_protobuf_unittest_TestParsingMerge_RepeatedFieldsGenerator__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestParsingMerge_RepeatedFieldsGenerator_Group1__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group1, global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group1.Builder> internal__static_protobuf_unittest_TestParsingMerge_RepeatedFieldsGenerator_Group1__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestParsingMerge_RepeatedFieldsGenerator_Group2__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group2, global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group2.Builder> internal__static_protobuf_unittest_TestParsingMerge_RepeatedFieldsGenerator_Group2__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestParsingMerge_OptionalGroup__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.OptionalGroup, global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.OptionalGroup.Builder> internal__static_protobuf_unittest_TestParsingMerge_OptionalGroup__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestParsingMerge_RepeatedGroup__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedGroup, global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedGroup.Builder> internal__static_protobuf_unittest_TestParsingMerge_RepeatedGroup__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestCommentInjectionMessage__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestCommentInjectionMessage, global::Google.ProtocolBuffers.TestProtos.TestCommentInjectionMessage.Builder> internal__static_protobuf_unittest_TestCommentInjectionMessage__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_FooClientMessage__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.FooClientMessage, global::Google.ProtocolBuffers.TestProtos.FooClientMessage.Builder> internal__static_protobuf_unittest_FooClientMessage__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_FooServerMessage__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.FooServerMessage, global::Google.ProtocolBuffers.TestProtos.FooServerMessage.Builder> internal__static_protobuf_unittest_FooServerMessage__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 Unittest() {
      byte[] descriptorData = global::System.Convert.FromBase64String(
          string.Concat(
            "Ch5nb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8SEXByb3RvYnVmX3Vu", 
            "aXR0ZXN0GiVnb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfaW1wb3J0LnByb3Rv", 
            "Iu0YCgxUZXN0QWxsVHlwZXMSFgoOb3B0aW9uYWxfaW50MzIYASABKAUSFgoO", 
            "b3B0aW9uYWxfaW50NjQYAiABKAMSFwoPb3B0aW9uYWxfdWludDMyGAMgASgN", 
            "EhcKD29wdGlvbmFsX3VpbnQ2NBgEIAEoBBIXCg9vcHRpb25hbF9zaW50MzIY", 
            "BSABKBESFwoPb3B0aW9uYWxfc2ludDY0GAYgASgSEhgKEG9wdGlvbmFsX2Zp", 
            "eGVkMzIYByABKAcSGAoQb3B0aW9uYWxfZml4ZWQ2NBgIIAEoBhIZChFvcHRp", 
            "b25hbF9zZml4ZWQzMhgJIAEoDxIZChFvcHRpb25hbF9zZml4ZWQ2NBgKIAEo", 
            "EBIWCg5vcHRpb25hbF9mbG9hdBgLIAEoAhIXCg9vcHRpb25hbF9kb3VibGUY", 
            "DCABKAESFQoNb3B0aW9uYWxfYm9vbBgNIAEoCBIXCg9vcHRpb25hbF9zdHJp", 
            "bmcYDiABKAkSFgoOb3B0aW9uYWxfYnl0ZXMYDyABKAwSRAoNb3B0aW9uYWxn", 
            "cm91cBgQIAEoCjItLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5P", 
            "cHRpb25hbEdyb3VwEk4KF29wdGlvbmFsX25lc3RlZF9tZXNzYWdlGBIgASgL", 
            "Mi0ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3Nh", 
            "Z2USQwoYb3B0aW9uYWxfZm9yZWlnbl9tZXNzYWdlGBMgASgLMiEucHJvdG9i", 
            "dWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2USSAoXb3B0aW9uYWxfaW1wb3J0", 
            "X21lc3NhZ2UYFCABKAsyJy5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1w", 
            "b3J0TWVzc2FnZRJIChRvcHRpb25hbF9uZXN0ZWRfZW51bRgVIAEoDjIqLnBy", 
            "b3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtEj0KFW9w", 
            "dGlvbmFsX2ZvcmVpZ25fZW51bRgWIAEoDjIeLnByb3RvYnVmX3VuaXR0ZXN0", 
            "LkZvcmVpZ25FbnVtEkIKFG9wdGlvbmFsX2ltcG9ydF9lbnVtGBcgASgOMiQu", 
            "cHJvdG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydEVudW0SIQoVb3B0aW9u", 
            "YWxfc3RyaW5nX3BpZWNlGBggASgJQgIIAhIZCg1vcHRpb25hbF9jb3JkGBkg", 
            "ASgJQgIIARJVCh5vcHRpb25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2UYGiAB", 
            "KAsyLS5wcm90b2J1Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVz", 
            "c2FnZRJQChVvcHRpb25hbF9sYXp5X21lc3NhZ2UYGyABKAsyLS5wcm90b2J1", 
            "Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZUICKAESFgoO", 
            "cmVwZWF0ZWRfaW50MzIYHyADKAUSFgoOcmVwZWF0ZWRfaW50NjQYICADKAMS", 
            "FwoPcmVwZWF0ZWRfdWludDMyGCEgAygNEhcKD3JlcGVhdGVkX3VpbnQ2NBgi", 
            "IAMoBBIXCg9yZXBlYXRlZF9zaW50MzIYIyADKBESFwoPcmVwZWF0ZWRfc2lu", 
            "dDY0GCQgAygSEhgKEHJlcGVhdGVkX2ZpeGVkMzIYJSADKAcSGAoQcmVwZWF0", 
            "ZWRfZml4ZWQ2NBgmIAMoBhIZChFyZXBlYXRlZF9zZml4ZWQzMhgnIAMoDxIZ", 
            "ChFyZXBlYXRlZF9zZml4ZWQ2NBgoIAMoEBIWCg5yZXBlYXRlZF9mbG9hdBgp", 
            "IAMoAhIXCg9yZXBlYXRlZF9kb3VibGUYKiADKAESFQoNcmVwZWF0ZWRfYm9v", 
            "bBgrIAMoCBIXCg9yZXBlYXRlZF9zdHJpbmcYLCADKAkSFgoOcmVwZWF0ZWRf", 
            "Ynl0ZXMYLSADKAwSRAoNcmVwZWF0ZWRncm91cBguIAMoCjItLnByb3RvYnVm", 
            "X3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5SZXBlYXRlZEdyb3VwEk4KF3JlcGVh", 
            "dGVkX25lc3RlZF9tZXNzYWdlGDAgAygLMi0ucHJvdG9idWZfdW5pdHRlc3Qu", 
            "VGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2USQwoYcmVwZWF0ZWRfZm9yZWln", 
            "bl9tZXNzYWdlGDEgAygLMiEucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1l", 
            "c3NhZ2USSAoXcmVwZWF0ZWRfaW1wb3J0X21lc3NhZ2UYMiADKAsyJy5wcm90", 
            "b2J1Zl91bml0dGVzdF9pbXBvcnQuSW1wb3J0TWVzc2FnZRJIChRyZXBlYXRl", 
            "ZF9uZXN0ZWRfZW51bRgzIAMoDjIqLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RB", 
            "bGxUeXBlcy5OZXN0ZWRFbnVtEj0KFXJlcGVhdGVkX2ZvcmVpZ25fZW51bRg0", 
            "IAMoDjIeLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtEkIKFHJlcGVh", 
            "dGVkX2ltcG9ydF9lbnVtGDUgAygOMiQucHJvdG9idWZfdW5pdHRlc3RfaW1w", 
            "b3J0LkltcG9ydEVudW0SIQoVcmVwZWF0ZWRfc3RyaW5nX3BpZWNlGDYgAygJ", 
            "QgIIAhIZCg1yZXBlYXRlZF9jb3JkGDcgAygJQgIIARJQChVyZXBlYXRlZF9s", 
            "YXp5X21lc3NhZ2UYOSADKAsyLS5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxs", 
            "VHlwZXMuTmVzdGVkTWVzc2FnZUICKAESGQoNZGVmYXVsdF9pbnQzMhg9IAEo", 
            "BToCNDESGQoNZGVmYXVsdF9pbnQ2NBg+IAEoAzoCNDISGgoOZGVmYXVsdF91", 
            "aW50MzIYPyABKA06AjQzEhoKDmRlZmF1bHRfdWludDY0GEAgASgEOgI0NBIb", 
            "Cg5kZWZhdWx0X3NpbnQzMhhBIAEoEToDLTQ1EhoKDmRlZmF1bHRfc2ludDY0", 
            "GEIgASgSOgI0NhIbCg9kZWZhdWx0X2ZpeGVkMzIYQyABKAc6AjQ3EhsKD2Rl", 
            "ZmF1bHRfZml4ZWQ2NBhEIAEoBjoCNDgSHAoQZGVmYXVsdF9zZml4ZWQzMhhF", 
            "IAEoDzoCNDkSHQoQZGVmYXVsdF9zZml4ZWQ2NBhGIAEoEDoDLTUwEhsKDWRl", 
            "ZmF1bHRfZmxvYXQYRyABKAI6BDUxLjUSHQoOZGVmYXVsdF9kb3VibGUYSCAB", 
            "KAE6BTUyMDAwEhoKDGRlZmF1bHRfYm9vbBhJIAEoCDoEdHJ1ZRIdCg5kZWZh", 
            "dWx0X3N0cmluZxhKIAEoCToFaGVsbG8SHAoNZGVmYXVsdF9ieXRlcxhLIAEo", 
            "DDoFd29ybGQSTAoTZGVmYXVsdF9uZXN0ZWRfZW51bRhRIAEoDjIqLnByb3Rv", 
            "YnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtOgNCQVISSQoU", 
            "ZGVmYXVsdF9mb3JlaWduX2VudW0YUiABKA4yHi5wcm90b2J1Zl91bml0dGVz", 
            "dC5Gb3JlaWduRW51bToLRk9SRUlHTl9CQVISTQoTZGVmYXVsdF9pbXBvcnRf", 
            "ZW51bRhTIAEoDjIkLnByb3RvYnVmX3VuaXR0ZXN0X2ltcG9ydC5JbXBvcnRF", 
            "bnVtOgpJTVBPUlRfQkFSEiUKFGRlZmF1bHRfc3RyaW5nX3BpZWNlGFQgASgJ", 
            "OgNhYmNCAggCEh0KDGRlZmF1bHRfY29yZBhVIAEoCToDMTIzQgIIARIWCgxv", 
            "bmVvZl91aW50MzIYbyABKA1IABJNChRvbmVvZl9uZXN0ZWRfbWVzc2FnZRhw", 
            "IAEoCzItLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRN", 
            "ZXNzYWdlSAASFgoMb25lb2Zfc3RyaW5nGHEgASgJSAASFQoLb25lb2ZfYnl0", 
            "ZXMYciABKAxIABobCg1OZXN0ZWRNZXNzYWdlEgoKAmJiGAEgASgFGhoKDU9w", 
            "dGlvbmFsR3JvdXASCQoBYRgRIAEoBRoaCg1SZXBlYXRlZEdyb3VwEgkKAWEY", 
            "LyABKAUiOQoKTmVzdGVkRW51bRIHCgNGT08QARIHCgNCQVIQAhIHCgNCQVoQ", 
            "AxIQCgNORUcQ////////////AUINCgtvbmVvZl9maWVsZCJ8ChJOZXN0ZWRU", 
            "ZXN0QWxsVHlwZXMSNAoFY2hpbGQYASABKAsyJS5wcm90b2J1Zl91bml0dGVz", 
            "dC5OZXN0ZWRUZXN0QWxsVHlwZXMSMAoHcGF5bG9hZBgCIAEoCzIfLnByb3Rv", 
            "YnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyI0ChRUZXN0RGVwcmVjYXRlZEZp", 
            "ZWxkcxIcChBkZXByZWNhdGVkX2ludDMyGAEgASgFQgIYASIbCg5Gb3JlaWdu", 
            "TWVzc2FnZRIJCgFjGAEgASgFIh0KEVRlc3RBbGxFeHRlbnNpb25zKggIARCA", 
            "gICAAiIkChdPcHRpb25hbEdyb3VwX2V4dGVuc2lvbhIJCgFhGBEgASgFIiQK", 
            "F1JlcGVhdGVkR3JvdXBfZXh0ZW5zaW9uEgkKAWEYLyABKAUimAEKE1Rlc3RO", 
            "ZXN0ZWRFeHRlbnNpb24yOQoEdGVzdBIkLnByb3RvYnVmX3VuaXR0ZXN0LlRl", 
            "c3RBbGxFeHRlbnNpb25zGOoHIAEoCToEdGVzdDJGChduZXN0ZWRfc3RyaW5n", 
            "X2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNp", 
            "b25zGOsHIAEoCSLVBQoMVGVzdFJlcXVpcmVkEgkKAWEYASACKAUSDgoGZHVt", 
            "bXkyGAIgASgFEgkKAWIYAyACKAUSDgoGZHVtbXk0GAQgASgFEg4KBmR1bW15", 
            "NRgFIAEoBRIOCgZkdW1teTYYBiABKAUSDgoGZHVtbXk3GAcgASgFEg4KBmR1", 
            "bW15OBgIIAEoBRIOCgZkdW1teTkYCSABKAUSDwoHZHVtbXkxMBgKIAEoBRIP", 
            "CgdkdW1teTExGAsgASgFEg8KB2R1bW15MTIYDCABKAUSDwoHZHVtbXkxMxgN", 
            "IAEoBRIPCgdkdW1teTE0GA4gASgFEg8KB2R1bW15MTUYDyABKAUSDwoHZHVt", 
            "bXkxNhgQIAEoBRIPCgdkdW1teTE3GBEgASgFEg8KB2R1bW15MTgYEiABKAUS", 
            "DwoHZHVtbXkxORgTIAEoBRIPCgdkdW1teTIwGBQgASgFEg8KB2R1bW15MjEY", 
            "FSABKAUSDwoHZHVtbXkyMhgWIAEoBRIPCgdkdW1teTIzGBcgASgFEg8KB2R1", 
            "bW15MjQYGCABKAUSDwoHZHVtbXkyNRgZIAEoBRIPCgdkdW1teTI2GBogASgF", 
            "Eg8KB2R1bW15MjcYGyABKAUSDwoHZHVtbXkyOBgcIAEoBRIPCgdkdW1teTI5", 
            "GB0gASgFEg8KB2R1bW15MzAYHiABKAUSDwoHZHVtbXkzMRgfIAEoBRIPCgdk", 
            "dW1teTMyGCAgASgFEgkKAWMYISACKAUyVgoGc2luZ2xlEiQucHJvdG9idWZf", 
            "dW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMY6AcgASgLMh8ucHJvdG9idWZf", 
            "dW5pdHRlc3QuVGVzdFJlcXVpcmVkMlUKBW11bHRpEiQucHJvdG9idWZfdW5p", 
            "dHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMY6QcgAygLMh8ucHJvdG9idWZfdW5p", 
            "dHRlc3QuVGVzdFJlcXVpcmVkIpoBChNUZXN0UmVxdWlyZWRGb3JlaWduEjkK", 
            "EG9wdGlvbmFsX21lc3NhZ2UYASABKAsyHy5wcm90b2J1Zl91bml0dGVzdC5U", 
            "ZXN0UmVxdWlyZWQSOQoQcmVwZWF0ZWRfbWVzc2FnZRgCIAMoCzIfLnByb3Rv", 
            "YnVmX3VuaXR0ZXN0LlRlc3RSZXF1aXJlZBINCgVkdW1teRgDIAEoBSJaChFU", 
            "ZXN0Rm9yZWlnbk5lc3RlZBJFCg5mb3JlaWduX25lc3RlZBgBIAEoCzItLnBy", 
            "b3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlIhIK", 
            "EFRlc3RFbXB0eU1lc3NhZ2UiKgoeVGVzdEVtcHR5TWVzc2FnZVdpdGhFeHRl", 
            "bnNpb25zKggIARCAgICAAiI3ChtUZXN0TXVsdGlwbGVFeHRlbnNpb25SYW5n", 
            "ZXMqBAgqECsqBgivIBCUISoKCICABBCAgICAAiI0ChhUZXN0UmVhbGx5TGFy", 
            "Z2VUYWdOdW1iZXISCQoBYRgBIAEoBRINCgJiYhj///9/IAEoBSJVChRUZXN0", 
            "UmVjdXJzaXZlTWVzc2FnZRIyCgFhGAEgASgLMicucHJvdG9idWZfdW5pdHRl", 
            "c3QuVGVzdFJlY3Vyc2l2ZU1lc3NhZ2USCQoBaRgCIAEoBSJLChRUZXN0TXV0", 
            "dWFsUmVjdXJzaW9uQRIzCgJiYhgBIAEoCzInLnByb3RvYnVmX3VuaXR0ZXN0", 
            "LlRlc3RNdXR1YWxSZWN1cnNpb25CImIKFFRlc3RNdXR1YWxSZWN1cnNpb25C", 
            "EjIKAWEYASABKAsyJy5wcm90b2J1Zl91bml0dGVzdC5UZXN0TXV0dWFsUmVj", 
            "dXJzaW9uQRIWCg5vcHRpb25hbF9pbnQzMhgCIAEoBSKzAQoSVGVzdER1cEZp", 
            "ZWxkTnVtYmVyEgkKAWEYASABKAUSNgoDZm9vGAIgASgKMikucHJvdG9idWZf", 
            "dW5pdHRlc3QuVGVzdER1cEZpZWxkTnVtYmVyLkZvbxI2CgNiYXIYAyABKAoy", 
            "KS5wcm90b2J1Zl91bml0dGVzdC5UZXN0RHVwRmllbGROdW1iZXIuQmFyGhAK", 
            "A0ZvbxIJCgFhGAEgASgFGhAKA0JhchIJCgFhGAEgASgFIkwKEFRlc3RFYWdl", 
            "ck1lc3NhZ2USOAoLc3ViX21lc3NhZ2UYASABKAsyHy5wcm90b2J1Zl91bml0", 
            "dGVzdC5UZXN0QWxsVHlwZXNCAigAIksKD1Rlc3RMYXp5TWVzc2FnZRI4Cgtz", 
            "dWJfbWVzc2FnZRgBIAEoCzIfLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxU", 
            "eXBlc0ICKAEigAIKGFRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cxJaChdvcHRp", 
            "b25hbF9uZXN0ZWRfbWVzc2FnZRgBIAEoCzI5LnByb3RvYnVmX3VuaXR0ZXN0", 
            "LlRlc3ROZXN0ZWRNZXNzYWdlSGFzQml0cy5OZXN0ZWRNZXNzYWdlGocBCg1O", 
            "ZXN0ZWRNZXNzYWdlEiQKHG5lc3RlZG1lc3NhZ2VfcmVwZWF0ZWRfaW50MzIY", 
            "ASADKAUSUAolbmVzdGVkbWVzc2FnZV9yZXBlYXRlZF9mb3JlaWdubWVzc2Fn", 
            "ZRgCIAMoCzIhLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNzYWdlIuUD", 
            "ChdUZXN0Q2FtZWxDYXNlRmllbGROYW1lcxIWCg5QcmltaXRpdmVGaWVsZBgB", 
            "IAEoBRITCgtTdHJpbmdGaWVsZBgCIAEoCRIxCglFbnVtRmllbGQYAyABKA4y", 
            "Hi5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bRI3CgxNZXNzYWdlRmll", 
            "bGQYBCABKAsyIS5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZRIc", 
            "ChBTdHJpbmdQaWVjZUZpZWxkGAUgASgJQgIIAhIVCglDb3JkRmllbGQYBiAB", 
            "KAlCAggBEh4KFlJlcGVhdGVkUHJpbWl0aXZlRmllbGQYByADKAUSGwoTUmVw", 
            "ZWF0ZWRTdHJpbmdGaWVsZBgIIAMoCRI5ChFSZXBlYXRlZEVudW1GaWVsZBgJ", 
            "IAMoDjIeLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtEj8KFFJlcGVh", 
            "dGVkTWVzc2FnZUZpZWxkGAogAygLMiEucHJvdG9idWZfdW5pdHRlc3QuRm9y", 
            "ZWlnbk1lc3NhZ2USJAoYUmVwZWF0ZWRTdHJpbmdQaWVjZUZpZWxkGAsgAygJ", 
            "QgIIAhIdChFSZXBlYXRlZENvcmRGaWVsZBgMIAMoCUICCAEi1QEKElRlc3RG", 
            "aWVsZE9yZGVyaW5ncxIRCglteV9zdHJpbmcYCyABKAkSDgoGbXlfaW50GAEg", 
            "ASgDEhAKCG15X2Zsb2F0GGUgASgCElUKF29wdGlvbmFsX25lc3RlZF9tZXNz", 
            "YWdlGMgBIAEoCzIzLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RGaWVsZE9yZGVy", 
            "aW5ncy5OZXN0ZWRNZXNzYWdlGicKDU5lc3RlZE1lc3NhZ2USCgoCb28YAiAB", 
            "KAMSCgoCYmIYASABKAUqBAgCEAsqBAgMEGUitgcKGFRlc3RFeHRyZW1lRGVm", 
            "YXVsdFZhbHVlcxI/Cg1lc2NhcGVkX2J5dGVzGAEgASgMOihcMDAwXDAwMVww", 
            "MDdcMDEwXDAxNFxuXHJcdFwwMTNcXFwnXCJcMzc2EiAKDGxhcmdlX3VpbnQz", 
            "MhgCIAEoDToKNDI5NDk2NzI5NRIqCgxsYXJnZV91aW50NjQYAyABKAQ6FDE4", 
            "NDQ2NzQ0MDczNzA5NTUxNjE1EiAKC3NtYWxsX2ludDMyGAQgASgFOgstMjE0", 
            "NzQ4MzY0NxIpCgtzbWFsbF9pbnQ2NBgFIAEoAzoULTkyMjMzNzIwMzY4NTQ3", 
            "NzU4MDcSJwoScmVhbGx5X3NtYWxsX2ludDMyGBUgASgFOgstMjE0NzQ4MzY0", 
            "OBIwChJyZWFsbHlfc21hbGxfaW50NjQYFiABKAM6FC05MjIzMzcyMDM2ODU0", 
            "Nzc1ODA4EhgKC3V0Zjhfc3RyaW5nGAYgASgJOgPhiLQSFQoKemVyb19mbG9h", 
            "dBgHIAEoAjoBMBIUCglvbmVfZmxvYXQYCCABKAI6ATESGAoLc21hbGxfZmxv", 
            "YXQYCSABKAI6AzEuNRIeChJuZWdhdGl2ZV9vbmVfZmxvYXQYCiABKAI6Ai0x", 
            "EhwKDm5lZ2F0aXZlX2Zsb2F0GAsgASgCOgQtMS41EhoKC2xhcmdlX2Zsb2F0", 
            "GAwgASgCOgUyZSswOBIkChRzbWFsbF9uZWdhdGl2ZV9mbG9hdBgNIAEoAjoG", 
            "LThlLTI4EhcKCmluZl9kb3VibGUYDiABKAE6A2luZhIcCg5uZWdfaW5mX2Rv", 
            "dWJsZRgPIAEoAToELWluZhIXCgpuYW5fZG91YmxlGBAgASgBOgNuYW4SFgoJ", 
            "aW5mX2Zsb2F0GBEgASgCOgNpbmYSGwoNbmVnX2luZl9mbG9hdBgSIAEoAjoE", 
            "LWluZhIWCgluYW5fZmxvYXQYEyABKAI6A25hbhIrCgxjcHBfdHJpZ3JhcGgY", 
            "FCABKAk6FT8gPyA/PyA/PyA/Pz8gPz8vID8/LRIgChBzdHJpbmdfd2l0aF96", 
            "ZXJvGBcgASgJOgZoZWwAbG8SIgoPYnl0ZXNfd2l0aF96ZXJvGBggASgMOgl3", 
            "b3JcMDAwbGQSKAoWc3RyaW5nX3BpZWNlX3dpdGhfemVybxgZIAEoCToEYWIA", 
            "Y0ICCAISIAoOY29yZF93aXRoX3plcm8YGiABKAk6BDEyADNCAggBEiYKEnJl", 
            "cGxhY2VtZW50X3N0cmluZxgbIAEoCToKJHt1bmtub3dufSJLChFTcGFyc2VF", 
            "bnVtTWVzc2FnZRI2CgtzcGFyc2VfZW51bRgBIAEoDjIhLnByb3RvYnVmX3Vu", 
            "aXR0ZXN0LlRlc3RTcGFyc2VFbnVtIhkKCU9uZVN0cmluZxIMCgRkYXRhGAEg", 
            "ASgJIhoKCk1vcmVTdHJpbmcSDAoEZGF0YRgBIAMoCSIYCghPbmVCeXRlcxIM", 
            "CgRkYXRhGAEgASgMIhkKCU1vcmVCeXRlcxIMCgRkYXRhGAEgAygMIhwKDElu", 
            "dDMyTWVzc2FnZRIMCgRkYXRhGAEgASgFIh0KDVVpbnQzMk1lc3NhZ2USDAoE", 
            "ZGF0YRgBIAEoDSIcCgxJbnQ2NE1lc3NhZ2USDAoEZGF0YRgBIAEoAyIdCg1V", 
            "aW50NjRNZXNzYWdlEgwKBGRhdGEYASABKAQiGwoLQm9vbE1lc3NhZ2USDAoE", 
            "ZGF0YRgBIAEoCCLQAQoJVGVzdE9uZW9mEhEKB2Zvb19pbnQYASABKAVIABIU", 
            "Cgpmb29fc3RyaW5nGAIgASgJSAASNgoLZm9vX21lc3NhZ2UYAyABKAsyHy5w", 
            "cm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXNIABI5Cghmb29ncm91cBgE", 
            "IAEoCjIlLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVvZi5Gb29Hcm91cEgA", 
            "GiAKCEZvb0dyb3VwEgkKAWEYBSABKAUSCQoBYhgGIAEoCUIFCgNmb28i5wEK", 
            "HFRlc3RPbmVvZkJhY2t3YXJkc0NvbXBhdGlibGUSDwoHZm9vX2ludBgBIAEo", 
            "BRISCgpmb29fc3RyaW5nGAIgASgJEjQKC2Zvb19tZXNzYWdlGAMgASgLMh8u", 
            "cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzEkoKCGZvb2dyb3VwGAQg", 
            "ASgKMjgucHJvdG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mQmFja3dhcmRzQ29t", 
            "cGF0aWJsZS5Gb29Hcm91cBogCghGb29Hcm91cBIJCgFhGAUgASgFEgkKAWIY", 
            "BiABKAkingYKClRlc3RPbmVvZjISEQoHZm9vX2ludBgBIAEoBUgAEhQKCmZv", 
            "b19zdHJpbmcYAiABKAlIABIWCghmb29fY29yZBgDIAEoCUICCAFIABIeChBm", 
            "b29fc3RyaW5nX3BpZWNlGAQgASgJQgIIAkgAEhMKCWZvb19ieXRlcxgFIAEo", 
            "DEgAEjwKCGZvb19lbnVtGAYgASgOMigucHJvdG9idWZfdW5pdHRlc3QuVGVz", 
            "dE9uZW9mMi5OZXN0ZWRFbnVtSAASQgoLZm9vX21lc3NhZ2UYByABKAsyKy5w", 
            "cm90b2J1Zl91bml0dGVzdC5UZXN0T25lb2YyLk5lc3RlZE1lc3NhZ2VIABI6", 
            "Cghmb29ncm91cBgIIAEoCjImLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RPbmVv", 
            "ZjIuRm9vR3JvdXBIABJLChBmb29fbGF6eV9tZXNzYWdlGAsgASgLMisucHJv", 
            "dG9idWZfdW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRNZXNzYWdlQgIoAUgA", 
            "EhQKB2Jhcl9pbnQYDCABKAU6ATVIARIcCgpiYXJfc3RyaW5nGA0gASgJOgZT", 
            "VFJJTkdIARIcCghiYXJfY29yZBgOIAEoCToEQ09SREICCAFIARImChBiYXJf", 
            "c3RyaW5nX3BpZWNlGA8gASgJOgZTUElFQ0VCAggCSAESGgoJYmFyX2J5dGVz", 
            "GBAgASgMOgVCWVRFU0gBEkEKCGJhcl9lbnVtGBEgASgOMigucHJvdG9idWZf", 
            "dW5pdHRlc3QuVGVzdE9uZW9mMi5OZXN0ZWRFbnVtOgNCQVJIARIPCgdiYXpf", 
            "aW50GBIgASgFEhcKCmJhel9zdHJpbmcYEyABKAk6A0JBWhogCghGb29Hcm91", 
            "cBIJCgFhGAkgASgFEgkKAWIYCiABKAkaMwoNTmVzdGVkTWVzc2FnZRIPCgdx", 
            "dXhfaW50GAEgASgDEhEKCWNvcmdlX2ludBgCIAMoBSInCgpOZXN0ZWRFbnVt", 
            "EgcKA0ZPTxABEgcKA0JBUhACEgcKA0JBWhADQgUKA2Zvb0IFCgNiYXIiuAEK", 
            "EVRlc3RSZXF1aXJlZE9uZW9mEhEKB2Zvb19pbnQYASABKAVIABIUCgpmb29f", 
            "c3RyaW5nGAIgASgJSAASSQoLZm9vX21lc3NhZ2UYAyABKAsyMi5wcm90b2J1", 
            "Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRPbmVvZi5OZXN0ZWRNZXNzYWdlSAAa", 
            "KAoNTmVzdGVkTWVzc2FnZRIXCg9yZXF1aXJlZF9kb3VibGUYASACKAFCBQoD", 
            "Zm9vIqoDCg9UZXN0UGFja2VkVHlwZXMSGAoMcGFja2VkX2ludDMyGFogAygF", 
            "QgIQARIYCgxwYWNrZWRfaW50NjQYWyADKANCAhABEhkKDXBhY2tlZF91aW50", 
            "MzIYXCADKA1CAhABEhkKDXBhY2tlZF91aW50NjQYXSADKARCAhABEhkKDXBh", 
            "Y2tlZF9zaW50MzIYXiADKBFCAhABEhkKDXBhY2tlZF9zaW50NjQYXyADKBJC", 
            "AhABEhoKDnBhY2tlZF9maXhlZDMyGGAgAygHQgIQARIaCg5wYWNrZWRfZml4", 
            "ZWQ2NBhhIAMoBkICEAESGwoPcGFja2VkX3NmaXhlZDMyGGIgAygPQgIQARIb", 
            "Cg9wYWNrZWRfc2ZpeGVkNjQYYyADKBBCAhABEhgKDHBhY2tlZF9mbG9hdBhk", 
            "IAMoAkICEAESGQoNcGFja2VkX2RvdWJsZRhlIAMoAUICEAESFwoLcGFja2Vk", 
            "X2Jvb2wYZiADKAhCAhABEjcKC3BhY2tlZF9lbnVtGGcgAygOMh4ucHJvdG9i", 
            "dWZfdW5pdHRlc3QuRm9yZWlnbkVudW1CAhABIsgDChFUZXN0VW5wYWNrZWRU", 
            "eXBlcxIaCg51bnBhY2tlZF9pbnQzMhhaIAMoBUICEAASGgoOdW5wYWNrZWRf", 
            "aW50NjQYWyADKANCAhAAEhsKD3VucGFja2VkX3VpbnQzMhhcIAMoDUICEAAS", 
            "GwoPdW5wYWNrZWRfdWludDY0GF0gAygEQgIQABIbCg91bnBhY2tlZF9zaW50", 
            "MzIYXiADKBFCAhAAEhsKD3VucGFja2VkX3NpbnQ2NBhfIAMoEkICEAASHAoQ", 
            "dW5wYWNrZWRfZml4ZWQzMhhgIAMoB0ICEAASHAoQdW5wYWNrZWRfZml4ZWQ2", 
            "NBhhIAMoBkICEAASHQoRdW5wYWNrZWRfc2ZpeGVkMzIYYiADKA9CAhAAEh0K", 
            "EXVucGFja2VkX3NmaXhlZDY0GGMgAygQQgIQABIaCg51bnBhY2tlZF9mbG9h", 
            "dBhkIAMoAkICEAASGwoPdW5wYWNrZWRfZG91YmxlGGUgAygBQgIQABIZCg11", 
            "bnBhY2tlZF9ib29sGGYgAygIQgIQABI5Cg11bnBhY2tlZF9lbnVtGGcgAygO", 
            "Mh4ucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW1CAhAAIiAKFFRlc3RQ", 
            "YWNrZWRFeHRlbnNpb25zKggIARCAgICAAiIiChZUZXN0VW5wYWNrZWRFeHRl", 
            "bnNpb25zKggIARCAgICAAiKZBAoVVGVzdER5bmFtaWNFeHRlbnNpb25zEhkK", 
            "EHNjYWxhcl9leHRlbnNpb24Y0A8gASgHEjcKDmVudW1fZXh0ZW5zaW9uGNEP", 
            "IAEoDjIeLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtElkKFmR5bmFt", 
            "aWNfZW51bV9leHRlbnNpb24Y0g8gASgOMjgucHJvdG9idWZfdW5pdHRlc3Qu", 
            "VGVzdER5bmFtaWNFeHRlbnNpb25zLkR5bmFtaWNFbnVtVHlwZRI9ChFtZXNz", 
            "YWdlX2V4dGVuc2lvbhjTDyABKAsyIS5wcm90b2J1Zl91bml0dGVzdC5Gb3Jl", 
            "aWduTWVzc2FnZRJfChlkeW5hbWljX21lc3NhZ2VfZXh0ZW5zaW9uGNQPIAEo", 
            "CzI7LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3REeW5hbWljRXh0ZW5zaW9ucy5E", 
            "eW5hbWljTWVzc2FnZVR5cGUSGwoScmVwZWF0ZWRfZXh0ZW5zaW9uGNUPIAMo", 
            "CRIdChBwYWNrZWRfZXh0ZW5zaW9uGNYPIAMoEUICEAEaLAoSRHluYW1pY01l", 
            "c3NhZ2VUeXBlEhYKDWR5bmFtaWNfZmllbGQYtBAgASgFIkcKD0R5bmFtaWNF", 
            "bnVtVHlwZRIQCgtEWU5BTUlDX0ZPTxCYERIQCgtEWU5BTUlDX0JBUhCZERIQ", 
            "CgtEWU5BTUlDX0JBWhCaESLAAQojVGVzdFJlcGVhdGVkU2NhbGFyRGlmZmVy", 
            "ZW50VGFnU2l6ZXMSGAoQcmVwZWF0ZWRfZml4ZWQzMhgMIAMoBxIWCg5yZXBl", 
            "YXRlZF9pbnQzMhgNIAMoBRIZChByZXBlYXRlZF9maXhlZDY0GP4PIAMoBhIX", 
            "Cg5yZXBlYXRlZF9pbnQ2NBj/DyADKAMSGAoOcmVwZWF0ZWRfZmxvYXQY/v8P", 
            "IAMoAhIZCg9yZXBlYXRlZF91aW50NjQY//8PIAMoBCL3CQoQVGVzdFBhcnNp", 
            "bmdNZXJnZRI7ChJyZXF1aXJlZF9hbGxfdHlwZXMYASACKAsyHy5wcm90b2J1", 
            "Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMSOwoSb3B0aW9uYWxfYWxsX3R5cGVz", 
            "GAIgASgLMh8ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzEjsKEnJl", 
            "cGVhdGVkX2FsbF90eXBlcxgDIAMoCzIfLnByb3RvYnVmX3VuaXR0ZXN0LlRl", 
            "c3RBbGxUeXBlcxJICg1vcHRpb25hbGdyb3VwGAogASgKMjEucHJvdG9idWZf", 
            "dW5pdHRlc3QuVGVzdFBhcnNpbmdNZXJnZS5PcHRpb25hbEdyb3VwEkgKDXJl", 
            "cGVhdGVkZ3JvdXAYFCADKAoyMS5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFy", 
            "c2luZ01lcmdlLlJlcGVhdGVkR3JvdXAaqgQKF1JlcGVhdGVkRmllbGRzR2Vu", 
            "ZXJhdG9yEi8KBmZpZWxkMRgBIAMoCzIfLnByb3RvYnVmX3VuaXR0ZXN0LlRl", 
            "c3RBbGxUeXBlcxIvCgZmaWVsZDIYAiADKAsyHy5wcm90b2J1Zl91bml0dGVz", 
            "dC5UZXN0QWxsVHlwZXMSLwoGZmllbGQzGAMgAygLMh8ucHJvdG9idWZfdW5p", 
            "dHRlc3QuVGVzdEFsbFR5cGVzElIKBmdyb3VwMRgKIAMoCjJCLnByb3RvYnVm", 
            "X3VuaXR0ZXN0LlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5l", 
            "cmF0b3IuR3JvdXAxElIKBmdyb3VwMhgUIAMoCjJCLnByb3RvYnVmX3VuaXR0", 
            "ZXN0LlRlc3RQYXJzaW5nTWVyZ2UuUmVwZWF0ZWRGaWVsZHNHZW5lcmF0b3Iu", 
            "R3JvdXAyEi4KBGV4dDEY6AcgAygLMh8ucHJvdG9idWZfdW5pdHRlc3QuVGVz", 
            "dEFsbFR5cGVzEi4KBGV4dDIY6QcgAygLMh8ucHJvdG9idWZfdW5pdHRlc3Qu", 
            "VGVzdEFsbFR5cGVzGjkKBkdyb3VwMRIvCgZmaWVsZDEYCyABKAsyHy5wcm90", 
            "b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMaOQoGR3JvdXAyEi8KBmZpZWxk", 
            "MRgVIAEoCzIfLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcxpSCg1P", 
            "cHRpb25hbEdyb3VwEkEKGG9wdGlvbmFsX2dyb3VwX2FsbF90eXBlcxgLIAEo", 
            "CzIfLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcxpSCg1SZXBlYXRl", 
            "ZEdyb3VwEkEKGHJlcGVhdGVkX2dyb3VwX2FsbF90eXBlcxgVIAEoCzIfLnBy", 
            "b3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcyoJCOgHEICAgIACMlsKDG9w", 
            "dGlvbmFsX2V4dBIjLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYXJzaW5nTWVy", 
            "Z2UY6AcgASgLMh8ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzMlsK", 
            "DHJlcGVhdGVkX2V4dBIjLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYXJzaW5n", 
            "TWVyZ2UY6QcgAygLMh8ucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVz", 
            "IkQKG1Rlc3RDb21tZW50SW5qZWN0aW9uTWVzc2FnZRIlCgFhGAEgASgJOhoq", 
            "LyA8LSBOZWl0aGVyIHNob3VsZCB0aGlzLiIMCgpGb29SZXF1ZXN0Ig0KC0Zv", 
            "b1Jlc3BvbnNlIhIKEEZvb0NsaWVudE1lc3NhZ2UiEgoQRm9vU2VydmVyTWVz", 
            "c2FnZSIMCgpCYXJSZXF1ZXN0Ig0KC0JhclJlc3BvbnNlKkAKC0ZvcmVpZ25F", 
            "bnVtEg8KC0ZPUkVJR05fRk9PEAQSDwoLRk9SRUlHTl9CQVIQBRIPCgtGT1JF", 
            "SUdOX0JBWhAGKksKFFRlc3RFbnVtV2l0aER1cFZhbHVlEggKBEZPTzEQARII", 
            "CgRCQVIxEAISBwoDQkFaEAMSCAoERk9PMhABEggKBEJBUjIQAhoCEAEqiQEK", 
            "DlRlc3RTcGFyc2VFbnVtEgwKCFNQQVJTRV9BEHsSDgoIU1BBUlNFX0IQpucD", 
            "Eg8KCFNQQVJTRV9DELKxgAYSFQoIU1BBUlNFX0QQ8f//////////ARIVCghT", 
            "UEFSU0VfRRC03vz///////8BEgwKCFNQQVJTRV9GEAASDAoIU1BBUlNFX0cQ", 
            "AjKZAQoLVGVzdFNlcnZpY2USRAoDRm9vEh0ucHJvdG9idWZfdW5pdHRlc3Qu", 
            "Rm9vUmVxdWVzdBoeLnByb3RvYnVmX3VuaXR0ZXN0LkZvb1Jlc3BvbnNlEkQK", 
            "A0JhchIdLnByb3RvYnVmX3VuaXR0ZXN0LkJhclJlcXVlc3QaHi5wcm90b2J1", 
            "Zl91bml0dGVzdC5CYXJSZXNwb25zZTpGChhvcHRpb25hbF9pbnQzMl9leHRl", 
            "bnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxgB", 
            "IAEoBTpGChhvcHRpb25hbF9pbnQ2NF9leHRlbnNpb24SJC5wcm90b2J1Zl91", 
            "bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxgCIAEoAzpHChlvcHRpb25hbF91", 
            "aW50MzJfZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4", 
            "dGVuc2lvbnMYAyABKA06RwoZb3B0aW9uYWxfdWludDY0X2V4dGVuc2lvbhIk", 
            "LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGAQgASgEOkcK", 
            "GW9wdGlvbmFsX3NpbnQzMl9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVz", 
            "dC5UZXN0QWxsRXh0ZW5zaW9ucxgFIAEoETpHChlvcHRpb25hbF9zaW50NjRf", 
            "ZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lv", 
            "bnMYBiABKBI6SAoab3B0aW9uYWxfZml4ZWQzMl9leHRlbnNpb24SJC5wcm90", 
            "b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxgHIAEoBzpIChpvcHRp", 
            "b25hbF9maXhlZDY0X2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRl", 
            "c3RBbGxFeHRlbnNpb25zGAggASgGOkkKG29wdGlvbmFsX3NmaXhlZDMyX2V4", 
            "dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25z", 
            "GAkgASgPOkkKG29wdGlvbmFsX3NmaXhlZDY0X2V4dGVuc2lvbhIkLnByb3Rv", 
            "YnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGAogASgQOkYKGG9wdGlv", 
            "bmFsX2Zsb2F0X2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RB", 
            "bGxFeHRlbnNpb25zGAsgASgCOkcKGW9wdGlvbmFsX2RvdWJsZV9leHRlbnNp", 
            "b24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxgMIAEo", 
            "ATpFChdvcHRpb25hbF9ib29sX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0", 
            "ZXN0LlRlc3RBbGxFeHRlbnNpb25zGA0gASgIOkcKGW9wdGlvbmFsX3N0cmlu", 
            "Z19leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5z", 
            "aW9ucxgOIAEoCTpGChhvcHRpb25hbF9ieXRlc19leHRlbnNpb24SJC5wcm90", 
            "b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxgPIAEoDDpxChdvcHRp", 
            "b25hbGdyb3VwX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RB", 
            "bGxFeHRlbnNpb25zGBAgASgKMioucHJvdG9idWZfdW5pdHRlc3QuT3B0aW9u", 
            "YWxHcm91cF9leHRlbnNpb246fgohb3B0aW9uYWxfbmVzdGVkX21lc3NhZ2Vf", 
            "ZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lv", 
            "bnMYEiABKAsyLS5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVz", 
            "dGVkTWVzc2FnZTpzCiJvcHRpb25hbF9mb3JlaWduX21lc3NhZ2VfZXh0ZW5z", 
            "aW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYEyAB", 
            "KAsyIS5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduTWVzc2FnZTp4CiFvcHRp", 
            "b25hbF9pbXBvcnRfbWVzc2FnZV9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0", 
            "dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxgUIAEoCzInLnByb3RvYnVmX3VuaXR0", 
            "ZXN0X2ltcG9ydC5JbXBvcnRNZXNzYWdlOngKHm9wdGlvbmFsX25lc3RlZF9l", 
            "bnVtX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRl", 
            "bnNpb25zGBUgASgOMioucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVz", 
            "Lk5lc3RlZEVudW06bQofb3B0aW9uYWxfZm9yZWlnbl9lbnVtX2V4dGVuc2lv", 
            "bhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGBYgASgO", 
            "Mh4ucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW06cgoeb3B0aW9uYWxf", 
            "aW1wb3J0X2VudW1fZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVz", 
            "dEFsbEV4dGVuc2lvbnMYFyABKA4yJC5wcm90b2J1Zl91bml0dGVzdF9pbXBv", 
            "cnQuSW1wb3J0RW51bTpRCh9vcHRpb25hbF9zdHJpbmdfcGllY2VfZXh0ZW5z", 
            "aW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYGCAB", 
            "KAlCAggCOkkKF29wdGlvbmFsX2NvcmRfZXh0ZW5zaW9uEiQucHJvdG9idWZf", 
            "dW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYGSABKAlCAggBOoUBCihvcHRp", 
            "b25hbF9wdWJsaWNfaW1wb3J0X21lc3NhZ2VfZXh0ZW5zaW9uEiQucHJvdG9i", 
            "dWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYGiABKAsyLS5wcm90b2J1", 
            "Zl91bml0dGVzdF9pbXBvcnQuUHVibGljSW1wb3J0TWVzc2FnZTqAAQofb3B0", 
            "aW9uYWxfbGF6eV9tZXNzYWdlX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0", 
            "ZXN0LlRlc3RBbGxFeHRlbnNpb25zGBsgASgLMi0ucHJvdG9idWZfdW5pdHRl", 
            "c3QuVGVzdEFsbFR5cGVzLk5lc3RlZE1lc3NhZ2VCAigBOkYKGHJlcGVhdGVk", 
            "X2ludDMyX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxF", 
            "eHRlbnNpb25zGB8gAygFOkYKGHJlcGVhdGVkX2ludDY0X2V4dGVuc2lvbhIk", 
            "LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGCAgAygDOkcK", 
            "GXJlcGVhdGVkX3VpbnQzMl9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVz", 
            "dC5UZXN0QWxsRXh0ZW5zaW9ucxghIAMoDTpHChlyZXBlYXRlZF91aW50NjRf", 
            "ZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lv", 
            "bnMYIiADKAQ6RwoZcmVwZWF0ZWRfc2ludDMyX2V4dGVuc2lvbhIkLnByb3Rv", 
            "YnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGCMgAygROkcKGXJlcGVh", 
            "dGVkX3NpbnQ2NF9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0", 
            "QWxsRXh0ZW5zaW9ucxgkIAMoEjpIChpyZXBlYXRlZF9maXhlZDMyX2V4dGVu", 
            "c2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGCUg", 
            "AygHOkgKGnJlcGVhdGVkX2ZpeGVkNjRfZXh0ZW5zaW9uEiQucHJvdG9idWZf", 
            "dW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYJiADKAY6SQobcmVwZWF0ZWRf", 
            "c2ZpeGVkMzJfZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFs", 
            "bEV4dGVuc2lvbnMYJyADKA86SQobcmVwZWF0ZWRfc2ZpeGVkNjRfZXh0ZW5z", 
            "aW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYKCAD", 
            "KBA6RgoYcmVwZWF0ZWRfZmxvYXRfZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5p", 
            "dHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYKSADKAI6RwoZcmVwZWF0ZWRfZG91", 
            "YmxlX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRl", 
            "bnNpb25zGCogAygBOkUKF3JlcGVhdGVkX2Jvb2xfZXh0ZW5zaW9uEiQucHJv", 
            "dG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYKyADKAg6RwoZcmVw", 
            "ZWF0ZWRfc3RyaW5nX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRl", 
            "c3RBbGxFeHRlbnNpb25zGCwgAygJOkYKGHJlcGVhdGVkX2J5dGVzX2V4dGVu", 
            "c2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGC0g", 
            "AygMOnEKF3JlcGVhdGVkZ3JvdXBfZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5p", 
            "dHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYLiADKAoyKi5wcm90b2J1Zl91bml0", 
            "dGVzdC5SZXBlYXRlZEdyb3VwX2V4dGVuc2lvbjp+CiFyZXBlYXRlZF9uZXN0", 
            "ZWRfbWVzc2FnZV9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0", 
            "QWxsRXh0ZW5zaW9ucxgwIAMoCzItLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RB", 
            "bGxUeXBlcy5OZXN0ZWRNZXNzYWdlOnMKInJlcGVhdGVkX2ZvcmVpZ25fbWVz", 
            "c2FnZV9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0", 
            "ZW5zaW9ucxgxIAMoCzIhLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25NZXNz", 
            "YWdlOngKIXJlcGVhdGVkX2ltcG9ydF9tZXNzYWdlX2V4dGVuc2lvbhIkLnBy", 
            "b3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGDIgAygLMicucHJv", 
            "dG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydE1lc3NhZ2U6eAoecmVwZWF0", 
            "ZWRfbmVzdGVkX2VudW1fZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3Qu", 
            "VGVzdEFsbEV4dGVuc2lvbnMYMyADKA4yKi5wcm90b2J1Zl91bml0dGVzdC5U", 
            "ZXN0QWxsVHlwZXMuTmVzdGVkRW51bTptCh9yZXBlYXRlZF9mb3JlaWduX2Vu", 
            "dW1fZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVu", 
            "c2lvbnMYNCADKA4yHi5wcm90b2J1Zl91bml0dGVzdC5Gb3JlaWduRW51bTpy", 
            "Ch5yZXBlYXRlZF9pbXBvcnRfZW51bV9leHRlbnNpb24SJC5wcm90b2J1Zl91", 
            "bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxg1IAMoDjIkLnByb3RvYnVmX3Vu", 
            "aXR0ZXN0X2ltcG9ydC5JbXBvcnRFbnVtOlEKH3JlcGVhdGVkX3N0cmluZ19w", 
            "aWVjZV9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0", 
            "ZW5zaW9ucxg2IAMoCUICCAI6SQoXcmVwZWF0ZWRfY29yZF9leHRlbnNpb24S", 
            "JC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxg3IAMoCUIC", 
            "CAE6gAEKH3JlcGVhdGVkX2xhenlfbWVzc2FnZV9leHRlbnNpb24SJC5wcm90", 
            "b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxg5IAMoCzItLnByb3Rv", 
            "YnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlQgIoATpJ", 
            "ChdkZWZhdWx0X2ludDMyX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0", 
            "LlRlc3RBbGxFeHRlbnNpb25zGD0gASgFOgI0MTpJChdkZWZhdWx0X2ludDY0", 
            "X2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNp", 
            "b25zGD4gASgDOgI0MjpKChhkZWZhdWx0X3VpbnQzMl9leHRlbnNpb24SJC5w", 
            "cm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxg/IAEoDToCNDM6", 
            "SgoYZGVmYXVsdF91aW50NjRfZXh0ZW5zaW9uEiQucHJvdG9idWZfdW5pdHRl", 
            "c3QuVGVzdEFsbEV4dGVuc2lvbnMYQCABKAQ6AjQ0OksKGGRlZmF1bHRfc2lu", 
            "dDMyX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRl", 
            "bnNpb25zGEEgASgROgMtNDU6SgoYZGVmYXVsdF9zaW50NjRfZXh0ZW5zaW9u", 
            "EiQucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYQiABKBI6", 
            "AjQ2OksKGWRlZmF1bHRfZml4ZWQzMl9leHRlbnNpb24SJC5wcm90b2J1Zl91", 
            "bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxhDIAEoBzoCNDc6SwoZZGVmYXVs", 
            "dF9maXhlZDY0X2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RB", 
            "bGxFeHRlbnNpb25zGEQgASgGOgI0ODpMChpkZWZhdWx0X3NmaXhlZDMyX2V4", 
            "dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25z", 
            "GEUgASgPOgI0OTpNChpkZWZhdWx0X3NmaXhlZDY0X2V4dGVuc2lvbhIkLnBy", 
            "b3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGEYgASgQOgMtNTA6", 
            "SwoXZGVmYXVsdF9mbG9hdF9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVz", 
            "dC5UZXN0QWxsRXh0ZW5zaW9ucxhHIAEoAjoENTEuNTpNChhkZWZhdWx0X2Rv", 
            "dWJsZV9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0", 
            "ZW5zaW9ucxhIIAEoAToFNTIwMDA6SgoWZGVmYXVsdF9ib29sX2V4dGVuc2lv", 
            "bhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGEkgASgI", 
            "OgR0cnVlOk0KGGRlZmF1bHRfc3RyaW5nX2V4dGVuc2lvbhIkLnByb3RvYnVm", 
            "X3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGEogASgJOgVoZWxsbzpMChdk", 
            "ZWZhdWx0X2J5dGVzX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRl", 
            "c3RBbGxFeHRlbnNpb25zGEsgASgMOgV3b3JsZDp8Ch1kZWZhdWx0X25lc3Rl", 
            "ZF9lbnVtX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxF", 
            "eHRlbnNpb25zGFEgASgOMioucHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5", 
            "cGVzLk5lc3RlZEVudW06A0JBUjp5Ch5kZWZhdWx0X2ZvcmVpZ25fZW51bV9l", 
            "eHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9u", 
            "cxhSIAEoDjIeLnByb3RvYnVmX3VuaXR0ZXN0LkZvcmVpZ25FbnVtOgtGT1JF", 
            "SUdOX0JBUjp9Ch1kZWZhdWx0X2ltcG9ydF9lbnVtX2V4dGVuc2lvbhIkLnBy", 
            "b3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxFeHRlbnNpb25zGFMgASgOMiQucHJv", 
            "dG9idWZfdW5pdHRlc3RfaW1wb3J0LkltcG9ydEVudW06CklNUE9SVF9CQVI6", 
            "VQoeZGVmYXVsdF9zdHJpbmdfcGllY2VfZXh0ZW5zaW9uEiQucHJvdG9idWZf", 
            "dW5pdHRlc3QuVGVzdEFsbEV4dGVuc2lvbnMYVCABKAk6A2FiY0ICCAI6TQoW", 
            "ZGVmYXVsdF9jb3JkX2V4dGVuc2lvbhIkLnByb3RvYnVmX3VuaXR0ZXN0LlRl", 
            "c3RBbGxFeHRlbnNpb25zGFUgASgJOgMxMjNCAggBOkQKFm9uZW9mX3VpbnQz", 
            "Ml9leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5z", 
            "aW9ucxhvIAEoDTp7Ch5vbmVvZl9uZXN0ZWRfbWVzc2FnZV9leHRlbnNpb24S", 
            "JC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxhwIAEoCzIt", 
            "LnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdl", 
            "OkQKFm9uZW9mX3N0cmluZ19leHRlbnNpb24SJC5wcm90b2J1Zl91bml0dGVz", 
            "dC5UZXN0QWxsRXh0ZW5zaW9ucxhxIAEoCTpDChVvbmVvZl9ieXRlc19leHRl", 
            "bnNpb24SJC5wcm90b2J1Zl91bml0dGVzdC5UZXN0QWxsRXh0ZW5zaW9ucxhy", 
            "IAEoDDpCChNteV9leHRlbnNpb25fc3RyaW5nEiUucHJvdG9idWZfdW5pdHRl", 
            "c3QuVGVzdEZpZWxkT3JkZXJpbmdzGDIgASgJOj8KEG15X2V4dGVuc2lvbl9p", 
            "bnQSJS5wcm90b2J1Zl91bml0dGVzdC5UZXN0RmllbGRPcmRlcmluZ3MYBSAB", 
            "KAU6SwoWcGFja2VkX2ludDMyX2V4dGVuc2lvbhInLnByb3RvYnVmX3VuaXR0", 
            "ZXN0LlRlc3RQYWNrZWRFeHRlbnNpb25zGFogAygFQgIQATpLChZwYWNrZWRf", 
            "aW50NjRfZXh0ZW5zaW9uEicucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tl", 
            "ZEV4dGVuc2lvbnMYWyADKANCAhABOkwKF3BhY2tlZF91aW50MzJfZXh0ZW5z", 
            "aW9uEicucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZEV4dGVuc2lvbnMY", 
            "XCADKA1CAhABOkwKF3BhY2tlZF91aW50NjRfZXh0ZW5zaW9uEicucHJvdG9i", 
            "dWZfdW5pdHRlc3QuVGVzdFBhY2tlZEV4dGVuc2lvbnMYXSADKARCAhABOkwK", 
            "F3BhY2tlZF9zaW50MzJfZXh0ZW5zaW9uEicucHJvdG9idWZfdW5pdHRlc3Qu", 
            "VGVzdFBhY2tlZEV4dGVuc2lvbnMYXiADKBFCAhABOkwKF3BhY2tlZF9zaW50", 
            "NjRfZXh0ZW5zaW9uEicucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tlZEV4", 
            "dGVuc2lvbnMYXyADKBJCAhABOk0KGHBhY2tlZF9maXhlZDMyX2V4dGVuc2lv", 
            "bhInLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRFeHRlbnNpb25zGGAg", 
            "AygHQgIQATpNChhwYWNrZWRfZml4ZWQ2NF9leHRlbnNpb24SJy5wcm90b2J1", 
            "Zl91bml0dGVzdC5UZXN0UGFja2VkRXh0ZW5zaW9ucxhhIAMoBkICEAE6TgoZ", 
            "cGFja2VkX3NmaXhlZDMyX2V4dGVuc2lvbhInLnByb3RvYnVmX3VuaXR0ZXN0", 
            "LlRlc3RQYWNrZWRFeHRlbnNpb25zGGIgAygPQgIQATpOChlwYWNrZWRfc2Zp", 
            "eGVkNjRfZXh0ZW5zaW9uEicucHJvdG9idWZfdW5pdHRlc3QuVGVzdFBhY2tl", 
            "ZEV4dGVuc2lvbnMYYyADKBBCAhABOksKFnBhY2tlZF9mbG9hdF9leHRlbnNp", 
            "b24SJy5wcm90b2J1Zl91bml0dGVzdC5UZXN0UGFja2VkRXh0ZW5zaW9ucxhk", 
            "IAMoAkICEAE6TAoXcGFja2VkX2RvdWJsZV9leHRlbnNpb24SJy5wcm90b2J1", 
            "Zl91bml0dGVzdC5UZXN0UGFja2VkRXh0ZW5zaW9ucxhlIAMoAUICEAE6SgoV", 
            "cGFja2VkX2Jvb2xfZXh0ZW5zaW9uEicucHJvdG9idWZfdW5pdHRlc3QuVGVz", 
            "dFBhY2tlZEV4dGVuc2lvbnMYZiADKAhCAhABOmoKFXBhY2tlZF9lbnVtX2V4", 
            "dGVuc2lvbhInLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQYWNrZWRFeHRlbnNp", 
            "b25zGGcgAygOMh4ucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbkVudW1CAhAB", 
            "Ok8KGHVucGFja2VkX2ludDMyX2V4dGVuc2lvbhIpLnByb3RvYnVmX3VuaXR0", 
            "ZXN0LlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMYWiADKAVCAhAAOk8KGHVucGFj", 
            "a2VkX2ludDY0X2V4dGVuc2lvbhIpLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RV", 
            "bnBhY2tlZEV4dGVuc2lvbnMYWyADKANCAhAAOlAKGXVucGFja2VkX3VpbnQz", 
            "Ml9leHRlbnNpb24SKS5wcm90b2J1Zl91bml0dGVzdC5UZXN0VW5wYWNrZWRF", 
            "eHRlbnNpb25zGFwgAygNQgIQADpQChl1bnBhY2tlZF91aW50NjRfZXh0ZW5z", 
            "aW9uEikucHJvdG9idWZfdW5pdHRlc3QuVGVzdFVucGFja2VkRXh0ZW5zaW9u", 
            "cxhdIAMoBEICEAA6UAoZdW5wYWNrZWRfc2ludDMyX2V4dGVuc2lvbhIpLnBy", 
            "b3RvYnVmX3VuaXR0ZXN0LlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMYXiADKBFC", 
            "AhAAOlAKGXVucGFja2VkX3NpbnQ2NF9leHRlbnNpb24SKS5wcm90b2J1Zl91", 
            "bml0dGVzdC5UZXN0VW5wYWNrZWRFeHRlbnNpb25zGF8gAygSQgIQADpRChp1", 
            "bnBhY2tlZF9maXhlZDMyX2V4dGVuc2lvbhIpLnByb3RvYnVmX3VuaXR0ZXN0", 
            "LlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMYYCADKAdCAhAAOlEKGnVucGFja2Vk", 
            "X2ZpeGVkNjRfZXh0ZW5zaW9uEikucHJvdG9idWZfdW5pdHRlc3QuVGVzdFVu", 
            "cGFja2VkRXh0ZW5zaW9ucxhhIAMoBkICEAA6UgobdW5wYWNrZWRfc2ZpeGVk", 
            "MzJfZXh0ZW5zaW9uEikucHJvdG9idWZfdW5pdHRlc3QuVGVzdFVucGFja2Vk", 
            "RXh0ZW5zaW9ucxhiIAMoD0ICEAA6UgobdW5wYWNrZWRfc2ZpeGVkNjRfZXh0", 
            "ZW5zaW9uEikucHJvdG9idWZfdW5pdHRlc3QuVGVzdFVucGFja2VkRXh0ZW5z", 
            "aW9ucxhjIAMoEEICEAA6TwoYdW5wYWNrZWRfZmxvYXRfZXh0ZW5zaW9uEiku", 
            "cHJvdG9idWZfdW5pdHRlc3QuVGVzdFVucGFja2VkRXh0ZW5zaW9ucxhkIAMo", 
            "AkICEAA6UAoZdW5wYWNrZWRfZG91YmxlX2V4dGVuc2lvbhIpLnByb3RvYnVm", 
            "X3VuaXR0ZXN0LlRlc3RVbnBhY2tlZEV4dGVuc2lvbnMYZSADKAFCAhAAOk4K", 
            "F3VucGFja2VkX2Jvb2xfZXh0ZW5zaW9uEikucHJvdG9idWZfdW5pdHRlc3Qu", 
            "VGVzdFVucGFja2VkRXh0ZW5zaW9ucxhmIAMoCEICEAA6bgoXdW5wYWNrZWRf", 
            "ZW51bV9leHRlbnNpb24SKS5wcm90b2J1Zl91bml0dGVzdC5UZXN0VW5wYWNr", 
            "ZWRFeHRlbnNpb25zGGcgAygOMh4ucHJvdG9idWZfdW5pdHRlc3QuRm9yZWln", 
            "bkVudW1CAhAAQkFCDVVuaXR0ZXN0UHJvdG9IAYABAYgBAZABAfgBAaoCIUdv", 
          "b2dsZS5Qcm90b2NvbEJ1ZmZlcnMuVGVzdFByb3Rvcw=="));
      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", "OptionalPublicImportMessage", "OptionalLazyMessage", "RepeatedInt32", "RepeatedInt64", "RepeatedUint32", "RepeatedUint64", "RepeatedSint32", "RepeatedSint64", "RepeatedFixed32", "RepeatedFixed64", "RepeatedSfixed32", "RepeatedSfixed64", "RepeatedFloat", "RepeatedDouble", "RepeatedBool", "RepeatedString", "RepeatedBytes", "RepeatedGroup", "RepeatedNestedMessage", "RepeatedForeignMessage", "RepeatedImportMessage", "RepeatedNestedEnum", "RepeatedForeignEnum", "RepeatedImportEnum", "RepeatedStringPiece", "RepeatedCord", "RepeatedLazyMessage", "DefaultInt32", "DefaultInt64", "DefaultUint32", "DefaultUint64", "DefaultSint32", "DefaultSint64", "DefaultFixed32", "DefaultFixed64", "DefaultSfixed32", "DefaultSfixed64", "DefaultFloat", "DefaultDouble", "DefaultBool", "DefaultString", "DefaultBytes", "DefaultNestedEnum", "DefaultForeignEnum", "DefaultImportEnum", "DefaultStringPiece", "DefaultCord", "OneofUint32", "OneofNestedMessage", "OneofString", "OneofBytes", });
        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_NestedTestAllTypes__Descriptor = Descriptor.MessageTypes[1];
        internal__static_protobuf_unittest_NestedTestAllTypes__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.NestedTestAllTypes, global::Google.ProtocolBuffers.TestProtos.NestedTestAllTypes.Builder>(internal__static_protobuf_unittest_NestedTestAllTypes__Descriptor,
                new string[] { "Child", "Payload", });
        internal__static_protobuf_unittest_TestDeprecatedFields__Descriptor = Descriptor.MessageTypes[2];
        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[3];
        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[4];
        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[5];
        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[6];
        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[7];
        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]);
        global::Google.ProtocolBuffers.TestProtos.TestNestedExtension.NestedStringExtension = pb::GeneratedSingleExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.TestNestedExtension.Descriptor.Extensions[1]);
        internal__static_protobuf_unittest_TestRequired__Descriptor = Descriptor.MessageTypes[8];
        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[9];
        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[10];
        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[11];
        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[12];
        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[13];
        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[14];
        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[15];
        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[16];
        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[17];
        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[18];
        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_TestEagerMessage__Descriptor = Descriptor.MessageTypes[19];
        internal__static_protobuf_unittest_TestEagerMessage__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestEagerMessage, global::Google.ProtocolBuffers.TestProtos.TestEagerMessage.Builder>(internal__static_protobuf_unittest_TestEagerMessage__Descriptor,
                new string[] { "SubMessage", });
        internal__static_protobuf_unittest_TestLazyMessage__Descriptor = Descriptor.MessageTypes[20];
        internal__static_protobuf_unittest_TestLazyMessage__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestLazyMessage, global::Google.ProtocolBuffers.TestProtos.TestLazyMessage.Builder>(internal__static_protobuf_unittest_TestLazyMessage__Descriptor,
                new string[] { "SubMessage", });
        internal__static_protobuf_unittest_TestNestedMessageHasBits__Descriptor = Descriptor.MessageTypes[21];
        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[22];
        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[23];
        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", "OptionalNestedMessage", });
        internal__static_protobuf_unittest_TestFieldOrderings_NestedMessage__Descriptor = internal__static_protobuf_unittest_TestFieldOrderings__Descriptor.NestedTypes[0];
        internal__static_protobuf_unittest_TestFieldOrderings_NestedMessage__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestFieldOrderings.Types.NestedMessage, global::Google.ProtocolBuffers.TestProtos.TestFieldOrderings.Types.NestedMessage.Builder>(internal__static_protobuf_unittest_TestFieldOrderings_NestedMessage__Descriptor,
                new string[] { "Oo", "Bb", });
        internal__static_protobuf_unittest_TestExtremeDefaultValues__Descriptor = Descriptor.MessageTypes[24];
        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", "ReallySmallInt32", "ReallySmallInt64", "Utf8String", "ZeroFloat", "OneFloat", "SmallFloat", "NegativeOneFloat", "NegativeFloat", "LargeFloat", "SmallNegativeFloat", "InfDouble", "NegInfDouble", "NanDouble", "InfFloat", "NegInfFloat", "NanFloat", "CppTrigraph", "StringWithZero", "BytesWithZero", "StringPieceWithZero", "CordWithZero", "ReplacementString", });
        internal__static_protobuf_unittest_SparseEnumMessage__Descriptor = Descriptor.MessageTypes[25];
        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[26];
        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_MoreString__Descriptor = Descriptor.MessageTypes[27];
        internal__static_protobuf_unittest_MoreString__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.MoreString, global::Google.ProtocolBuffers.TestProtos.MoreString.Builder>(internal__static_protobuf_unittest_MoreString__Descriptor,
                new string[] { "Data", });
        internal__static_protobuf_unittest_OneBytes__Descriptor = Descriptor.MessageTypes[28];
        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_MoreBytes__Descriptor = Descriptor.MessageTypes[29];
        internal__static_protobuf_unittest_MoreBytes__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.MoreBytes, global::Google.ProtocolBuffers.TestProtos.MoreBytes.Builder>(internal__static_protobuf_unittest_MoreBytes__Descriptor,
                new string[] { "Data", });
        internal__static_protobuf_unittest_Int32Message__Descriptor = Descriptor.MessageTypes[30];
        internal__static_protobuf_unittest_Int32Message__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.Int32Message, global::Google.ProtocolBuffers.TestProtos.Int32Message.Builder>(internal__static_protobuf_unittest_Int32Message__Descriptor,
                new string[] { "Data", });
        internal__static_protobuf_unittest_Uint32Message__Descriptor = Descriptor.MessageTypes[31];
        internal__static_protobuf_unittest_Uint32Message__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.Uint32Message, global::Google.ProtocolBuffers.TestProtos.Uint32Message.Builder>(internal__static_protobuf_unittest_Uint32Message__Descriptor,
                new string[] { "Data", });
        internal__static_protobuf_unittest_Int64Message__Descriptor = Descriptor.MessageTypes[32];
        internal__static_protobuf_unittest_Int64Message__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.Int64Message, global::Google.ProtocolBuffers.TestProtos.Int64Message.Builder>(internal__static_protobuf_unittest_Int64Message__Descriptor,
                new string[] { "Data", });
        internal__static_protobuf_unittest_Uint64Message__Descriptor = Descriptor.MessageTypes[33];
        internal__static_protobuf_unittest_Uint64Message__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.Uint64Message, global::Google.ProtocolBuffers.TestProtos.Uint64Message.Builder>(internal__static_protobuf_unittest_Uint64Message__Descriptor,
                new string[] { "Data", });
        internal__static_protobuf_unittest_BoolMessage__Descriptor = Descriptor.MessageTypes[34];
        internal__static_protobuf_unittest_BoolMessage__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.BoolMessage, global::Google.ProtocolBuffers.TestProtos.BoolMessage.Builder>(internal__static_protobuf_unittest_BoolMessage__Descriptor,
                new string[] { "Data", });
        internal__static_protobuf_unittest_TestOneof__Descriptor = Descriptor.MessageTypes[35];
        internal__static_protobuf_unittest_TestOneof__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestOneof, global::Google.ProtocolBuffers.TestProtos.TestOneof.Builder>(internal__static_protobuf_unittest_TestOneof__Descriptor,
                new string[] { "FooInt", "FooString", "FooMessage", "FooGroup", });
        internal__static_protobuf_unittest_TestOneof_FooGroup__Descriptor = internal__static_protobuf_unittest_TestOneof__Descriptor.NestedTypes[0];
        internal__static_protobuf_unittest_TestOneof_FooGroup__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestOneof.Types.FooGroup, global::Google.ProtocolBuffers.TestProtos.TestOneof.Types.FooGroup.Builder>(internal__static_protobuf_unittest_TestOneof_FooGroup__Descriptor,
                new string[] { "A", "B", });
        internal__static_protobuf_unittest_TestOneofBackwardsCompatible__Descriptor = Descriptor.MessageTypes[36];
        internal__static_protobuf_unittest_TestOneofBackwardsCompatible__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestOneofBackwardsCompatible, global::Google.ProtocolBuffers.TestProtos.TestOneofBackwardsCompatible.Builder>(internal__static_protobuf_unittest_TestOneofBackwardsCompatible__Descriptor,
                new string[] { "FooInt", "FooString", "FooMessage", "FooGroup", });
        internal__static_protobuf_unittest_TestOneofBackwardsCompatible_FooGroup__Descriptor = internal__static_protobuf_unittest_TestOneofBackwardsCompatible__Descriptor.NestedTypes[0];
        internal__static_protobuf_unittest_TestOneofBackwardsCompatible_FooGroup__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestOneofBackwardsCompatible.Types.FooGroup, global::Google.ProtocolBuffers.TestProtos.TestOneofBackwardsCompatible.Types.FooGroup.Builder>(internal__static_protobuf_unittest_TestOneofBackwardsCompatible_FooGroup__Descriptor,
                new string[] { "A", "B", });
        internal__static_protobuf_unittest_TestOneof2__Descriptor = Descriptor.MessageTypes[37];
        internal__static_protobuf_unittest_TestOneof2__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestOneof2, global::Google.ProtocolBuffers.TestProtos.TestOneof2.Builder>(internal__static_protobuf_unittest_TestOneof2__Descriptor,
                new string[] { "FooInt", "FooString", "FooCord", "FooStringPiece", "FooBytes", "FooEnum", "FooMessage", "FooGroup", "FooLazyMessage", "BarInt", "BarString", "BarCord", "BarStringPiece", "BarBytes", "BarEnum", "BazInt", "BazString", });
        internal__static_protobuf_unittest_TestOneof2_FooGroup__Descriptor = internal__static_protobuf_unittest_TestOneof2__Descriptor.NestedTypes[0];
        internal__static_protobuf_unittest_TestOneof2_FooGroup__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.FooGroup, global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.FooGroup.Builder>(internal__static_protobuf_unittest_TestOneof2_FooGroup__Descriptor,
                new string[] { "A", "B", });
        internal__static_protobuf_unittest_TestOneof2_NestedMessage__Descriptor = internal__static_protobuf_unittest_TestOneof2__Descriptor.NestedTypes[1];
        internal__static_protobuf_unittest_TestOneof2_NestedMessage__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage, global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage.Builder>(internal__static_protobuf_unittest_TestOneof2_NestedMessage__Descriptor,
                new string[] { "QuxInt", "CorgeInt", });
        internal__static_protobuf_unittest_TestRequiredOneof__Descriptor = Descriptor.MessageTypes[38];
        internal__static_protobuf_unittest_TestRequiredOneof__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof, global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.Builder>(internal__static_protobuf_unittest_TestRequiredOneof__Descriptor,
                new string[] { "FooInt", "FooString", "FooMessage", });
        internal__static_protobuf_unittest_TestRequiredOneof_NestedMessage__Descriptor = internal__static_protobuf_unittest_TestRequiredOneof__Descriptor.NestedTypes[0];
        internal__static_protobuf_unittest_TestRequiredOneof_NestedMessage__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.Types.NestedMessage, global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.Types.NestedMessage.Builder>(internal__static_protobuf_unittest_TestRequiredOneof_NestedMessage__Descriptor,
                new string[] { "RequiredDouble", });
        internal__static_protobuf_unittest_TestPackedTypes__Descriptor = Descriptor.MessageTypes[39];
        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[40];
        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[41];
        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_TestUnpackedExtensions__Descriptor = Descriptor.MessageTypes[42];
        internal__static_protobuf_unittest_TestUnpackedExtensions__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestUnpackedExtensions, global::Google.ProtocolBuffers.TestProtos.TestUnpackedExtensions.Builder>(internal__static_protobuf_unittest_TestUnpackedExtensions__Descriptor,
                new string[] { });
        internal__static_protobuf_unittest_TestDynamicExtensions__Descriptor = Descriptor.MessageTypes[43];
        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[44];
        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_TestParsingMerge__Descriptor = Descriptor.MessageTypes[45];
        internal__static_protobuf_unittest_TestParsingMerge__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge, global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Builder>(internal__static_protobuf_unittest_TestParsingMerge__Descriptor,
                new string[] { "RequiredAllTypes", "OptionalAllTypes", "RepeatedAllTypes", "OptionalGroup", "RepeatedGroup", });
        internal__static_protobuf_unittest_TestParsingMerge_RepeatedFieldsGenerator__Descriptor = internal__static_protobuf_unittest_TestParsingMerge__Descriptor.NestedTypes[0];
        internal__static_protobuf_unittest_TestParsingMerge_RepeatedFieldsGenerator__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator, global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Builder>(internal__static_protobuf_unittest_TestParsingMerge_RepeatedFieldsGenerator__Descriptor,
                new string[] { "Field1", "Field2", "Field3", "Group1", "Group2", "Ext1", "Ext2", });
        internal__static_protobuf_unittest_TestParsingMerge_RepeatedFieldsGenerator_Group1__Descriptor = internal__static_protobuf_unittest_TestParsingMerge_RepeatedFieldsGenerator__Descriptor.NestedTypes[0];
        internal__static_protobuf_unittest_TestParsingMerge_RepeatedFieldsGenerator_Group1__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group1, global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group1.Builder>(internal__static_protobuf_unittest_TestParsingMerge_RepeatedFieldsGenerator_Group1__Descriptor,
                new string[] { "Field1", });
        internal__static_protobuf_unittest_TestParsingMerge_RepeatedFieldsGenerator_Group2__Descriptor = internal__static_protobuf_unittest_TestParsingMerge_RepeatedFieldsGenerator__Descriptor.NestedTypes[1];
        internal__static_protobuf_unittest_TestParsingMerge_RepeatedFieldsGenerator_Group2__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group2, global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group2.Builder>(internal__static_protobuf_unittest_TestParsingMerge_RepeatedFieldsGenerator_Group2__Descriptor,
                new string[] { "Field1", });
        internal__static_protobuf_unittest_TestParsingMerge_OptionalGroup__Descriptor = internal__static_protobuf_unittest_TestParsingMerge__Descriptor.NestedTypes[1];
        internal__static_protobuf_unittest_TestParsingMerge_OptionalGroup__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.OptionalGroup, global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.OptionalGroup.Builder>(internal__static_protobuf_unittest_TestParsingMerge_OptionalGroup__Descriptor,
                new string[] { "OptionalGroupAllTypes", });
        internal__static_protobuf_unittest_TestParsingMerge_RepeatedGroup__Descriptor = internal__static_protobuf_unittest_TestParsingMerge__Descriptor.NestedTypes[2];
        internal__static_protobuf_unittest_TestParsingMerge_RepeatedGroup__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedGroup, global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedGroup.Builder>(internal__static_protobuf_unittest_TestParsingMerge_RepeatedGroup__Descriptor,
                new string[] { "RepeatedGroupAllTypes", });
        global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.OptionalExt = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.TestAllTypes>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Descriptor.Extensions[0]);
        global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.RepeatedExt = pb::GeneratedRepeatExtension<global::Google.ProtocolBuffers.TestProtos.TestAllTypes>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Descriptor.Extensions[1]);
        internal__static_protobuf_unittest_TestCommentInjectionMessage__Descriptor = Descriptor.MessageTypes[46];
        internal__static_protobuf_unittest_TestCommentInjectionMessage__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestCommentInjectionMessage, global::Google.ProtocolBuffers.TestProtos.TestCommentInjectionMessage.Builder>(internal__static_protobuf_unittest_TestCommentInjectionMessage__Descriptor,
                new string[] { "A", });
        internal__static_protobuf_unittest_FooRequest__Descriptor = Descriptor.MessageTypes[47];
        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[48];
        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_FooClientMessage__Descriptor = Descriptor.MessageTypes[49];
        internal__static_protobuf_unittest_FooClientMessage__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.FooClientMessage, global::Google.ProtocolBuffers.TestProtos.FooClientMessage.Builder>(internal__static_protobuf_unittest_FooClientMessage__Descriptor,
                new string[] { });
        internal__static_protobuf_unittest_FooServerMessage__Descriptor = Descriptor.MessageTypes[50];
        internal__static_protobuf_unittest_FooServerMessage__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.FooServerMessage, global::Google.ProtocolBuffers.TestProtos.FooServerMessage.Builder>(internal__static_protobuf_unittest_FooServerMessage__Descriptor,
                new string[] { });
        internal__static_protobuf_unittest_BarRequest__Descriptor = Descriptor.MessageTypes[51];
        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[52];
        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.Unittest.OptionalInt32Extension = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[0]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalInt64Extension = pb::GeneratedSingleExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[1]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalUint32Extension = pb::GeneratedSingleExtension<uint>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[2]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalUint64Extension = pb::GeneratedSingleExtension<ulong>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[3]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalSint32Extension = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[4]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalSint64Extension = pb::GeneratedSingleExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[5]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalFixed32Extension = pb::GeneratedSingleExtension<uint>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[6]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalFixed64Extension = pb::GeneratedSingleExtension<ulong>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[7]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalSfixed32Extension = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[8]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalSfixed64Extension = pb::GeneratedSingleExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[9]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalFloatExtension = pb::GeneratedSingleExtension<float>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[10]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalDoubleExtension = pb::GeneratedSingleExtension<double>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[11]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalBoolExtension = pb::GeneratedSingleExtension<bool>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[12]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalStringExtension = pb::GeneratedSingleExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[13]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalBytesExtension = pb::GeneratedSingleExtension<pb::ByteString>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[14]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalGroupExtension = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.OptionalGroup_extension>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[15]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalNestedMessageExtension = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[16]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalForeignMessageExtension = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.ForeignMessage>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[17]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalImportMessageExtension = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.ImportMessage>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[18]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalNestedEnumExtension = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[19]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalForeignEnumExtension = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[20]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalImportEnumExtension = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.ImportEnum>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[21]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalStringPieceExtension = pb::GeneratedSingleExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[22]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalCordExtension = pb::GeneratedSingleExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[23]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalPublicImportMessageExtension = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.PublicImportMessage>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[24]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OptionalLazyMessageExtension = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[25]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedInt32Extension = pb::GeneratedRepeatExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[26]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedInt64Extension = pb::GeneratedRepeatExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[27]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedUint32Extension = pb::GeneratedRepeatExtension<uint>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[28]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedUint64Extension = pb::GeneratedRepeatExtension<ulong>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[29]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedSint32Extension = pb::GeneratedRepeatExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[30]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedSint64Extension = pb::GeneratedRepeatExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[31]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedFixed32Extension = pb::GeneratedRepeatExtension<uint>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[32]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedFixed64Extension = pb::GeneratedRepeatExtension<ulong>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[33]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedSfixed32Extension = pb::GeneratedRepeatExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[34]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedSfixed64Extension = pb::GeneratedRepeatExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[35]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedFloatExtension = pb::GeneratedRepeatExtension<float>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[36]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedDoubleExtension = pb::GeneratedRepeatExtension<double>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[37]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedBoolExtension = pb::GeneratedRepeatExtension<bool>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[38]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedStringExtension = pb::GeneratedRepeatExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[39]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedBytesExtension = pb::GeneratedRepeatExtension<pb::ByteString>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[40]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedGroupExtension = pb::GeneratedRepeatExtension<global::Google.ProtocolBuffers.TestProtos.RepeatedGroup_extension>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[41]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedNestedMessageExtension = pb::GeneratedRepeatExtension<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[42]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedForeignMessageExtension = pb::GeneratedRepeatExtension<global::Google.ProtocolBuffers.TestProtos.ForeignMessage>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[43]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedImportMessageExtension = pb::GeneratedRepeatExtension<global::Google.ProtocolBuffers.TestProtos.ImportMessage>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[44]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedNestedEnumExtension = pb::GeneratedRepeatExtension<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[45]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedForeignEnumExtension = pb::GeneratedRepeatExtension<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[46]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedImportEnumExtension = pb::GeneratedRepeatExtension<global::Google.ProtocolBuffers.TestProtos.ImportEnum>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[47]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedStringPieceExtension = pb::GeneratedRepeatExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[48]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedCordExtension = pb::GeneratedRepeatExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[49]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RepeatedLazyMessageExtension = pb::GeneratedRepeatExtension<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[50]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultInt32Extension = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[51]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultInt64Extension = pb::GeneratedSingleExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[52]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultUint32Extension = pb::GeneratedSingleExtension<uint>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[53]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultUint64Extension = pb::GeneratedSingleExtension<ulong>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[54]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultSint32Extension = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[55]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultSint64Extension = pb::GeneratedSingleExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[56]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultFixed32Extension = pb::GeneratedSingleExtension<uint>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[57]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultFixed64Extension = pb::GeneratedSingleExtension<ulong>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[58]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultSfixed32Extension = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[59]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultSfixed64Extension = pb::GeneratedSingleExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[60]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultFloatExtension = pb::GeneratedSingleExtension<float>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[61]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultDoubleExtension = pb::GeneratedSingleExtension<double>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[62]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultBoolExtension = pb::GeneratedSingleExtension<bool>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[63]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultStringExtension = pb::GeneratedSingleExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[64]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultBytesExtension = pb::GeneratedSingleExtension<pb::ByteString>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[65]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultNestedEnumExtension = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[66]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultForeignEnumExtension = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[67]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultImportEnumExtension = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.ImportEnum>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[68]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultStringPieceExtension = pb::GeneratedSingleExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[69]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.DefaultCordExtension = pb::GeneratedSingleExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[70]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OneofUint32Extension = pb::GeneratedSingleExtension<uint>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[71]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OneofNestedMessageExtension = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[72]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OneofStringExtension = pb::GeneratedSingleExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[73]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.OneofBytesExtension = pb::GeneratedSingleExtension<pb::ByteString>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[74]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.MyExtensionString = pb::GeneratedSingleExtension<string>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[75]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.MyExtensionInt = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[76]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.PackedInt32Extension = pb::GeneratedRepeatExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[77]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.PackedInt64Extension = pb::GeneratedRepeatExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[78]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.PackedUint32Extension = pb::GeneratedRepeatExtension<uint>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[79]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.PackedUint64Extension = pb::GeneratedRepeatExtension<ulong>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[80]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.PackedSint32Extension = pb::GeneratedRepeatExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[81]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.PackedSint64Extension = pb::GeneratedRepeatExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[82]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.PackedFixed32Extension = pb::GeneratedRepeatExtension<uint>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[83]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.PackedFixed64Extension = pb::GeneratedRepeatExtension<ulong>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[84]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.PackedSfixed32Extension = pb::GeneratedRepeatExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[85]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.PackedSfixed64Extension = pb::GeneratedRepeatExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[86]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.PackedFloatExtension = pb::GeneratedRepeatExtension<float>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[87]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.PackedDoubleExtension = pb::GeneratedRepeatExtension<double>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[88]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.PackedBoolExtension = pb::GeneratedRepeatExtension<bool>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[89]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.PackedEnumExtension = pb::GeneratedRepeatExtension<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[90]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedInt32Extension = pb::GeneratedRepeatExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[91]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedInt64Extension = pb::GeneratedRepeatExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[92]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedUint32Extension = pb::GeneratedRepeatExtension<uint>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[93]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedUint64Extension = pb::GeneratedRepeatExtension<ulong>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[94]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedSint32Extension = pb::GeneratedRepeatExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[95]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedSint64Extension = pb::GeneratedRepeatExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[96]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedFixed32Extension = pb::GeneratedRepeatExtension<uint>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[97]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedFixed64Extension = pb::GeneratedRepeatExtension<ulong>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[98]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedSfixed32Extension = pb::GeneratedRepeatExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[99]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedSfixed64Extension = pb::GeneratedRepeatExtension<long>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[100]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedFloatExtension = pb::GeneratedRepeatExtension<float>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[101]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedDoubleExtension = pb::GeneratedRepeatExtension<double>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[102]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedBoolExtension = pb::GeneratedRepeatExtension<bool>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[103]);
        global::Google.ProtocolBuffers.TestProtos.Unittest.UnpackedEnumExtension = pb::GeneratedRepeatExtension<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor.Extensions[104]);
        pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();
        RegisterAllExtensions(registry);
        global::Google.ProtocolBuffers.TestProtos.UnittestImport.RegisterAllExtensions(registry);
        return registry;
      };
      pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
          new pbd::FileDescriptor[] {
          global::Google.ProtocolBuffers.TestProtos.UnittestImport.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", "oneof_bytes", "oneof_nested_message", "oneof_string", "oneof_uint32", "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_lazy_message", "optional_nested_enum", "optional_nested_message", "optional_public_import_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_lazy_message", "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, 914, 898, 906, 888, 104, 122, 202, 97, 61, 65, 93, 176, 154, 184, 162, 8, 16, 218, 168, 146, 210, 77, 81, 40, 48, 114, 194, 24, 32, 131, 344, 362, 442, 337, 301, 305, 333, 416, 394, 424, 402, 248, 256, 458, 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.Unittest.internal__static_protobuf_unittest_TestAllTypes__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestAllTypes, TestAllTypes.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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,
        NEG = -1,
      }

      [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.Unittest.internal__static_protobuf_unittest_TestAllTypes_NestedMessage__Descriptor; }
        }

        protected override pb::FieldAccess.FieldAccessorTable<NestedMessage, NestedMessage.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_TestAllTypes_OptionalGroup__Descriptor; }
        }

        protected override pb::FieldAccess.FieldAccessorTable<OptionalGroup, OptionalGroup.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_TestAllTypes_RepeatedGroup__Descriptor; }
        }

        protected override pb::FieldAccess.FieldAccessorTable<RepeatedGroup, RepeatedGroup.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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 OptionalPublicImportMessageFieldNumber = 26;
    private bool hasOptionalPublicImportMessage;
    private global::Google.ProtocolBuffers.TestProtos.PublicImportMessage optionalPublicImportMessage_;
    public bool HasOptionalPublicImportMessage {
      get { return hasOptionalPublicImportMessage; }
    }
    public global::Google.ProtocolBuffers.TestProtos.PublicImportMessage OptionalPublicImportMessage {
      get { return optionalPublicImportMessage_ ?? global::Google.ProtocolBuffers.TestProtos.PublicImportMessage.DefaultInstance; }
    }

    public const int OptionalLazyMessageFieldNumber = 27;
    private bool hasOptionalLazyMessage;
    private global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage optionalLazyMessage_;
    public bool HasOptionalLazyMessage {
      get { return hasOptionalLazyMessage; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage OptionalLazyMessage {
      get { return optionalLazyMessage_ ?? global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.DefaultInstance; }
    }

    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 RepeatedLazyMessageFieldNumber = 57;
    private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage> repeatedLazyMessage_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage>();
    public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage> RepeatedLazyMessageList {
      get { return repeatedLazyMessage_; }
    }
    public int RepeatedLazyMessageCount {
      get { return repeatedLazyMessage_.Count; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage GetRepeatedLazyMessage(int index) {
      return repeatedLazyMessage_[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_ = 46L;
    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_ = 48UL;
    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_ = -50L;
    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[65].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 const int OneofUint32FieldNumber = 111;
    private bool hasOneofUint32;
    private uint oneofUint32_;
    public bool HasOneofUint32 {
      get { return hasOneofUint32; }
    }
    [global::System.CLSCompliant(false)]
    public uint OneofUint32 {
      get { return oneofUint32_; }
    }

    public const int OneofNestedMessageFieldNumber = 112;
    private bool hasOneofNestedMessage;
    private global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage oneofNestedMessage_;
    public bool HasOneofNestedMessage {
      get { return hasOneofNestedMessage; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage OneofNestedMessage {
      get { return oneofNestedMessage_ ?? global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.DefaultInstance; }
    }

    public const int OneofStringFieldNumber = 113;
    private bool hasOneofString;
    private string oneofString_ = "";
    public bool HasOneofString {
      get { return hasOneofString; }
    }
    public string OneofString {
      get { return oneofString_; }
    }

    public const int OneofBytesFieldNumber = 114;
    private bool hasOneofBytes;
    private pb::ByteString oneofBytes_ = pb::ByteString.Empty;
    public bool HasOneofBytes {
      get { return hasOneofBytes; }
    }
    public pb::ByteString OneofBytes {
      get { return oneofBytes_; }
    }

    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[35], OptionalInt32);
      }
      if (hasOptionalInt64) {
        output.WriteInt64(2, field_names[36], OptionalInt64);
      }
      if (hasOptionalUint32) {
        output.WriteUInt32(3, field_names[47], OptionalUint32);
      }
      if (hasOptionalUint64) {
        output.WriteUInt64(4, field_names[48], OptionalUint64);
      }
      if (hasOptionalSint32) {
        output.WriteSInt32(5, field_names[43], OptionalSint32);
      }
      if (hasOptionalSint64) {
        output.WriteSInt64(6, field_names[44], OptionalSint64);
      }
      if (hasOptionalFixed32) {
        output.WriteFixed32(7, field_names[28], OptionalFixed32);
      }
      if (hasOptionalFixed64) {
        output.WriteFixed64(8, field_names[29], OptionalFixed64);
      }
      if (hasOptionalSfixed32) {
        output.WriteSFixed32(9, field_names[41], OptionalSfixed32);
      }
      if (hasOptionalSfixed64) {
        output.WriteSFixed64(10, field_names[42], OptionalSfixed64);
      }
      if (hasOptionalFloat) {
        output.WriteFloat(11, field_names[30], OptionalFloat);
      }
      if (hasOptionalDouble) {
        output.WriteDouble(12, field_names[27], OptionalDouble);
      }
      if (hasOptionalBool) {
        output.WriteBool(13, field_names[24], OptionalBool);
      }
      if (hasOptionalString) {
        output.WriteString(14, field_names[45], OptionalString);
      }
      if (hasOptionalBytes) {
        output.WriteBytes(15, field_names[25], OptionalBytes);
      }
      if (hasOptionalGroup) {
        output.WriteGroup(16, field_names[49], OptionalGroup);
      }
      if (hasOptionalNestedMessage) {
        output.WriteMessage(18, field_names[39], OptionalNestedMessage);
      }
      if (hasOptionalForeignMessage) {
        output.WriteMessage(19, field_names[32], OptionalForeignMessage);
      }
      if (hasOptionalImportMessage) {
        output.WriteMessage(20, field_names[34], OptionalImportMessage);
      }
      if (hasOptionalNestedEnum) {
        output.WriteEnum(21, field_names[38], (int) OptionalNestedEnum, OptionalNestedEnum);
      }
      if (hasOptionalForeignEnum) {
        output.WriteEnum(22, field_names[31], (int) OptionalForeignEnum, OptionalForeignEnum);
      }
      if (hasOptionalImportEnum) {
        output.WriteEnum(23, field_names[33], (int) OptionalImportEnum, OptionalImportEnum);
      }
      if (hasOptionalStringPiece) {
        output.WriteString(24, field_names[46], OptionalStringPiece);
      }
      if (hasOptionalCord) {
        output.WriteString(25, field_names[26], OptionalCord);
      }
      if (hasOptionalPublicImportMessage) {
        output.WriteMessage(26, field_names[40], OptionalPublicImportMessage);
      }
      if (hasOptionalLazyMessage) {
        output.WriteMessage(27, field_names[37], OptionalLazyMessage);
      }
      if (repeatedInt32_.Count > 0) {
        output.WriteInt32Array(31, field_names[61], repeatedInt32_);
      }
      if (repeatedInt64_.Count > 0) {
        output.WriteInt64Array(32, field_names[62], repeatedInt64_);
      }
      if (repeatedUint32_.Count > 0) {
        output.WriteUInt32Array(33, field_names[72], repeatedUint32_);
      }
      if (repeatedUint64_.Count > 0) {
        output.WriteUInt64Array(34, field_names[73], repeatedUint64_);
      }
      if (repeatedSint32_.Count > 0) {
        output.WriteSInt32Array(35, field_names[68], repeatedSint32_);
      }
      if (repeatedSint64_.Count > 0) {
        output.WriteSInt64Array(36, field_names[69], repeatedSint64_);
      }
      if (repeatedFixed32_.Count > 0) {
        output.WriteFixed32Array(37, field_names[54], repeatedFixed32_);
      }
      if (repeatedFixed64_.Count > 0) {
        output.WriteFixed64Array(38, field_names[55], repeatedFixed64_);
      }
      if (repeatedSfixed32_.Count > 0) {
        output.WriteSFixed32Array(39, field_names[66], repeatedSfixed32_);
      }
      if (repeatedSfixed64_.Count > 0) {
        output.WriteSFixed64Array(40, field_names[67], repeatedSfixed64_);
      }
      if (repeatedFloat_.Count > 0) {
        output.WriteFloatArray(41, field_names[56], repeatedFloat_);
      }
      if (repeatedDouble_.Count > 0) {
        output.WriteDoubleArray(42, field_names[53], repeatedDouble_);
      }
      if (repeatedBool_.Count > 0) {
        output.WriteBoolArray(43, field_names[50], repeatedBool_);
      }
      if (repeatedString_.Count > 0) {
        output.WriteStringArray(44, field_names[70], repeatedString_);
      }
      if (repeatedBytes_.Count > 0) {
        output.WriteBytesArray(45, field_names[51], repeatedBytes_);
      }
      if (repeatedGroup_.Count > 0) {
        output.WriteGroupArray(46, field_names[74], repeatedGroup_);
      }
      if (repeatedNestedMessage_.Count > 0) {
        output.WriteMessageArray(48, field_names[65], repeatedNestedMessage_);
      }
      if (repeatedForeignMessage_.Count > 0) {
        output.WriteMessageArray(49, field_names[58], repeatedForeignMessage_);
      }
      if (repeatedImportMessage_.Count > 0) {
        output.WriteMessageArray(50, field_names[60], repeatedImportMessage_);
      }
      if (repeatedNestedEnum_.Count > 0) {
        output.WriteEnumArray(51, field_names[64], repeatedNestedEnum_);
      }
      if (repeatedForeignEnum_.Count > 0) {
        output.WriteEnumArray(52, field_names[57], repeatedForeignEnum_);
      }
      if (repeatedImportEnum_.Count > 0) {
        output.WriteEnumArray(53, field_names[59], repeatedImportEnum_);
      }
      if (repeatedStringPiece_.Count > 0) {
        output.WriteStringArray(54, field_names[71], repeatedStringPiece_);
      }
      if (repeatedCord_.Count > 0) {
        output.WriteStringArray(55, field_names[52], repeatedCord_);
      }
      if (repeatedLazyMessage_.Count > 0) {
        output.WriteMessageArray(57, field_names[63], repeatedLazyMessage_);
      }
      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);
      }
      if (hasOneofUint32) {
        output.WriteUInt32(111, field_names[23], OneofUint32);
      }
      if (hasOneofNestedMessage) {
        output.WriteMessage(112, field_names[21], OneofNestedMessage);
      }
      if (hasOneofString) {
        output.WriteString(113, field_names[22], OneofString);
      }
      if (hasOneofBytes) {
        output.WriteBytes(114, field_names[20], OneofBytes);
      }
      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);
      }
      if (hasOptionalPublicImportMessage) {
        size += pb::CodedOutputStream.ComputeMessageSize(26, OptionalPublicImportMessage);
      }
      if (hasOptionalLazyMessage) {
        size += pb::CodedOutputStream.ComputeMessageSize(27, OptionalLazyMessage);
      }
      {
        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;
      }
      foreach (global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage element in RepeatedLazyMessageList) {
        size += pb::CodedOutputStream.ComputeMessageSize(57, element);
      }
      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);
      }
      if (hasOneofUint32) {
        size += pb::CodedOutputStream.ComputeUInt32Size(111, OneofUint32);
      }
      if (hasOneofNestedMessage) {
        size += pb::CodedOutputStream.ComputeMessageSize(112, OneofNestedMessage);
      }
      if (hasOneofString) {
        size += pb::CodedOutputStream.ComputeStringSize(113, OneofString);
      }
      if (hasOneofBytes) {
        size += pb::CodedOutputStream.ComputeBytesSize(114, OneofBytes);
      }
      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();
      repeatedLazyMessage_.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.HasOptionalPublicImportMessage) {
          MergeOptionalPublicImportMessage(other.OptionalPublicImportMessage);
        }
        if (other.HasOptionalLazyMessage) {
          MergeOptionalLazyMessage(other.OptionalLazyMessage);
        }
        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.repeatedLazyMessage_.Count != 0) {
          result.repeatedLazyMessage_.Add(other.repeatedLazyMessage_);
        }
        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;
        }
        if (other.HasOneofUint32) {
          OneofUint32 = other.OneofUint32;
        }
        if (other.HasOneofNestedMessage) {
          MergeOneofNestedMessage(other.OneofNestedMessage);
        }
        if (other.HasOneofString) {
          OneofString = other.OneofString;
        }
        if (other.HasOneofBytes) {
          OneofBytes = other.OneofBytes;
        }
        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 210: {
              global::Google.ProtocolBuffers.TestProtos.PublicImportMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.PublicImportMessage.CreateBuilder();
              if (result.hasOptionalPublicImportMessage) {
                subBuilder.MergeFrom(OptionalPublicImportMessage);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              OptionalPublicImportMessage = subBuilder.BuildPartial();
              break;
            }
            case 218: {
              global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.CreateBuilder();
              if (result.hasOptionalLazyMessage) {
                subBuilder.MergeFrom(OptionalLazyMessage);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              OptionalLazyMessage = subBuilder.BuildPartial();
              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 458: {
              input.ReadMessageArray(tag, field_name, result.repeatedLazyMessage_, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.DefaultInstance, extensionRegistry);
              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;
            }
            case 888: {
              result.hasOneofUint32 = input.ReadUInt32(ref result.oneofUint32_);
              break;
            }
            case 898: {
              global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.CreateBuilder();
              if (result.hasOneofNestedMessage) {
                subBuilder.MergeFrom(OneofNestedMessage);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              OneofNestedMessage = subBuilder.BuildPartial();
              break;
            }
            case 906: {
              result.hasOneofString = input.ReadString(ref result.oneofString_);
              break;
            }
            case 914: {
              result.hasOneofBytes = input.ReadBytes(ref result.oneofBytes_);
              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_ = 0L;
        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_ = 0UL;
        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_ = 0L;
        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 bool HasOptionalPublicImportMessage {
       get { return result.hasOptionalPublicImportMessage; }
      }
      public global::Google.ProtocolBuffers.TestProtos.PublicImportMessage OptionalPublicImportMessage {
        get { return result.OptionalPublicImportMessage; }
        set { SetOptionalPublicImportMessage(value); }
      }
      public Builder SetOptionalPublicImportMessage(global::Google.ProtocolBuffers.TestProtos.PublicImportMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasOptionalPublicImportMessage = true;
        result.optionalPublicImportMessage_ = value;
        return this;
      }
      public Builder SetOptionalPublicImportMessage(global::Google.ProtocolBuffers.TestProtos.PublicImportMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasOptionalPublicImportMessage = true;
        result.optionalPublicImportMessage_ = builderForValue.Build();
        return this;
      }
      public Builder MergeOptionalPublicImportMessage(global::Google.ProtocolBuffers.TestProtos.PublicImportMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        if (result.hasOptionalPublicImportMessage &&
            result.optionalPublicImportMessage_ != global::Google.ProtocolBuffers.TestProtos.PublicImportMessage.DefaultInstance) {
            result.optionalPublicImportMessage_ = global::Google.ProtocolBuffers.TestProtos.PublicImportMessage.CreateBuilder(result.optionalPublicImportMessage_).MergeFrom(value).BuildPartial();
        } else {
          result.optionalPublicImportMessage_ = value;
        }
        result.hasOptionalPublicImportMessage = true;
        return this;
      }
      public Builder ClearOptionalPublicImportMessage() {
        PrepareBuilder();
        result.hasOptionalPublicImportMessage = false;
        result.optionalPublicImportMessage_ = null;
        return this;
      }

      public bool HasOptionalLazyMessage {
       get { return result.hasOptionalLazyMessage; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage OptionalLazyMessage {
        get { return result.OptionalLazyMessage; }
        set { SetOptionalLazyMessage(value); }
      }
      public Builder SetOptionalLazyMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasOptionalLazyMessage = true;
        result.optionalLazyMessage_ = value;
        return this;
      }
      public Builder SetOptionalLazyMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasOptionalLazyMessage = true;
        result.optionalLazyMessage_ = builderForValue.Build();
        return this;
      }
      public Builder MergeOptionalLazyMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        if (result.hasOptionalLazyMessage &&
            result.optionalLazyMessage_ != global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.DefaultInstance) {
            result.optionalLazyMessage_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.CreateBuilder(result.optionalLazyMessage_).MergeFrom(value).BuildPartial();
        } else {
          result.optionalLazyMessage_ = value;
        }
        result.hasOptionalLazyMessage = true;
        return this;
      }
      public Builder ClearOptionalLazyMessage() {
        PrepareBuilder();
        result.hasOptionalLazyMessage = false;
        result.optionalLazyMessage_ = null;
        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 pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage> RepeatedLazyMessageList {
        get { return PrepareBuilder().repeatedLazyMessage_; }
      }
      public int RepeatedLazyMessageCount {
        get { return result.RepeatedLazyMessageCount; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage GetRepeatedLazyMessage(int index) {
        return result.GetRepeatedLazyMessage(index);
      }
      public Builder SetRepeatedLazyMessage(int index, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.repeatedLazyMessage_[index] = value;
        return this;
      }
      public Builder SetRepeatedLazyMessage(int index, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.repeatedLazyMessage_[index] = builderForValue.Build();
        return this;
      }
      public Builder AddRepeatedLazyMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.repeatedLazyMessage_.Add(value);
        return this;
      }
      public Builder AddRepeatedLazyMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.repeatedLazyMessage_.Add(builderForValue.Build());
        return this;
      }
      public Builder AddRangeRepeatedLazyMessage(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage> values) {
        PrepareBuilder();
        result.repeatedLazyMessage_.Add(values);
        return this;
      }
      public Builder ClearRepeatedLazyMessage() {
        PrepareBuilder();
        result.repeatedLazyMessage_.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_ = 46L;
        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_ = 48UL;
        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_ = -50L;
        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[65].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;
      }

      public bool HasOneofUint32 {
        get { return result.hasOneofUint32; }
      }
      [global::System.CLSCompliant(false)]
      public uint OneofUint32 {
        get { return result.OneofUint32; }
        set { SetOneofUint32(value); }
      }
      [global::System.CLSCompliant(false)]
      public Builder SetOneofUint32(uint value) {
        PrepareBuilder();
        result.hasOneofUint32 = true;
        result.oneofUint32_ = value;
        return this;
      }
      public Builder ClearOneofUint32() {
        PrepareBuilder();
        result.hasOneofUint32 = false;
        result.oneofUint32_ = 0;
        return this;
      }

      public bool HasOneofNestedMessage {
       get { return result.hasOneofNestedMessage; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage OneofNestedMessage {
        get { return result.OneofNestedMessage; }
        set { SetOneofNestedMessage(value); }
      }
      public Builder SetOneofNestedMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasOneofNestedMessage = true;
        result.oneofNestedMessage_ = value;
        return this;
      }
      public Builder SetOneofNestedMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasOneofNestedMessage = true;
        result.oneofNestedMessage_ = builderForValue.Build();
        return this;
      }
      public Builder MergeOneofNestedMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        if (result.hasOneofNestedMessage &&
            result.oneofNestedMessage_ != global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.DefaultInstance) {
            result.oneofNestedMessage_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.CreateBuilder(result.oneofNestedMessage_).MergeFrom(value).BuildPartial();
        } else {
          result.oneofNestedMessage_ = value;
        }
        result.hasOneofNestedMessage = true;
        return this;
      }
      public Builder ClearOneofNestedMessage() {
        PrepareBuilder();
        result.hasOneofNestedMessage = false;
        result.oneofNestedMessage_ = null;
        return this;
      }

      public bool HasOneofString {
        get { return result.hasOneofString; }
      }
      public string OneofString {
        get { return result.OneofString; }
        set { SetOneofString(value); }
      }
      public Builder SetOneofString(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasOneofString = true;
        result.oneofString_ = value;
        return this;
      }
      public Builder ClearOneofString() {
        PrepareBuilder();
        result.hasOneofString = false;
        result.oneofString_ = "";
        return this;
      }

      public bool HasOneofBytes {
        get { return result.hasOneofBytes; }
      }
      public pb::ByteString OneofBytes {
        get { return result.OneofBytes; }
        set { SetOneofBytes(value); }
      }
      public Builder SetOneofBytes(pb::ByteString value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasOneofBytes = true;
        result.oneofBytes_ = value;
        return this;
      }
      public Builder ClearOneofBytes() {
        PrepareBuilder();
        result.hasOneofBytes = false;
        result.oneofBytes_ = pb::ByteString.Empty;
        return this;
      }
    }
    static TestAllTypes() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor, null);
    }
  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class NestedTestAllTypes : pb::GeneratedMessage<NestedTestAllTypes, NestedTestAllTypes.Builder> {
    private NestedTestAllTypes() { }
    private static readonly NestedTestAllTypes defaultInstance = new NestedTestAllTypes().MakeReadOnly();
    private static readonly string[] _nestedTestAllTypesFieldNames = new string[] { "child", "payload" };
    private static readonly uint[] _nestedTestAllTypesFieldTags = new uint[] { 10, 18 };
    public static NestedTestAllTypes DefaultInstance {
      get { return defaultInstance; }
    }

    public override NestedTestAllTypes DefaultInstanceForType {
      get { return DefaultInstance; }
    }

    protected override NestedTestAllTypes ThisMessage {
      get { return this; }
    }

    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_NestedTestAllTypes__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<NestedTestAllTypes, NestedTestAllTypes.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_NestedTestAllTypes__FieldAccessorTable; }
    }

    public const int ChildFieldNumber = 1;
    private bool hasChild;
    private global::Google.ProtocolBuffers.TestProtos.NestedTestAllTypes child_;
    public bool HasChild {
      get { return hasChild; }
    }
    public global::Google.ProtocolBuffers.TestProtos.NestedTestAllTypes Child {
      get { return child_ ?? global::Google.ProtocolBuffers.TestProtos.NestedTestAllTypes.DefaultInstance; }
    }

    public const int PayloadFieldNumber = 2;
    private bool hasPayload;
    private global::Google.ProtocolBuffers.TestProtos.TestAllTypes payload_;
    public bool HasPayload {
      get { return hasPayload; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes Payload {
      get { return payload_ ?? global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance; }
    }

    public override bool IsInitialized {
      get {
        return true;
      }
    }

    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _nestedTestAllTypesFieldNames;
      if (hasChild) {
        output.WriteMessage(1, field_names[0], Child);
      }
      if (hasPayload) {
        output.WriteMessage(2, field_names[1], Payload);
      }
      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 (hasChild) {
        size += pb::CodedOutputStream.ComputeMessageSize(1, Child);
      }
      if (hasPayload) {
        size += pb::CodedOutputStream.ComputeMessageSize(2, Payload);
      }
      size += UnknownFields.SerializedSize;
      memoizedSerializedSize = size;
      return size;
    }
    public static NestedTestAllTypes ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static NestedTestAllTypes ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static NestedTestAllTypes ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static NestedTestAllTypes ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static NestedTestAllTypes ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static NestedTestAllTypes ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static NestedTestAllTypes ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static NestedTestAllTypes ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static NestedTestAllTypes ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static NestedTestAllTypes ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private NestedTestAllTypes 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(NestedTestAllTypes prototype) {
      return new Builder(prototype);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<NestedTestAllTypes, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(NestedTestAllTypes cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }

      private bool resultIsReadOnly;
      private NestedTestAllTypes result;

      private NestedTestAllTypes PrepareBuilder() {
        if (resultIsReadOnly) {
          NestedTestAllTypes original = result;
          result = new NestedTestAllTypes();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }

      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }

      protected override NestedTestAllTypes 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.NestedTestAllTypes.Descriptor; }
      }

      public override NestedTestAllTypes DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.NestedTestAllTypes.DefaultInstance; }
      }

      public override NestedTestAllTypes BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }

      public override Builder MergeFrom(pb::IMessage other) {
        if (other is NestedTestAllTypes) {
          return MergeFrom((NestedTestAllTypes) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }

      public override Builder MergeFrom(NestedTestAllTypes other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.NestedTestAllTypes.DefaultInstance) return this;
        PrepareBuilder();
        if (other.HasChild) {
          MergeChild(other.Child);
        }
        if (other.HasPayload) {
          MergePayload(other.Payload);
        }
        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(_nestedTestAllTypesFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _nestedTestAllTypesFieldTags[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.NestedTestAllTypes.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.NestedTestAllTypes.CreateBuilder();
              if (result.hasChild) {
                subBuilder.MergeFrom(Child);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              Child = subBuilder.BuildPartial();
              break;
            }
            case 18: {
              global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder();
              if (result.hasPayload) {
                subBuilder.MergeFrom(Payload);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              Payload = subBuilder.BuildPartial();
              break;
            }
          }
        }

        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }


      public bool HasChild {
       get { return result.hasChild; }
      }
      public global::Google.ProtocolBuffers.TestProtos.NestedTestAllTypes Child {
        get { return result.Child; }
        set { SetChild(value); }
      }
      public Builder SetChild(global::Google.ProtocolBuffers.TestProtos.NestedTestAllTypes value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasChild = true;
        result.child_ = value;
        return this;
      }
      public Builder SetChild(global::Google.ProtocolBuffers.TestProtos.NestedTestAllTypes.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasChild = true;
        result.child_ = builderForValue.Build();
        return this;
      }
      public Builder MergeChild(global::Google.ProtocolBuffers.TestProtos.NestedTestAllTypes value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        if (result.hasChild &&
            result.child_ != global::Google.ProtocolBuffers.TestProtos.NestedTestAllTypes.DefaultInstance) {
            result.child_ = global::Google.ProtocolBuffers.TestProtos.NestedTestAllTypes.CreateBuilder(result.child_).MergeFrom(value).BuildPartial();
        } else {
          result.child_ = value;
        }
        result.hasChild = true;
        return this;
      }
      public Builder ClearChild() {
        PrepareBuilder();
        result.hasChild = false;
        result.child_ = null;
        return this;
      }

      public bool HasPayload {
       get { return result.hasPayload; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestAllTypes Payload {
        get { return result.Payload; }
        set { SetPayload(value); }
      }
      public Builder SetPayload(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasPayload = true;
        result.payload_ = value;
        return this;
      }
      public Builder SetPayload(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasPayload = true;
        result.payload_ = builderForValue.Build();
        return this;
      }
      public Builder MergePayload(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        if (result.hasPayload &&
            result.payload_ != global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance) {
            result.payload_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder(result.payload_).MergeFrom(value).BuildPartial();
        } else {
          result.payload_ = value;
        }
        result.hasPayload = true;
        return this;
      }
      public Builder ClearPayload() {
        PrepareBuilder();
        result.hasPayload = false;
        result.payload_ = null;
        return this;
      }
    }
    static NestedTestAllTypes() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.internal__static_protobuf_unittest_TestDeprecatedFields__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestDeprecatedFields, TestDeprecatedFields.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_ForeignMessage__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<ForeignMessage, ForeignMessage.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_TestAllExtensions__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestAllExtensions, TestAllExtensions.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_OptionalGroup_extension__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<OptionalGroup_extension, OptionalGroup_extension.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_RepeatedGroup_extension__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<RepeatedGroup_extension, RepeatedGroup_extension.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_TestNestedExtension__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestNestedExtension, TestNestedExtension.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestNestedExtension__FieldAccessorTable; }
    }

    public const int TestFieldNumber = 1002;
    public static pb::GeneratedExtensionBase<string> Test;
    public const int NestedStringExtensionFieldNumber = 1003;
    public static pb::GeneratedExtensionBase<string> NestedStringExtension;
    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.Unittest.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.Unittest.internal__static_protobuf_unittest_TestRequired__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestRequired, TestRequired.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_TestRequiredForeign__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestRequiredForeign, TestRequiredForeign.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_TestForeignNested__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestForeignNested, TestForeignNested.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_TestEmptyMessage__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestEmptyMessage, TestEmptyMessage.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_TestEmptyMessageWithExtensions__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestEmptyMessageWithExtensions, TestEmptyMessageWithExtensions.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_TestMultipleExtensionRanges__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestMultipleExtensionRanges, TestMultipleExtensionRanges.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_TestReallyLargeTagNumber__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestReallyLargeTagNumber, TestReallyLargeTagNumber.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_TestRecursiveMessage__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestRecursiveMessage, TestRecursiveMessage.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_TestMutualRecursionA__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestMutualRecursionA, TestMutualRecursionA.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_TestMutualRecursionB__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestMutualRecursionB, TestMutualRecursionB.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_TestDupFieldNumber__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestDupFieldNumber, TestDupFieldNumber.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.internal__static_protobuf_unittest_TestDupFieldNumber_Foo__Descriptor; }
        }

        protected override pb::FieldAccess.FieldAccessorTable<Foo, Foo.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_TestDupFieldNumber_Bar__Descriptor; }
        }

        protected override pb::FieldAccess.FieldAccessorTable<Bar, Bar.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.Descriptor, null);
    }
  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestEagerMessage : pb::GeneratedMessage<TestEagerMessage, TestEagerMessage.Builder> {
    private TestEagerMessage() { }
    private static readonly TestEagerMessage defaultInstance = new TestEagerMessage().MakeReadOnly();
    private static readonly string[] _testEagerMessageFieldNames = new string[] { "sub_message" };
    private static readonly uint[] _testEagerMessageFieldTags = new uint[] { 10 };
    public static TestEagerMessage DefaultInstance {
      get { return defaultInstance; }
    }

    public override TestEagerMessage DefaultInstanceForType {
      get { return DefaultInstance; }
    }

    protected override TestEagerMessage ThisMessage {
      get { return this; }
    }

    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestEagerMessage__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestEagerMessage, TestEagerMessage.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestEagerMessage__FieldAccessorTable; }
    }

    public const int SubMessageFieldNumber = 1;
    private bool hasSubMessage;
    private global::Google.ProtocolBuffers.TestProtos.TestAllTypes subMessage_;
    public bool HasSubMessage {
      get { return hasSubMessage; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes SubMessage {
      get { return subMessage_ ?? global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance; }
    }

    public override bool IsInitialized {
      get {
        return true;
      }
    }

    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _testEagerMessageFieldNames;
      if (hasSubMessage) {
        output.WriteMessage(1, field_names[0], SubMessage);
      }
      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 (hasSubMessage) {
        size += pb::CodedOutputStream.ComputeMessageSize(1, SubMessage);
      }
      size += UnknownFields.SerializedSize;
      memoizedSerializedSize = size;
      return size;
    }
    public static TestEagerMessage ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestEagerMessage ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestEagerMessage ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestEagerMessage ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestEagerMessage ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestEagerMessage ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestEagerMessage ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestEagerMessage ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestEagerMessage ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestEagerMessage ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestEagerMessage 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(TestEagerMessage prototype) {
      return new Builder(prototype);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestEagerMessage, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestEagerMessage cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }

      private bool resultIsReadOnly;
      private TestEagerMessage result;

      private TestEagerMessage PrepareBuilder() {
        if (resultIsReadOnly) {
          TestEagerMessage original = result;
          result = new TestEagerMessage();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }

      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }

      protected override TestEagerMessage 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.TestEagerMessage.Descriptor; }
      }

      public override TestEagerMessage DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestEagerMessage.DefaultInstance; }
      }

      public override TestEagerMessage BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }

      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestEagerMessage) {
          return MergeFrom((TestEagerMessage) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }

      public override Builder MergeFrom(TestEagerMessage other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestEagerMessage.DefaultInstance) return this;
        PrepareBuilder();
        if (other.HasSubMessage) {
          MergeSubMessage(other.SubMessage);
        }
        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(_testEagerMessageFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testEagerMessageFieldTags[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.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder();
              if (result.hasSubMessage) {
                subBuilder.MergeFrom(SubMessage);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              SubMessage = subBuilder.BuildPartial();
              break;
            }
          }
        }

        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }


      public bool HasSubMessage {
       get { return result.hasSubMessage; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestAllTypes SubMessage {
        get { return result.SubMessage; }
        set { SetSubMessage(value); }
      }
      public Builder SetSubMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasSubMessage = true;
        result.subMessage_ = value;
        return this;
      }
      public Builder SetSubMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasSubMessage = true;
        result.subMessage_ = builderForValue.Build();
        return this;
      }
      public Builder MergeSubMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        if (result.hasSubMessage &&
            result.subMessage_ != global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance) {
            result.subMessage_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder(result.subMessage_).MergeFrom(value).BuildPartial();
        } else {
          result.subMessage_ = value;
        }
        result.hasSubMessage = true;
        return this;
      }
      public Builder ClearSubMessage() {
        PrepareBuilder();
        result.hasSubMessage = false;
        result.subMessage_ = null;
        return this;
      }
    }
    static TestEagerMessage() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor, null);
    }
  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestLazyMessage : pb::GeneratedMessage<TestLazyMessage, TestLazyMessage.Builder> {
    private TestLazyMessage() { }
    private static readonly TestLazyMessage defaultInstance = new TestLazyMessage().MakeReadOnly();
    private static readonly string[] _testLazyMessageFieldNames = new string[] { "sub_message" };
    private static readonly uint[] _testLazyMessageFieldTags = new uint[] { 10 };
    public static TestLazyMessage DefaultInstance {
      get { return defaultInstance; }
    }

    public override TestLazyMessage DefaultInstanceForType {
      get { return DefaultInstance; }
    }

    protected override TestLazyMessage ThisMessage {
      get { return this; }
    }

    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestLazyMessage__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestLazyMessage, TestLazyMessage.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestLazyMessage__FieldAccessorTable; }
    }

    public const int SubMessageFieldNumber = 1;
    private bool hasSubMessage;
    private global::Google.ProtocolBuffers.TestProtos.TestAllTypes subMessage_;
    public bool HasSubMessage {
      get { return hasSubMessage; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes SubMessage {
      get { return subMessage_ ?? global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance; }
    }

    public override bool IsInitialized {
      get {
        return true;
      }
    }

    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _testLazyMessageFieldNames;
      if (hasSubMessage) {
        output.WriteMessage(1, field_names[0], SubMessage);
      }
      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 (hasSubMessage) {
        size += pb::CodedOutputStream.ComputeMessageSize(1, SubMessage);
      }
      size += UnknownFields.SerializedSize;
      memoizedSerializedSize = size;
      return size;
    }
    public static TestLazyMessage ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestLazyMessage ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestLazyMessage ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestLazyMessage ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestLazyMessage ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestLazyMessage ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestLazyMessage ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestLazyMessage ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestLazyMessage ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestLazyMessage ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestLazyMessage 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(TestLazyMessage prototype) {
      return new Builder(prototype);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestLazyMessage, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestLazyMessage cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }

      private bool resultIsReadOnly;
      private TestLazyMessage result;

      private TestLazyMessage PrepareBuilder() {
        if (resultIsReadOnly) {
          TestLazyMessage original = result;
          result = new TestLazyMessage();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }

      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }

      protected override TestLazyMessage 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.TestLazyMessage.Descriptor; }
      }

      public override TestLazyMessage DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestLazyMessage.DefaultInstance; }
      }

      public override TestLazyMessage BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }

      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestLazyMessage) {
          return MergeFrom((TestLazyMessage) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }

      public override Builder MergeFrom(TestLazyMessage other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestLazyMessage.DefaultInstance) return this;
        PrepareBuilder();
        if (other.HasSubMessage) {
          MergeSubMessage(other.SubMessage);
        }
        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(_testLazyMessageFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testLazyMessageFieldTags[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.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder();
              if (result.hasSubMessage) {
                subBuilder.MergeFrom(SubMessage);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              SubMessage = subBuilder.BuildPartial();
              break;
            }
          }
        }

        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }


      public bool HasSubMessage {
       get { return result.hasSubMessage; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestAllTypes SubMessage {
        get { return result.SubMessage; }
        set { SetSubMessage(value); }
      }
      public Builder SetSubMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasSubMessage = true;
        result.subMessage_ = value;
        return this;
      }
      public Builder SetSubMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasSubMessage = true;
        result.subMessage_ = builderForValue.Build();
        return this;
      }
      public Builder MergeSubMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        if (result.hasSubMessage &&
            result.subMessage_ != global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance) {
            result.subMessage_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder(result.subMessage_).MergeFrom(value).BuildPartial();
        } else {
          result.subMessage_ = value;
        }
        result.hasSubMessage = true;
        return this;
      }
      public Builder ClearSubMessage() {
        PrepareBuilder();
        result.hasSubMessage = false;
        result.subMessage_ = null;
        return this;
      }
    }
    static TestLazyMessage() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.internal__static_protobuf_unittest_TestNestedMessageHasBits__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestNestedMessageHasBits, TestNestedMessageHasBits.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.internal__static_protobuf_unittest_TestNestedMessageHasBits_NestedMessage__Descriptor; }
        }

        protected override pb::FieldAccess.FieldAccessorTable<NestedMessage, NestedMessage.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_TestCamelCaseFieldNames__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestCamelCaseFieldNames, TestCamelCaseFieldNames.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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", "optional_nested_message" };
    private static readonly uint[] _testFieldOrderingsFieldTags = new uint[] { 813, 8, 90, 1602 };
    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.Unittest.internal__static_protobuf_unittest_TestFieldOrderings__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestFieldOrderings, TestFieldOrderings.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestFieldOrderings__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[] { "bb", "oo" };
        private static readonly uint[] _nestedMessageFieldTags = new uint[] { 8, 16 };
        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.Unittest.internal__static_protobuf_unittest_TestFieldOrderings_NestedMessage__Descriptor; }
        }

        protected override pb::FieldAccess.FieldAccessorTable<NestedMessage, NestedMessage.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestFieldOrderings_NestedMessage__FieldAccessorTable; }
        }

        public const int OoFieldNumber = 2;
        private bool hasOo;
        private long oo_;
        public bool HasOo {
          get { return hasOo; }
        }
        public long Oo {
          get { return oo_; }
        }

        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);
          }
          if (hasOo) {
            output.WriteInt64(2, field_names[1], Oo);
          }
          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 (hasOo) {
            size += pb::CodedOutputStream.ComputeInt64Size(2, Oo);
          }
          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.TestFieldOrderings.Types.NestedMessage.Descriptor; }
          }

          public override NestedMessage DefaultInstanceForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestFieldOrderings.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.TestFieldOrderings.Types.NestedMessage.DefaultInstance) return this;
            PrepareBuilder();
            if (other.HasOo) {
              Oo = other.Oo;
            }
            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;
                }
                case 16: {
                  result.hasOo = input.ReadInt64(ref result.oo_);
                  break;
                }
              }
            }

            if (unknownFields != null) {
              this.UnknownFields = unknownFields.Build();
            }
            return this;
          }


          public bool HasOo {
            get { return result.hasOo; }
          }
          public long Oo {
            get { return result.Oo; }
            set { SetOo(value); }
          }
          public Builder SetOo(long value) {
            PrepareBuilder();
            result.hasOo = true;
            result.oo_ = value;
            return this;
          }
          public Builder ClearOo() {
            PrepareBuilder();
            result.hasOo = false;
            result.oo_ = 0L;
            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.Unittest.Descriptor, null);
        }
      }

    }
    #endregion

    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 const int OptionalNestedMessageFieldNumber = 200;
    private bool hasOptionalNestedMessage;
    private global::Google.ProtocolBuffers.TestProtos.TestFieldOrderings.Types.NestedMessage optionalNestedMessage_;
    public bool HasOptionalNestedMessage {
      get { return hasOptionalNestedMessage; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestFieldOrderings.Types.NestedMessage OptionalNestedMessage {
      get { return optionalNestedMessage_ ?? global::Google.ProtocolBuffers.TestProtos.TestFieldOrderings.Types.NestedMessage.DefaultInstance; }
    }

    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);
      }
      if (hasOptionalNestedMessage) {
        output.WriteMessage(200, field_names[3], 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 (hasMyString) {
        size += pb::CodedOutputStream.ComputeStringSize(11, MyString);
      }
      if (hasMyInt) {
        size += pb::CodedOutputStream.ComputeInt64Size(1, MyInt);
      }
      if (hasMyFloat) {
        size += pb::CodedOutputStream.ComputeFloatSize(101, MyFloat);
      }
      if (hasOptionalNestedMessage) {
        size += pb::CodedOutputStream.ComputeMessageSize(200, OptionalNestedMessage);
      }
      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;
        }
        if (other.HasOptionalNestedMessage) {
          MergeOptionalNestedMessage(other.OptionalNestedMessage);
        }
          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;
            }
            case 1602: {
              global::Google.ProtocolBuffers.TestProtos.TestFieldOrderings.Types.NestedMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestFieldOrderings.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 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;
      }

      public bool HasOptionalNestedMessage {
       get { return result.hasOptionalNestedMessage; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestFieldOrderings.Types.NestedMessage OptionalNestedMessage {
        get { return result.OptionalNestedMessage; }
        set { SetOptionalNestedMessage(value); }
      }
      public Builder SetOptionalNestedMessage(global::Google.ProtocolBuffers.TestProtos.TestFieldOrderings.Types.NestedMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasOptionalNestedMessage = true;
        result.optionalNestedMessage_ = value;
        return this;
      }
      public Builder SetOptionalNestedMessage(global::Google.ProtocolBuffers.TestProtos.TestFieldOrderings.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.TestFieldOrderings.Types.NestedMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        if (result.hasOptionalNestedMessage &&
            result.optionalNestedMessage_ != global::Google.ProtocolBuffers.TestProtos.TestFieldOrderings.Types.NestedMessage.DefaultInstance) {
            result.optionalNestedMessage_ = global::Google.ProtocolBuffers.TestProtos.TestFieldOrderings.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 TestFieldOrderings() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.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[] { "bytes_with_zero", "cord_with_zero", "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", "really_small_int32", "really_small_int64", "replacement_string", "small_float", "small_int32", "small_int64", "small_negative_float", "string_piece_with_zero", "string_with_zero", "utf8_string", "zero_float" };
    private static readonly uint[] _testExtremeDefaultValuesFieldTags = new uint[] { 194, 210, 162, 10, 113, 141, 101, 16, 24, 129, 157, 121, 149, 93, 85, 69, 168, 176, 218, 77, 32, 40, 109, 202, 186, 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.Unittest.internal__static_protobuf_unittest_TestExtremeDefaultValues__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestExtremeDefaultValues, TestExtremeDefaultValues.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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 ReallySmallInt32FieldNumber = 21;
    private bool hasReallySmallInt32;
    private int reallySmallInt32_ = -2147483648;
    public bool HasReallySmallInt32 {
      get { return hasReallySmallInt32; }
    }
    public int ReallySmallInt32 {
      get { return reallySmallInt32_; }
    }

    public const int ReallySmallInt64FieldNumber = 22;
    private bool hasReallySmallInt64;
    private long reallySmallInt64_ = -9223372036854775808L;
    public bool HasReallySmallInt64 {
      get { return hasReallySmallInt64; }
    }
    public long ReallySmallInt64 {
      get { return reallySmallInt64_; }
    }

    public const int Utf8StringFieldNumber = 6;
    private bool hasUtf8String;
    private string utf8String_ = (string) global::Google.ProtocolBuffers.TestProtos.TestExtremeDefaultValues.Descriptor.Fields[7].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 const int StringWithZeroFieldNumber = 23;
    private bool hasStringWithZero;
    private string stringWithZero_ = (string) global::Google.ProtocolBuffers.TestProtos.TestExtremeDefaultValues.Descriptor.Fields[22].DefaultValue;
    public bool HasStringWithZero {
      get { return hasStringWithZero; }
    }
    public string StringWithZero {
      get { return stringWithZero_; }
    }

    public const int BytesWithZeroFieldNumber = 24;
    private bool hasBytesWithZero;
    private pb::ByteString bytesWithZero_ = (pb::ByteString) global::Google.ProtocolBuffers.TestProtos.TestExtremeDefaultValues.Descriptor.Fields[23].DefaultValue;
    public bool HasBytesWithZero {
      get { return hasBytesWithZero; }
    }
    public pb::ByteString BytesWithZero {
      get { return bytesWithZero_; }
    }

    public const int StringPieceWithZeroFieldNumber = 25;
    private bool hasStringPieceWithZero;
    private string stringPieceWithZero_ = (string) global::Google.ProtocolBuffers.TestProtos.TestExtremeDefaultValues.Descriptor.Fields[24].DefaultValue;
    public bool HasStringPieceWithZero {
      get { return hasStringPieceWithZero; }
    }
    public string StringPieceWithZero {
      get { return stringPieceWithZero_; }
    }

    public const int CordWithZeroFieldNumber = 26;
    private bool hasCordWithZero;
    private string cordWithZero_ = (string) global::Google.ProtocolBuffers.TestProtos.TestExtremeDefaultValues.Descriptor.Fields[25].DefaultValue;
    public bool HasCordWithZero {
      get { return hasCordWithZero; }
    }
    public string CordWithZero {
      get { return cordWithZero_; }
    }

    public const int ReplacementStringFieldNumber = 27;
    private bool hasReplacementString;
    private string replacementString_ = "${unknown}";
    public bool HasReplacementString {
      get { return hasReplacementString; }
    }
    public string ReplacementString {
      get { return replacementString_; }
    }

    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[3], EscapedBytes);
      }
      if (hasLargeUint32) {
        output.WriteUInt32(2, field_names[7], LargeUint32);
      }
      if (hasLargeUint64) {
        output.WriteUInt64(3, field_names[8], LargeUint64);
      }
      if (hasSmallInt32) {
        output.WriteInt32(4, field_names[20], SmallInt32);
      }
      if (hasSmallInt64) {
        output.WriteInt64(5, field_names[21], SmallInt64);
      }
      if (hasUtf8String) {
        output.WriteString(6, field_names[25], Utf8String);
      }
      if (hasZeroFloat) {
        output.WriteFloat(7, field_names[26], ZeroFloat);
      }
      if (hasOneFloat) {
        output.WriteFloat(8, field_names[15], OneFloat);
      }
      if (hasSmallFloat) {
        output.WriteFloat(9, field_names[19], SmallFloat);
      }
      if (hasNegativeOneFloat) {
        output.WriteFloat(10, field_names[14], NegativeOneFloat);
      }
      if (hasNegativeFloat) {
        output.WriteFloat(11, field_names[13], NegativeFloat);
      }
      if (hasLargeFloat) {
        output.WriteFloat(12, field_names[6], LargeFloat);
      }
      if (hasSmallNegativeFloat) {
        output.WriteFloat(13, field_names[22], SmallNegativeFloat);
      }
      if (hasInfDouble) {
        output.WriteDouble(14, field_names[4], InfDouble);
      }
      if (hasNegInfDouble) {
        output.WriteDouble(15, field_names[11], NegInfDouble);
      }
      if (hasNanDouble) {
        output.WriteDouble(16, field_names[9], NanDouble);
      }
      if (hasInfFloat) {
        output.WriteFloat(17, field_names[5], InfFloat);
      }
      if (hasNegInfFloat) {
        output.WriteFloat(18, field_names[12], NegInfFloat);
      }
      if (hasNanFloat) {
        output.WriteFloat(19, field_names[10], NanFloat);
      }
      if (hasCppTrigraph) {
        output.WriteString(20, field_names[2], CppTrigraph);
      }
      if (hasReallySmallInt32) {
        output.WriteInt32(21, field_names[16], ReallySmallInt32);
      }
      if (hasReallySmallInt64) {
        output.WriteInt64(22, field_names[17], ReallySmallInt64);
      }
      if (hasStringWithZero) {
        output.WriteString(23, field_names[24], StringWithZero);
      }
      if (hasBytesWithZero) {
        output.WriteBytes(24, field_names[0], BytesWithZero);
      }
      if (hasStringPieceWithZero) {
        output.WriteString(25, field_names[23], StringPieceWithZero);
      }
      if (hasCordWithZero) {
        output.WriteString(26, field_names[1], CordWithZero);
      }
      if (hasReplacementString) {
        output.WriteString(27, field_names[18], ReplacementString);
      }
      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 (hasReallySmallInt32) {
        size += pb::CodedOutputStream.ComputeInt32Size(21, ReallySmallInt32);
      }
      if (hasReallySmallInt64) {
        size += pb::CodedOutputStream.ComputeInt64Size(22, ReallySmallInt64);
      }
      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);
      }
      if (hasStringWithZero) {
        size += pb::CodedOutputStream.ComputeStringSize(23, StringWithZero);
      }
      if (hasBytesWithZero) {
        size += pb::CodedOutputStream.ComputeBytesSize(24, BytesWithZero);
      }
      if (hasStringPieceWithZero) {
        size += pb::CodedOutputStream.ComputeStringSize(25, StringPieceWithZero);
      }
      if (hasCordWithZero) {
        size += pb::CodedOutputStream.ComputeStringSize(26, CordWithZero);
      }
      if (hasReplacementString) {
        size += pb::CodedOutputStream.ComputeStringSize(27, ReplacementString);
      }
      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.HasReallySmallInt32) {
          ReallySmallInt32 = other.ReallySmallInt32;
        }
        if (other.HasReallySmallInt64) {
          ReallySmallInt64 = other.ReallySmallInt64;
        }
        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;
        }
        if (other.HasStringWithZero) {
          StringWithZero = other.StringWithZero;
        }
        if (other.HasBytesWithZero) {
          BytesWithZero = other.BytesWithZero;
        }
        if (other.HasStringPieceWithZero) {
          StringPieceWithZero = other.StringPieceWithZero;
        }
        if (other.HasCordWithZero) {
          CordWithZero = other.CordWithZero;
        }
        if (other.HasReplacementString) {
          ReplacementString = other.ReplacementString;
        }
        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;
            }
            case 168: {
              result.hasReallySmallInt32 = input.ReadInt32(ref result.reallySmallInt32_);
              break;
            }
            case 176: {
              result.hasReallySmallInt64 = input.ReadInt64(ref result.reallySmallInt64_);
              break;
            }
            case 186: {
              result.hasStringWithZero = input.ReadString(ref result.stringWithZero_);
              break;
            }
            case 194: {
              result.hasBytesWithZero = input.ReadBytes(ref result.bytesWithZero_);
              break;
            }
            case 202: {
              result.hasStringPieceWithZero = input.ReadString(ref result.stringPieceWithZero_);
              break;
            }
            case 210: {
              result.hasCordWithZero = input.ReadString(ref result.cordWithZero_);
              break;
            }
            case 218: {
              result.hasReplacementString = input.ReadString(ref result.replacementString_);
              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 HasReallySmallInt32 {
        get { return result.hasReallySmallInt32; }
      }
      public int ReallySmallInt32 {
        get { return result.ReallySmallInt32; }
        set { SetReallySmallInt32(value); }
      }
      public Builder SetReallySmallInt32(int value) {
        PrepareBuilder();
        result.hasReallySmallInt32 = true;
        result.reallySmallInt32_ = value;
        return this;
      }
      public Builder ClearReallySmallInt32() {
        PrepareBuilder();
        result.hasReallySmallInt32 = false;
        result.reallySmallInt32_ = -2147483648;
        return this;
      }

      public bool HasReallySmallInt64 {
        get { return result.hasReallySmallInt64; }
      }
      public long ReallySmallInt64 {
        get { return result.ReallySmallInt64; }
        set { SetReallySmallInt64(value); }
      }
      public Builder SetReallySmallInt64(long value) {
        PrepareBuilder();
        result.hasReallySmallInt64 = true;
        result.reallySmallInt64_ = value;
        return this;
      }
      public Builder ClearReallySmallInt64() {
        PrepareBuilder();
        result.hasReallySmallInt64 = false;
        result.reallySmallInt64_ = -9223372036854775808L;
        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[7].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;
      }

      public bool HasStringWithZero {
        get { return result.hasStringWithZero; }
      }
      public string StringWithZero {
        get { return result.StringWithZero; }
        set { SetStringWithZero(value); }
      }
      public Builder SetStringWithZero(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasStringWithZero = true;
        result.stringWithZero_ = value;
        return this;
      }
      public Builder ClearStringWithZero() {
        PrepareBuilder();
        result.hasStringWithZero = false;
        result.stringWithZero_ = (string) global::Google.ProtocolBuffers.TestProtos.TestExtremeDefaultValues.Descriptor.Fields[22].DefaultValue;
        return this;
      }

      public bool HasBytesWithZero {
        get { return result.hasBytesWithZero; }
      }
      public pb::ByteString BytesWithZero {
        get { return result.BytesWithZero; }
        set { SetBytesWithZero(value); }
      }
      public Builder SetBytesWithZero(pb::ByteString value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasBytesWithZero = true;
        result.bytesWithZero_ = value;
        return this;
      }
      public Builder ClearBytesWithZero() {
        PrepareBuilder();
        result.hasBytesWithZero = false;
        result.bytesWithZero_ = (pb::ByteString) global::Google.ProtocolBuffers.TestProtos.TestExtremeDefaultValues.Descriptor.Fields[23].DefaultValue;
        return this;
      }

      public bool HasStringPieceWithZero {
        get { return result.hasStringPieceWithZero; }
      }
      public string StringPieceWithZero {
        get { return result.StringPieceWithZero; }
        set { SetStringPieceWithZero(value); }
      }
      public Builder SetStringPieceWithZero(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasStringPieceWithZero = true;
        result.stringPieceWithZero_ = value;
        return this;
      }
      public Builder ClearStringPieceWithZero() {
        PrepareBuilder();
        result.hasStringPieceWithZero = false;
        result.stringPieceWithZero_ = (string) global::Google.ProtocolBuffers.TestProtos.TestExtremeDefaultValues.Descriptor.Fields[24].DefaultValue;
        return this;
      }

      public bool HasCordWithZero {
        get { return result.hasCordWithZero; }
      }
      public string CordWithZero {
        get { return result.CordWithZero; }
        set { SetCordWithZero(value); }
      }
      public Builder SetCordWithZero(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasCordWithZero = true;
        result.cordWithZero_ = value;
        return this;
      }
      public Builder ClearCordWithZero() {
        PrepareBuilder();
        result.hasCordWithZero = false;
        result.cordWithZero_ = (string) global::Google.ProtocolBuffers.TestProtos.TestExtremeDefaultValues.Descriptor.Fields[25].DefaultValue;
        return this;
      }

      public bool HasReplacementString {
        get { return result.hasReplacementString; }
      }
      public string ReplacementString {
        get { return result.ReplacementString; }
        set { SetReplacementString(value); }
      }
      public Builder SetReplacementString(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasReplacementString = true;
        result.replacementString_ = value;
        return this;
      }
      public Builder ClearReplacementString() {
        PrepareBuilder();
        result.hasReplacementString = false;
        result.replacementString_ = "${unknown}";
        return this;
      }
    }
    static TestExtremeDefaultValues() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.internal__static_protobuf_unittest_SparseEnumMessage__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<SparseEnumMessage, SparseEnumMessage.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_OneString__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<OneString, OneString.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.Descriptor, null);
    }
  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class MoreString : pb::GeneratedMessage<MoreString, MoreString.Builder> {
    private MoreString() { }
    private static readonly MoreString defaultInstance = new MoreString().MakeReadOnly();
    private static readonly string[] _moreStringFieldNames = new string[] { "data" };
    private static readonly uint[] _moreStringFieldTags = new uint[] { 10 };
    public static MoreString DefaultInstance {
      get { return defaultInstance; }
    }

    public override MoreString DefaultInstanceForType {
      get { return DefaultInstance; }
    }

    protected override MoreString ThisMessage {
      get { return this; }
    }

    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_MoreString__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<MoreString, MoreString.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_MoreString__FieldAccessorTable; }
    }

    public const int DataFieldNumber = 1;
    private pbc::PopsicleList<string> data_ = new pbc::PopsicleList<string>();
    public scg::IList<string> DataList {
      get { return pbc::Lists.AsReadOnly(data_); }
    }
    public int DataCount {
      get { return data_.Count; }
    }
    public string GetData(int index) {
      return data_[index];
    }

    public override bool IsInitialized {
      get {
        return true;
      }
    }

    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _moreStringFieldNames;
      if (data_.Count > 0) {
        output.WriteStringArray(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;
      {
        int dataSize = 0;
        foreach (string element in DataList) {
          dataSize += pb::CodedOutputStream.ComputeStringSizeNoTag(element);
        }
        size += dataSize;
        size += 1 * data_.Count;
      }
      size += UnknownFields.SerializedSize;
      memoizedSerializedSize = size;
      return size;
    }
    public static MoreString ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static MoreString ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static MoreString ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static MoreString ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static MoreString ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static MoreString ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static MoreString ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static MoreString ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static MoreString ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static MoreString ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private MoreString MakeReadOnly() {
      data_.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(MoreString prototype) {
      return new Builder(prototype);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<MoreString, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(MoreString cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }

      private bool resultIsReadOnly;
      private MoreString result;

      private MoreString PrepareBuilder() {
        if (resultIsReadOnly) {
          MoreString original = result;
          result = new MoreString();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }

      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }

      protected override MoreString 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.MoreString.Descriptor; }
      }

      public override MoreString DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.MoreString.DefaultInstance; }
      }

      public override MoreString BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }

      public override Builder MergeFrom(pb::IMessage other) {
        if (other is MoreString) {
          return MergeFrom((MoreString) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }

      public override Builder MergeFrom(MoreString other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.MoreString.DefaultInstance) return this;
        PrepareBuilder();
        if (other.data_.Count != 0) {
          result.data_.Add(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(_moreStringFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _moreStringFieldTags[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: {
              input.ReadStringArray(tag, field_name, result.data_);
              break;
            }
          }
        }

        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }


      public pbc::IPopsicleList<string> DataList {
        get { return PrepareBuilder().data_; }
      }
      public int DataCount {
        get { return result.DataCount; }
      }
      public string GetData(int index) {
        return result.GetData(index);
      }
      public Builder SetData(int index, string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.data_[index] = value;
        return this;
      }
      public Builder AddData(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.data_.Add(value);
        return this;
      }
      public Builder AddRangeData(scg::IEnumerable<string> values) {
        PrepareBuilder();
        result.data_.Add(values);
        return this;
      }
      public Builder ClearData() {
        PrepareBuilder();
        result.data_.Clear();
        return this;
      }
    }
    static MoreString() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.internal__static_protobuf_unittest_OneBytes__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<OneBytes, OneBytes.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.Descriptor, null);
    }
  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class MoreBytes : pb::GeneratedMessage<MoreBytes, MoreBytes.Builder> {
    private MoreBytes() { }
    private static readonly MoreBytes defaultInstance = new MoreBytes().MakeReadOnly();
    private static readonly string[] _moreBytesFieldNames = new string[] { "data" };
    private static readonly uint[] _moreBytesFieldTags = new uint[] { 10 };
    public static MoreBytes DefaultInstance {
      get { return defaultInstance; }
    }

    public override MoreBytes DefaultInstanceForType {
      get { return DefaultInstance; }
    }

    protected override MoreBytes ThisMessage {
      get { return this; }
    }

    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_MoreBytes__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<MoreBytes, MoreBytes.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_MoreBytes__FieldAccessorTable; }
    }

    public const int DataFieldNumber = 1;
    private pbc::PopsicleList<pb::ByteString> data_ = new pbc::PopsicleList<pb::ByteString>();
    public scg::IList<pb::ByteString> DataList {
      get { return pbc::Lists.AsReadOnly(data_); }
    }
    public int DataCount {
      get { return data_.Count; }
    }
    public pb::ByteString GetData(int index) {
      return data_[index];
    }

    public override bool IsInitialized {
      get {
        return true;
      }
    }

    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _moreBytesFieldNames;
      if (data_.Count > 0) {
        output.WriteBytesArray(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;
      {
        int dataSize = 0;
        foreach (pb::ByteString element in DataList) {
          dataSize += pb::CodedOutputStream.ComputeBytesSizeNoTag(element);
        }
        size += dataSize;
        size += 1 * data_.Count;
      }
      size += UnknownFields.SerializedSize;
      memoizedSerializedSize = size;
      return size;
    }
    public static MoreBytes ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static MoreBytes ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static MoreBytes ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static MoreBytes ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static MoreBytes ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static MoreBytes ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static MoreBytes ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static MoreBytes ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static MoreBytes ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static MoreBytes ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private MoreBytes MakeReadOnly() {
      data_.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(MoreBytes prototype) {
      return new Builder(prototype);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<MoreBytes, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(MoreBytes cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }

      private bool resultIsReadOnly;
      private MoreBytes result;

      private MoreBytes PrepareBuilder() {
        if (resultIsReadOnly) {
          MoreBytes original = result;
          result = new MoreBytes();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }

      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }

      protected override MoreBytes 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.MoreBytes.Descriptor; }
      }

      public override MoreBytes DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.MoreBytes.DefaultInstance; }
      }

      public override MoreBytes BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }

      public override Builder MergeFrom(pb::IMessage other) {
        if (other is MoreBytes) {
          return MergeFrom((MoreBytes) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }

      public override Builder MergeFrom(MoreBytes other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.MoreBytes.DefaultInstance) return this;
        PrepareBuilder();
        if (other.data_.Count != 0) {
          result.data_.Add(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(_moreBytesFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _moreBytesFieldTags[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: {
              input.ReadBytesArray(tag, field_name, result.data_);
              break;
            }
          }
        }

        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }


      public pbc::IPopsicleList<pb::ByteString> DataList {
        get { return PrepareBuilder().data_; }
      }
      public int DataCount {
        get { return result.DataCount; }
      }
      public pb::ByteString GetData(int index) {
        return result.GetData(index);
      }
      public Builder SetData(int index, pb::ByteString value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.data_[index] = value;
        return this;
      }
      public Builder AddData(pb::ByteString value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.data_.Add(value);
        return this;
      }
      public Builder AddRangeData(scg::IEnumerable<pb::ByteString> values) {
        PrepareBuilder();
        result.data_.Add(values);
        return this;
      }
      public Builder ClearData() {
        PrepareBuilder();
        result.data_.Clear();
        return this;
      }
    }
    static MoreBytes() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor, null);
    }
  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class Int32Message : pb::GeneratedMessage<Int32Message, Int32Message.Builder> {
    private Int32Message() { }
    private static readonly Int32Message defaultInstance = new Int32Message().MakeReadOnly();
    private static readonly string[] _int32MessageFieldNames = new string[] { "data" };
    private static readonly uint[] _int32MessageFieldTags = new uint[] { 8 };
    public static Int32Message DefaultInstance {
      get { return defaultInstance; }
    }

    public override Int32Message DefaultInstanceForType {
      get { return DefaultInstance; }
    }

    protected override Int32Message ThisMessage {
      get { return this; }
    }

    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_Int32Message__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<Int32Message, Int32Message.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_Int32Message__FieldAccessorTable; }
    }

    public const int DataFieldNumber = 1;
    private bool hasData;
    private int data_;
    public bool HasData {
      get { return hasData; }
    }
    public int Data {
      get { return data_; }
    }

    public override bool IsInitialized {
      get {
        return true;
      }
    }

    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _int32MessageFieldNames;
      if (hasData) {
        output.WriteInt32(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.ComputeInt32Size(1, Data);
      }
      size += UnknownFields.SerializedSize;
      memoizedSerializedSize = size;
      return size;
    }
    public static Int32Message ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static Int32Message ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static Int32Message ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static Int32Message ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static Int32Message ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static Int32Message ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static Int32Message ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static Int32Message ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static Int32Message ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static Int32Message ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private Int32Message 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(Int32Message prototype) {
      return new Builder(prototype);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<Int32Message, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(Int32Message cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }

      private bool resultIsReadOnly;
      private Int32Message result;

      private Int32Message PrepareBuilder() {
        if (resultIsReadOnly) {
          Int32Message original = result;
          result = new Int32Message();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }

      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }

      protected override Int32Message 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.Int32Message.Descriptor; }
      }

      public override Int32Message DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.Int32Message.DefaultInstance; }
      }

      public override Int32Message BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }

      public override Builder MergeFrom(pb::IMessage other) {
        if (other is Int32Message) {
          return MergeFrom((Int32Message) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }

      public override Builder MergeFrom(Int32Message other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.Int32Message.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(_int32MessageFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _int32MessageFieldTags[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.hasData = input.ReadInt32(ref result.data_);
              break;
            }
          }
        }

        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }


      public bool HasData {
        get { return result.hasData; }
      }
      public int Data {
        get { return result.Data; }
        set { SetData(value); }
      }
      public Builder SetData(int value) {
        PrepareBuilder();
        result.hasData = true;
        result.data_ = value;
        return this;
      }
      public Builder ClearData() {
        PrepareBuilder();
        result.hasData = false;
        result.data_ = 0;
        return this;
      }
    }
    static Int32Message() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor, null);
    }
  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class Uint32Message : pb::GeneratedMessage<Uint32Message, Uint32Message.Builder> {
    private Uint32Message() { }
    private static readonly Uint32Message defaultInstance = new Uint32Message().MakeReadOnly();
    private static readonly string[] _uint32MessageFieldNames = new string[] { "data" };
    private static readonly uint[] _uint32MessageFieldTags = new uint[] { 8 };
    public static Uint32Message DefaultInstance {
      get { return defaultInstance; }
    }

    public override Uint32Message DefaultInstanceForType {
      get { return DefaultInstance; }
    }

    protected override Uint32Message ThisMessage {
      get { return this; }
    }

    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_Uint32Message__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<Uint32Message, Uint32Message.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_Uint32Message__FieldAccessorTable; }
    }

    public const int DataFieldNumber = 1;
    private bool hasData;
    private uint data_;
    public bool HasData {
      get { return hasData; }
    }
    [global::System.CLSCompliant(false)]
    public uint Data {
      get { return data_; }
    }

    public override bool IsInitialized {
      get {
        return true;
      }
    }

    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _uint32MessageFieldNames;
      if (hasData) {
        output.WriteUInt32(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.ComputeUInt32Size(1, Data);
      }
      size += UnknownFields.SerializedSize;
      memoizedSerializedSize = size;
      return size;
    }
    public static Uint32Message ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static Uint32Message ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static Uint32Message ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static Uint32Message ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static Uint32Message ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static Uint32Message ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static Uint32Message ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static Uint32Message ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static Uint32Message ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static Uint32Message ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private Uint32Message 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(Uint32Message prototype) {
      return new Builder(prototype);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<Uint32Message, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(Uint32Message cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }

      private bool resultIsReadOnly;
      private Uint32Message result;

      private Uint32Message PrepareBuilder() {
        if (resultIsReadOnly) {
          Uint32Message original = result;
          result = new Uint32Message();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }

      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }

      protected override Uint32Message 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.Uint32Message.Descriptor; }
      }

      public override Uint32Message DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.Uint32Message.DefaultInstance; }
      }

      public override Uint32Message BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }

      public override Builder MergeFrom(pb::IMessage other) {
        if (other is Uint32Message) {
          return MergeFrom((Uint32Message) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }

      public override Builder MergeFrom(Uint32Message other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.Uint32Message.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(_uint32MessageFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _uint32MessageFieldTags[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.hasData = input.ReadUInt32(ref result.data_);
              break;
            }
          }
        }

        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }


      public bool HasData {
        get { return result.hasData; }
      }
      [global::System.CLSCompliant(false)]
      public uint Data {
        get { return result.Data; }
        set { SetData(value); }
      }
      [global::System.CLSCompliant(false)]
      public Builder SetData(uint value) {
        PrepareBuilder();
        result.hasData = true;
        result.data_ = value;
        return this;
      }
      public Builder ClearData() {
        PrepareBuilder();
        result.hasData = false;
        result.data_ = 0;
        return this;
      }
    }
    static Uint32Message() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor, null);
    }
  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class Int64Message : pb::GeneratedMessage<Int64Message, Int64Message.Builder> {
    private Int64Message() { }
    private static readonly Int64Message defaultInstance = new Int64Message().MakeReadOnly();
    private static readonly string[] _int64MessageFieldNames = new string[] { "data" };
    private static readonly uint[] _int64MessageFieldTags = new uint[] { 8 };
    public static Int64Message DefaultInstance {
      get { return defaultInstance; }
    }

    public override Int64Message DefaultInstanceForType {
      get { return DefaultInstance; }
    }

    protected override Int64Message ThisMessage {
      get { return this; }
    }

    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_Int64Message__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<Int64Message, Int64Message.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_Int64Message__FieldAccessorTable; }
    }

    public const int DataFieldNumber = 1;
    private bool hasData;
    private long data_;
    public bool HasData {
      get { return hasData; }
    }
    public long Data {
      get { return data_; }
    }

    public override bool IsInitialized {
      get {
        return true;
      }
    }

    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _int64MessageFieldNames;
      if (hasData) {
        output.WriteInt64(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.ComputeInt64Size(1, Data);
      }
      size += UnknownFields.SerializedSize;
      memoizedSerializedSize = size;
      return size;
    }
    public static Int64Message ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static Int64Message ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static Int64Message ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static Int64Message ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static Int64Message ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static Int64Message ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static Int64Message ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static Int64Message ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static Int64Message ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static Int64Message ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private Int64Message 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(Int64Message prototype) {
      return new Builder(prototype);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<Int64Message, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(Int64Message cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }

      private bool resultIsReadOnly;
      private Int64Message result;

      private Int64Message PrepareBuilder() {
        if (resultIsReadOnly) {
          Int64Message original = result;
          result = new Int64Message();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }

      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }

      protected override Int64Message 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.Int64Message.Descriptor; }
      }

      public override Int64Message DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.Int64Message.DefaultInstance; }
      }

      public override Int64Message BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }

      public override Builder MergeFrom(pb::IMessage other) {
        if (other is Int64Message) {
          return MergeFrom((Int64Message) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }

      public override Builder MergeFrom(Int64Message other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.Int64Message.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(_int64MessageFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _int64MessageFieldTags[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.hasData = input.ReadInt64(ref result.data_);
              break;
            }
          }
        }

        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }


      public bool HasData {
        get { return result.hasData; }
      }
      public long Data {
        get { return result.Data; }
        set { SetData(value); }
      }
      public Builder SetData(long value) {
        PrepareBuilder();
        result.hasData = true;
        result.data_ = value;
        return this;
      }
      public Builder ClearData() {
        PrepareBuilder();
        result.hasData = false;
        result.data_ = 0L;
        return this;
      }
    }
    static Int64Message() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor, null);
    }
  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class Uint64Message : pb::GeneratedMessage<Uint64Message, Uint64Message.Builder> {
    private Uint64Message() { }
    private static readonly Uint64Message defaultInstance = new Uint64Message().MakeReadOnly();
    private static readonly string[] _uint64MessageFieldNames = new string[] { "data" };
    private static readonly uint[] _uint64MessageFieldTags = new uint[] { 8 };
    public static Uint64Message DefaultInstance {
      get { return defaultInstance; }
    }

    public override Uint64Message DefaultInstanceForType {
      get { return DefaultInstance; }
    }

    protected override Uint64Message ThisMessage {
      get { return this; }
    }

    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_Uint64Message__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<Uint64Message, Uint64Message.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_Uint64Message__FieldAccessorTable; }
    }

    public const int DataFieldNumber = 1;
    private bool hasData;
    private ulong data_;
    public bool HasData {
      get { return hasData; }
    }
    [global::System.CLSCompliant(false)]
    public ulong Data {
      get { return data_; }
    }

    public override bool IsInitialized {
      get {
        return true;
      }
    }

    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _uint64MessageFieldNames;
      if (hasData) {
        output.WriteUInt64(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.ComputeUInt64Size(1, Data);
      }
      size += UnknownFields.SerializedSize;
      memoizedSerializedSize = size;
      return size;
    }
    public static Uint64Message ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static Uint64Message ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static Uint64Message ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static Uint64Message ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static Uint64Message ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static Uint64Message ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static Uint64Message ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static Uint64Message ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static Uint64Message ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static Uint64Message ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private Uint64Message 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(Uint64Message prototype) {
      return new Builder(prototype);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<Uint64Message, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(Uint64Message cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }

      private bool resultIsReadOnly;
      private Uint64Message result;

      private Uint64Message PrepareBuilder() {
        if (resultIsReadOnly) {
          Uint64Message original = result;
          result = new Uint64Message();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }

      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }

      protected override Uint64Message 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.Uint64Message.Descriptor; }
      }

      public override Uint64Message DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.Uint64Message.DefaultInstance; }
      }

      public override Uint64Message BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }

      public override Builder MergeFrom(pb::IMessage other) {
        if (other is Uint64Message) {
          return MergeFrom((Uint64Message) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }

      public override Builder MergeFrom(Uint64Message other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.Uint64Message.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(_uint64MessageFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _uint64MessageFieldTags[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.hasData = input.ReadUInt64(ref result.data_);
              break;
            }
          }
        }

        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }


      public bool HasData {
        get { return result.hasData; }
      }
      [global::System.CLSCompliant(false)]
      public ulong Data {
        get { return result.Data; }
        set { SetData(value); }
      }
      [global::System.CLSCompliant(false)]
      public Builder SetData(ulong value) {
        PrepareBuilder();
        result.hasData = true;
        result.data_ = value;
        return this;
      }
      public Builder ClearData() {
        PrepareBuilder();
        result.hasData = false;
        result.data_ = 0UL;
        return this;
      }
    }
    static Uint64Message() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor, null);
    }
  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class BoolMessage : pb::GeneratedMessage<BoolMessage, BoolMessage.Builder> {
    private BoolMessage() { }
    private static readonly BoolMessage defaultInstance = new BoolMessage().MakeReadOnly();
    private static readonly string[] _boolMessageFieldNames = new string[] { "data" };
    private static readonly uint[] _boolMessageFieldTags = new uint[] { 8 };
    public static BoolMessage DefaultInstance {
      get { return defaultInstance; }
    }

    public override BoolMessage DefaultInstanceForType {
      get { return DefaultInstance; }
    }

    protected override BoolMessage ThisMessage {
      get { return this; }
    }

    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_BoolMessage__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<BoolMessage, BoolMessage.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_BoolMessage__FieldAccessorTable; }
    }

    public const int DataFieldNumber = 1;
    private bool hasData;
    private bool data_;
    public bool HasData {
      get { return hasData; }
    }
    public bool Data {
      get { return data_; }
    }

    public override bool IsInitialized {
      get {
        return true;
      }
    }

    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _boolMessageFieldNames;
      if (hasData) {
        output.WriteBool(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.ComputeBoolSize(1, Data);
      }
      size += UnknownFields.SerializedSize;
      memoizedSerializedSize = size;
      return size;
    }
    public static BoolMessage ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static BoolMessage ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static BoolMessage ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static BoolMessage ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static BoolMessage ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static BoolMessage ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static BoolMessage ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static BoolMessage ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static BoolMessage ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static BoolMessage ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private BoolMessage 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(BoolMessage prototype) {
      return new Builder(prototype);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<BoolMessage, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(BoolMessage cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }

      private bool resultIsReadOnly;
      private BoolMessage result;

      private BoolMessage PrepareBuilder() {
        if (resultIsReadOnly) {
          BoolMessage original = result;
          result = new BoolMessage();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }

      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }

      protected override BoolMessage 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.BoolMessage.Descriptor; }
      }

      public override BoolMessage DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.BoolMessage.DefaultInstance; }
      }

      public override BoolMessage BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }

      public override Builder MergeFrom(pb::IMessage other) {
        if (other is BoolMessage) {
          return MergeFrom((BoolMessage) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }

      public override Builder MergeFrom(BoolMessage other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.BoolMessage.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(_boolMessageFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _boolMessageFieldTags[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.hasData = input.ReadBool(ref result.data_);
              break;
            }
          }
        }

        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }


      public bool HasData {
        get { return result.hasData; }
      }
      public bool Data {
        get { return result.Data; }
        set { SetData(value); }
      }
      public Builder SetData(bool value) {
        PrepareBuilder();
        result.hasData = true;
        result.data_ = value;
        return this;
      }
      public Builder ClearData() {
        PrepareBuilder();
        result.hasData = false;
        result.data_ = false;
        return this;
      }
    }
    static BoolMessage() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor, null);
    }
  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestOneof : pb::GeneratedMessage<TestOneof, TestOneof.Builder> {
    private TestOneof() { }
    private static readonly TestOneof defaultInstance = new TestOneof().MakeReadOnly();
    private static readonly string[] _testOneofFieldNames = new string[] { "foo_int", "foo_message", "foo_string", "foogroup" };
    private static readonly uint[] _testOneofFieldTags = new uint[] { 8, 26, 18, 35 };
    public static TestOneof DefaultInstance {
      get { return defaultInstance; }
    }

    public override TestOneof DefaultInstanceForType {
      get { return DefaultInstance; }
    }

    protected override TestOneof ThisMessage {
      get { return this; }
    }

    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestOneof__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestOneof, TestOneof.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestOneof__FieldAccessorTable; }
    }

    #region Nested types
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public static partial class Types {
      [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
      public sealed partial class FooGroup : pb::GeneratedMessage<FooGroup, FooGroup.Builder> {
        private FooGroup() { }
        private static readonly FooGroup defaultInstance = new FooGroup().MakeReadOnly();
        private static readonly string[] _fooGroupFieldNames = new string[] { "a", "b" };
        private static readonly uint[] _fooGroupFieldTags = new uint[] { 40, 50 };
        public static FooGroup DefaultInstance {
          get { return defaultInstance; }
        }

        public override FooGroup DefaultInstanceForType {
          get { return DefaultInstance; }
        }

        protected override FooGroup ThisMessage {
          get { return this; }
        }

        public static pbd::MessageDescriptor Descriptor {
          get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestOneof_FooGroup__Descriptor; }
        }

        protected override pb::FieldAccess.FieldAccessorTable<FooGroup, FooGroup.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestOneof_FooGroup__FieldAccessorTable; }
        }

        public const int AFieldNumber = 5;
        private bool hasA;
        private int a_;
        public bool HasA {
          get { return hasA; }
        }
        public int A {
          get { return a_; }
        }

        public const int BFieldNumber = 6;
        private bool hasB;
        private string b_ = "";
        public bool HasB {
          get { return hasB; }
        }
        public string B {
          get { return b_; }
        }

        public override bool IsInitialized {
          get {
            return true;
          }
        }

        public override void WriteTo(pb::ICodedOutputStream output) {
          CalcSerializedSize();
          string[] field_names = _fooGroupFieldNames;
          if (hasA) {
            output.WriteInt32(5, field_names[0], A);
          }
          if (hasB) {
            output.WriteString(6, field_names[1], B);
          }
          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(5, A);
          }
          if (hasB) {
            size += pb::CodedOutputStream.ComputeStringSize(6, B);
          }
          size += UnknownFields.SerializedSize;
          memoizedSerializedSize = size;
          return size;
        }
        public static FooGroup ParseFrom(pb::ByteString data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static FooGroup ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static FooGroup ParseFrom(byte[] data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static FooGroup ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static FooGroup ParseFrom(global::System.IO.Stream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static FooGroup ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static FooGroup ParseDelimitedFrom(global::System.IO.Stream input) {
          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
        }
        public static FooGroup ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
        }
        public static FooGroup ParseFrom(pb::ICodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static FooGroup ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        private FooGroup 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(FooGroup prototype) {
          return new Builder(prototype);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public sealed partial class Builder : pb::GeneratedBuilder<FooGroup, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {
            result = DefaultInstance;
            resultIsReadOnly = true;
          }
          internal Builder(FooGroup cloneFrom) {
            result = cloneFrom;
            resultIsReadOnly = true;
          }

          private bool resultIsReadOnly;
          private FooGroup result;

          private FooGroup PrepareBuilder() {
            if (resultIsReadOnly) {
              FooGroup original = result;
              result = new FooGroup();
              resultIsReadOnly = false;
              MergeFrom(original);
            }
            return result;
          }

          public override bool IsInitialized {
            get { return result.IsInitialized; }
          }

          protected override FooGroup 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.TestOneof.Types.FooGroup.Descriptor; }
          }

          public override FooGroup DefaultInstanceForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestOneof.Types.FooGroup.DefaultInstance; }
          }

          public override FooGroup BuildPartial() {
            if (resultIsReadOnly) {
              return result;
            }
            resultIsReadOnly = true;
            return result.MakeReadOnly();
          }

          public override Builder MergeFrom(pb::IMessage other) {
            if (other is FooGroup) {
              return MergeFrom((FooGroup) other);
            } else {
              base.MergeFrom(other);
              return this;
            }
          }

          public override Builder MergeFrom(FooGroup other) {
            if (other == global::Google.ProtocolBuffers.TestProtos.TestOneof.Types.FooGroup.DefaultInstance) return this;
            PrepareBuilder();
            if (other.HasA) {
              A = other.A;
            }
            if (other.HasB) {
              B = other.B;
            }
            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(_fooGroupFieldNames, field_name, global::System.StringComparer.Ordinal);
                if(field_ordinal >= 0)
                  tag = _fooGroupFieldTags[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 40: {
                  result.hasA = input.ReadInt32(ref result.a_);
                  break;
                }
                case 50: {
                  result.hasB = input.ReadString(ref result.b_);
                  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 HasB {
            get { return result.hasB; }
          }
          public string B {
            get { return result.B; }
            set { SetB(value); }
          }
          public Builder SetB(string value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            result.hasB = true;
            result.b_ = value;
            return this;
          }
          public Builder ClearB() {
            PrepareBuilder();
            result.hasB = false;
            result.b_ = "";
            return this;
          }
        }
        static FooGroup() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor, null);
        }
      }

    }
    #endregion

    public const int FooIntFieldNumber = 1;
    private bool hasFooInt;
    private int fooInt_;
    public bool HasFooInt {
      get { return hasFooInt; }
    }
    public int FooInt {
      get { return fooInt_; }
    }

    public const int FooStringFieldNumber = 2;
    private bool hasFooString;
    private string fooString_ = "";
    public bool HasFooString {
      get { return hasFooString; }
    }
    public string FooString {
      get { return fooString_; }
    }

    public const int FooMessageFieldNumber = 3;
    private bool hasFooMessage;
    private global::Google.ProtocolBuffers.TestProtos.TestAllTypes fooMessage_;
    public bool HasFooMessage {
      get { return hasFooMessage; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes FooMessage {
      get { return fooMessage_ ?? global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance; }
    }

    public const int FooGroupFieldNumber = 4;
    private bool hasFooGroup;
    private global::Google.ProtocolBuffers.TestProtos.TestOneof.Types.FooGroup fooGroup_;
    public bool HasFooGroup {
      get { return hasFooGroup; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestOneof.Types.FooGroup FooGroup {
      get { return fooGroup_ ?? global::Google.ProtocolBuffers.TestProtos.TestOneof.Types.FooGroup.DefaultInstance; }
    }

    public override bool IsInitialized {
      get {
        return true;
      }
    }

    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _testOneofFieldNames;
      if (hasFooInt) {
        output.WriteInt32(1, field_names[0], FooInt);
      }
      if (hasFooString) {
        output.WriteString(2, field_names[2], FooString);
      }
      if (hasFooMessage) {
        output.WriteMessage(3, field_names[1], FooMessage);
      }
      if (hasFooGroup) {
        output.WriteGroup(4, field_names[3], FooGroup);
      }
      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 (hasFooInt) {
        size += pb::CodedOutputStream.ComputeInt32Size(1, FooInt);
      }
      if (hasFooString) {
        size += pb::CodedOutputStream.ComputeStringSize(2, FooString);
      }
      if (hasFooMessage) {
        size += pb::CodedOutputStream.ComputeMessageSize(3, FooMessage);
      }
      if (hasFooGroup) {
        size += pb::CodedOutputStream.ComputeGroupSize(4, FooGroup);
      }
      size += UnknownFields.SerializedSize;
      memoizedSerializedSize = size;
      return size;
    }
    public static TestOneof ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestOneof ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestOneof ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestOneof ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestOneof ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestOneof ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestOneof ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestOneof ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestOneof ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestOneof ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestOneof 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(TestOneof prototype) {
      return new Builder(prototype);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestOneof, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestOneof cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }

      private bool resultIsReadOnly;
      private TestOneof result;

      private TestOneof PrepareBuilder() {
        if (resultIsReadOnly) {
          TestOneof original = result;
          result = new TestOneof();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }

      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }

      protected override TestOneof 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.TestOneof.Descriptor; }
      }

      public override TestOneof DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestOneof.DefaultInstance; }
      }

      public override TestOneof BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }

      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestOneof) {
          return MergeFrom((TestOneof) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }

      public override Builder MergeFrom(TestOneof other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestOneof.DefaultInstance) return this;
        PrepareBuilder();
        if (other.HasFooInt) {
          FooInt = other.FooInt;
        }
        if (other.HasFooString) {
          FooString = other.FooString;
        }
        if (other.HasFooMessage) {
          MergeFooMessage(other.FooMessage);
        }
        if (other.HasFooGroup) {
          MergeFooGroup(other.FooGroup);
        }
        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(_testOneofFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testOneofFieldTags[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.hasFooInt = input.ReadInt32(ref result.fooInt_);
              break;
            }
            case 18: {
              result.hasFooString = input.ReadString(ref result.fooString_);
              break;
            }
            case 26: {
              global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder();
              if (result.hasFooMessage) {
                subBuilder.MergeFrom(FooMessage);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              FooMessage = subBuilder.BuildPartial();
              break;
            }
            case 35: {
              global::Google.ProtocolBuffers.TestProtos.TestOneof.Types.FooGroup.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestOneof.Types.FooGroup.CreateBuilder();
              if (result.hasFooGroup) {
                subBuilder.MergeFrom(FooGroup);
              }
              input.ReadGroup(4, subBuilder, extensionRegistry);
              FooGroup = subBuilder.BuildPartial();
              break;
            }
          }
        }

        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }


      public bool HasFooInt {
        get { return result.hasFooInt; }
      }
      public int FooInt {
        get { return result.FooInt; }
        set { SetFooInt(value); }
      }
      public Builder SetFooInt(int value) {
        PrepareBuilder();
        result.hasFooInt = true;
        result.fooInt_ = value;
        return this;
      }
      public Builder ClearFooInt() {
        PrepareBuilder();
        result.hasFooInt = false;
        result.fooInt_ = 0;
        return this;
      }

      public bool HasFooString {
        get { return result.hasFooString; }
      }
      public string FooString {
        get { return result.FooString; }
        set { SetFooString(value); }
      }
      public Builder SetFooString(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasFooString = true;
        result.fooString_ = value;
        return this;
      }
      public Builder ClearFooString() {
        PrepareBuilder();
        result.hasFooString = false;
        result.fooString_ = "";
        return this;
      }

      public bool HasFooMessage {
       get { return result.hasFooMessage; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestAllTypes FooMessage {
        get { return result.FooMessage; }
        set { SetFooMessage(value); }
      }
      public Builder SetFooMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasFooMessage = true;
        result.fooMessage_ = value;
        return this;
      }
      public Builder SetFooMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasFooMessage = true;
        result.fooMessage_ = builderForValue.Build();
        return this;
      }
      public Builder MergeFooMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        if (result.hasFooMessage &&
            result.fooMessage_ != global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance) {
            result.fooMessage_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder(result.fooMessage_).MergeFrom(value).BuildPartial();
        } else {
          result.fooMessage_ = value;
        }
        result.hasFooMessage = true;
        return this;
      }
      public Builder ClearFooMessage() {
        PrepareBuilder();
        result.hasFooMessage = false;
        result.fooMessage_ = null;
        return this;
      }

      public bool HasFooGroup {
       get { return result.hasFooGroup; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestOneof.Types.FooGroup FooGroup {
        get { return result.FooGroup; }
        set { SetFooGroup(value); }
      }
      public Builder SetFooGroup(global::Google.ProtocolBuffers.TestProtos.TestOneof.Types.FooGroup value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasFooGroup = true;
        result.fooGroup_ = value;
        return this;
      }
      public Builder SetFooGroup(global::Google.ProtocolBuffers.TestProtos.TestOneof.Types.FooGroup.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasFooGroup = true;
        result.fooGroup_ = builderForValue.Build();
        return this;
      }
      public Builder MergeFooGroup(global::Google.ProtocolBuffers.TestProtos.TestOneof.Types.FooGroup value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        if (result.hasFooGroup &&
            result.fooGroup_ != global::Google.ProtocolBuffers.TestProtos.TestOneof.Types.FooGroup.DefaultInstance) {
            result.fooGroup_ = global::Google.ProtocolBuffers.TestProtos.TestOneof.Types.FooGroup.CreateBuilder(result.fooGroup_).MergeFrom(value).BuildPartial();
        } else {
          result.fooGroup_ = value;
        }
        result.hasFooGroup = true;
        return this;
      }
      public Builder ClearFooGroup() {
        PrepareBuilder();
        result.hasFooGroup = false;
        result.fooGroup_ = null;
        return this;
      }
    }
    static TestOneof() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor, null);
    }
  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestOneofBackwardsCompatible : pb::GeneratedMessage<TestOneofBackwardsCompatible, TestOneofBackwardsCompatible.Builder> {
    private TestOneofBackwardsCompatible() { }
    private static readonly TestOneofBackwardsCompatible defaultInstance = new TestOneofBackwardsCompatible().MakeReadOnly();
    private static readonly string[] _testOneofBackwardsCompatibleFieldNames = new string[] { "foo_int", "foo_message", "foo_string", "foogroup" };
    private static readonly uint[] _testOneofBackwardsCompatibleFieldTags = new uint[] { 8, 26, 18, 35 };
    public static TestOneofBackwardsCompatible DefaultInstance {
      get { return defaultInstance; }
    }

    public override TestOneofBackwardsCompatible DefaultInstanceForType {
      get { return DefaultInstance; }
    }

    protected override TestOneofBackwardsCompatible ThisMessage {
      get { return this; }
    }

    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestOneofBackwardsCompatible__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestOneofBackwardsCompatible, TestOneofBackwardsCompatible.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestOneofBackwardsCompatible__FieldAccessorTable; }
    }

    #region Nested types
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public static partial class Types {
      [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
      public sealed partial class FooGroup : pb::GeneratedMessage<FooGroup, FooGroup.Builder> {
        private FooGroup() { }
        private static readonly FooGroup defaultInstance = new FooGroup().MakeReadOnly();
        private static readonly string[] _fooGroupFieldNames = new string[] { "a", "b" };
        private static readonly uint[] _fooGroupFieldTags = new uint[] { 40, 50 };
        public static FooGroup DefaultInstance {
          get { return defaultInstance; }
        }

        public override FooGroup DefaultInstanceForType {
          get { return DefaultInstance; }
        }

        protected override FooGroup ThisMessage {
          get { return this; }
        }

        public static pbd::MessageDescriptor Descriptor {
          get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestOneofBackwardsCompatible_FooGroup__Descriptor; }
        }

        protected override pb::FieldAccess.FieldAccessorTable<FooGroup, FooGroup.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestOneofBackwardsCompatible_FooGroup__FieldAccessorTable; }
        }

        public const int AFieldNumber = 5;
        private bool hasA;
        private int a_;
        public bool HasA {
          get { return hasA; }
        }
        public int A {
          get { return a_; }
        }

        public const int BFieldNumber = 6;
        private bool hasB;
        private string b_ = "";
        public bool HasB {
          get { return hasB; }
        }
        public string B {
          get { return b_; }
        }

        public override bool IsInitialized {
          get {
            return true;
          }
        }

        public override void WriteTo(pb::ICodedOutputStream output) {
          CalcSerializedSize();
          string[] field_names = _fooGroupFieldNames;
          if (hasA) {
            output.WriteInt32(5, field_names[0], A);
          }
          if (hasB) {
            output.WriteString(6, field_names[1], B);
          }
          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(5, A);
          }
          if (hasB) {
            size += pb::CodedOutputStream.ComputeStringSize(6, B);
          }
          size += UnknownFields.SerializedSize;
          memoizedSerializedSize = size;
          return size;
        }
        public static FooGroup ParseFrom(pb::ByteString data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static FooGroup ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static FooGroup ParseFrom(byte[] data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static FooGroup ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static FooGroup ParseFrom(global::System.IO.Stream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static FooGroup ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static FooGroup ParseDelimitedFrom(global::System.IO.Stream input) {
          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
        }
        public static FooGroup ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
        }
        public static FooGroup ParseFrom(pb::ICodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static FooGroup ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        private FooGroup 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(FooGroup prototype) {
          return new Builder(prototype);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public sealed partial class Builder : pb::GeneratedBuilder<FooGroup, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {
            result = DefaultInstance;
            resultIsReadOnly = true;
          }
          internal Builder(FooGroup cloneFrom) {
            result = cloneFrom;
            resultIsReadOnly = true;
          }

          private bool resultIsReadOnly;
          private FooGroup result;

          private FooGroup PrepareBuilder() {
            if (resultIsReadOnly) {
              FooGroup original = result;
              result = new FooGroup();
              resultIsReadOnly = false;
              MergeFrom(original);
            }
            return result;
          }

          public override bool IsInitialized {
            get { return result.IsInitialized; }
          }

          protected override FooGroup 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.TestOneofBackwardsCompatible.Types.FooGroup.Descriptor; }
          }

          public override FooGroup DefaultInstanceForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestOneofBackwardsCompatible.Types.FooGroup.DefaultInstance; }
          }

          public override FooGroup BuildPartial() {
            if (resultIsReadOnly) {
              return result;
            }
            resultIsReadOnly = true;
            return result.MakeReadOnly();
          }

          public override Builder MergeFrom(pb::IMessage other) {
            if (other is FooGroup) {
              return MergeFrom((FooGroup) other);
            } else {
              base.MergeFrom(other);
              return this;
            }
          }

          public override Builder MergeFrom(FooGroup other) {
            if (other == global::Google.ProtocolBuffers.TestProtos.TestOneofBackwardsCompatible.Types.FooGroup.DefaultInstance) return this;
            PrepareBuilder();
            if (other.HasA) {
              A = other.A;
            }
            if (other.HasB) {
              B = other.B;
            }
            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(_fooGroupFieldNames, field_name, global::System.StringComparer.Ordinal);
                if(field_ordinal >= 0)
                  tag = _fooGroupFieldTags[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 40: {
                  result.hasA = input.ReadInt32(ref result.a_);
                  break;
                }
                case 50: {
                  result.hasB = input.ReadString(ref result.b_);
                  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 HasB {
            get { return result.hasB; }
          }
          public string B {
            get { return result.B; }
            set { SetB(value); }
          }
          public Builder SetB(string value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            result.hasB = true;
            result.b_ = value;
            return this;
          }
          public Builder ClearB() {
            PrepareBuilder();
            result.hasB = false;
            result.b_ = "";
            return this;
          }
        }
        static FooGroup() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor, null);
        }
      }

    }
    #endregion

    public const int FooIntFieldNumber = 1;
    private bool hasFooInt;
    private int fooInt_;
    public bool HasFooInt {
      get { return hasFooInt; }
    }
    public int FooInt {
      get { return fooInt_; }
    }

    public const int FooStringFieldNumber = 2;
    private bool hasFooString;
    private string fooString_ = "";
    public bool HasFooString {
      get { return hasFooString; }
    }
    public string FooString {
      get { return fooString_; }
    }

    public const int FooMessageFieldNumber = 3;
    private bool hasFooMessage;
    private global::Google.ProtocolBuffers.TestProtos.TestAllTypes fooMessage_;
    public bool HasFooMessage {
      get { return hasFooMessage; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes FooMessage {
      get { return fooMessage_ ?? global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance; }
    }

    public const int FooGroupFieldNumber = 4;
    private bool hasFooGroup;
    private global::Google.ProtocolBuffers.TestProtos.TestOneofBackwardsCompatible.Types.FooGroup fooGroup_;
    public bool HasFooGroup {
      get { return hasFooGroup; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestOneofBackwardsCompatible.Types.FooGroup FooGroup {
      get { return fooGroup_ ?? global::Google.ProtocolBuffers.TestProtos.TestOneofBackwardsCompatible.Types.FooGroup.DefaultInstance; }
    }

    public override bool IsInitialized {
      get {
        return true;
      }
    }

    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _testOneofBackwardsCompatibleFieldNames;
      if (hasFooInt) {
        output.WriteInt32(1, field_names[0], FooInt);
      }
      if (hasFooString) {
        output.WriteString(2, field_names[2], FooString);
      }
      if (hasFooMessage) {
        output.WriteMessage(3, field_names[1], FooMessage);
      }
      if (hasFooGroup) {
        output.WriteGroup(4, field_names[3], FooGroup);
      }
      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 (hasFooInt) {
        size += pb::CodedOutputStream.ComputeInt32Size(1, FooInt);
      }
      if (hasFooString) {
        size += pb::CodedOutputStream.ComputeStringSize(2, FooString);
      }
      if (hasFooMessage) {
        size += pb::CodedOutputStream.ComputeMessageSize(3, FooMessage);
      }
      if (hasFooGroup) {
        size += pb::CodedOutputStream.ComputeGroupSize(4, FooGroup);
      }
      size += UnknownFields.SerializedSize;
      memoizedSerializedSize = size;
      return size;
    }
    public static TestOneofBackwardsCompatible ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestOneofBackwardsCompatible ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestOneofBackwardsCompatible ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestOneofBackwardsCompatible ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestOneofBackwardsCompatible ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestOneofBackwardsCompatible ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestOneofBackwardsCompatible ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestOneofBackwardsCompatible ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestOneofBackwardsCompatible ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestOneofBackwardsCompatible ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestOneofBackwardsCompatible 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(TestOneofBackwardsCompatible prototype) {
      return new Builder(prototype);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestOneofBackwardsCompatible, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestOneofBackwardsCompatible cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }

      private bool resultIsReadOnly;
      private TestOneofBackwardsCompatible result;

      private TestOneofBackwardsCompatible PrepareBuilder() {
        if (resultIsReadOnly) {
          TestOneofBackwardsCompatible original = result;
          result = new TestOneofBackwardsCompatible();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }

      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }

      protected override TestOneofBackwardsCompatible 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.TestOneofBackwardsCompatible.Descriptor; }
      }

      public override TestOneofBackwardsCompatible DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestOneofBackwardsCompatible.DefaultInstance; }
      }

      public override TestOneofBackwardsCompatible BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }

      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestOneofBackwardsCompatible) {
          return MergeFrom((TestOneofBackwardsCompatible) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }

      public override Builder MergeFrom(TestOneofBackwardsCompatible other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestOneofBackwardsCompatible.DefaultInstance) return this;
        PrepareBuilder();
        if (other.HasFooInt) {
          FooInt = other.FooInt;
        }
        if (other.HasFooString) {
          FooString = other.FooString;
        }
        if (other.HasFooMessage) {
          MergeFooMessage(other.FooMessage);
        }
        if (other.HasFooGroup) {
          MergeFooGroup(other.FooGroup);
        }
        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(_testOneofBackwardsCompatibleFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testOneofBackwardsCompatibleFieldTags[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.hasFooInt = input.ReadInt32(ref result.fooInt_);
              break;
            }
            case 18: {
              result.hasFooString = input.ReadString(ref result.fooString_);
              break;
            }
            case 26: {
              global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder();
              if (result.hasFooMessage) {
                subBuilder.MergeFrom(FooMessage);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              FooMessage = subBuilder.BuildPartial();
              break;
            }
            case 35: {
              global::Google.ProtocolBuffers.TestProtos.TestOneofBackwardsCompatible.Types.FooGroup.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestOneofBackwardsCompatible.Types.FooGroup.CreateBuilder();
              if (result.hasFooGroup) {
                subBuilder.MergeFrom(FooGroup);
              }
              input.ReadGroup(4, subBuilder, extensionRegistry);
              FooGroup = subBuilder.BuildPartial();
              break;
            }
          }
        }

        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }


      public bool HasFooInt {
        get { return result.hasFooInt; }
      }
      public int FooInt {
        get { return result.FooInt; }
        set { SetFooInt(value); }
      }
      public Builder SetFooInt(int value) {
        PrepareBuilder();
        result.hasFooInt = true;
        result.fooInt_ = value;
        return this;
      }
      public Builder ClearFooInt() {
        PrepareBuilder();
        result.hasFooInt = false;
        result.fooInt_ = 0;
        return this;
      }

      public bool HasFooString {
        get { return result.hasFooString; }
      }
      public string FooString {
        get { return result.FooString; }
        set { SetFooString(value); }
      }
      public Builder SetFooString(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasFooString = true;
        result.fooString_ = value;
        return this;
      }
      public Builder ClearFooString() {
        PrepareBuilder();
        result.hasFooString = false;
        result.fooString_ = "";
        return this;
      }

      public bool HasFooMessage {
       get { return result.hasFooMessage; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestAllTypes FooMessage {
        get { return result.FooMessage; }
        set { SetFooMessage(value); }
      }
      public Builder SetFooMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasFooMessage = true;
        result.fooMessage_ = value;
        return this;
      }
      public Builder SetFooMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasFooMessage = true;
        result.fooMessage_ = builderForValue.Build();
        return this;
      }
      public Builder MergeFooMessage(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        if (result.hasFooMessage &&
            result.fooMessage_ != global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance) {
            result.fooMessage_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder(result.fooMessage_).MergeFrom(value).BuildPartial();
        } else {
          result.fooMessage_ = value;
        }
        result.hasFooMessage = true;
        return this;
      }
      public Builder ClearFooMessage() {
        PrepareBuilder();
        result.hasFooMessage = false;
        result.fooMessage_ = null;
        return this;
      }

      public bool HasFooGroup {
       get { return result.hasFooGroup; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestOneofBackwardsCompatible.Types.FooGroup FooGroup {
        get { return result.FooGroup; }
        set { SetFooGroup(value); }
      }
      public Builder SetFooGroup(global::Google.ProtocolBuffers.TestProtos.TestOneofBackwardsCompatible.Types.FooGroup value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasFooGroup = true;
        result.fooGroup_ = value;
        return this;
      }
      public Builder SetFooGroup(global::Google.ProtocolBuffers.TestProtos.TestOneofBackwardsCompatible.Types.FooGroup.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasFooGroup = true;
        result.fooGroup_ = builderForValue.Build();
        return this;
      }
      public Builder MergeFooGroup(global::Google.ProtocolBuffers.TestProtos.TestOneofBackwardsCompatible.Types.FooGroup value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        if (result.hasFooGroup &&
            result.fooGroup_ != global::Google.ProtocolBuffers.TestProtos.TestOneofBackwardsCompatible.Types.FooGroup.DefaultInstance) {
            result.fooGroup_ = global::Google.ProtocolBuffers.TestProtos.TestOneofBackwardsCompatible.Types.FooGroup.CreateBuilder(result.fooGroup_).MergeFrom(value).BuildPartial();
        } else {
          result.fooGroup_ = value;
        }
        result.hasFooGroup = true;
        return this;
      }
      public Builder ClearFooGroup() {
        PrepareBuilder();
        result.hasFooGroup = false;
        result.fooGroup_ = null;
        return this;
      }
    }
    static TestOneofBackwardsCompatible() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor, null);
    }
  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestOneof2 : pb::GeneratedMessage<TestOneof2, TestOneof2.Builder> {
    private TestOneof2() { }
    private static readonly TestOneof2 defaultInstance = new TestOneof2().MakeReadOnly();
    private static readonly string[] _testOneof2FieldNames = new string[] { "bar_bytes", "bar_cord", "bar_enum", "bar_int", "bar_string", "bar_string_piece", "baz_int", "baz_string", "foo_bytes", "foo_cord", "foo_enum", "foo_int", "foo_lazy_message", "foo_message", "foo_string", "foo_string_piece", "foogroup" };
    private static readonly uint[] _testOneof2FieldTags = new uint[] { 130, 114, 136, 96, 106, 122, 144, 154, 42, 26, 48, 8, 90, 58, 18, 34, 67 };
    public static TestOneof2 DefaultInstance {
      get { return defaultInstance; }
    }

    public override TestOneof2 DefaultInstanceForType {
      get { return DefaultInstance; }
    }

    protected override TestOneof2 ThisMessage {
      get { return this; }
    }

    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestOneof2__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestOneof2, TestOneof2.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestOneof2__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 FooGroup : pb::GeneratedMessage<FooGroup, FooGroup.Builder> {
        private FooGroup() { }
        private static readonly FooGroup defaultInstance = new FooGroup().MakeReadOnly();
        private static readonly string[] _fooGroupFieldNames = new string[] { "a", "b" };
        private static readonly uint[] _fooGroupFieldTags = new uint[] { 72, 82 };
        public static FooGroup DefaultInstance {
          get { return defaultInstance; }
        }

        public override FooGroup DefaultInstanceForType {
          get { return DefaultInstance; }
        }

        protected override FooGroup ThisMessage {
          get { return this; }
        }

        public static pbd::MessageDescriptor Descriptor {
          get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestOneof2_FooGroup__Descriptor; }
        }

        protected override pb::FieldAccess.FieldAccessorTable<FooGroup, FooGroup.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestOneof2_FooGroup__FieldAccessorTable; }
        }

        public const int AFieldNumber = 9;
        private bool hasA;
        private int a_;
        public bool HasA {
          get { return hasA; }
        }
        public int A {
          get { return a_; }
        }

        public const int BFieldNumber = 10;
        private bool hasB;
        private string b_ = "";
        public bool HasB {
          get { return hasB; }
        }
        public string B {
          get { return b_; }
        }

        public override bool IsInitialized {
          get {
            return true;
          }
        }

        public override void WriteTo(pb::ICodedOutputStream output) {
          CalcSerializedSize();
          string[] field_names = _fooGroupFieldNames;
          if (hasA) {
            output.WriteInt32(9, field_names[0], A);
          }
          if (hasB) {
            output.WriteString(10, field_names[1], B);
          }
          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(9, A);
          }
          if (hasB) {
            size += pb::CodedOutputStream.ComputeStringSize(10, B);
          }
          size += UnknownFields.SerializedSize;
          memoizedSerializedSize = size;
          return size;
        }
        public static FooGroup ParseFrom(pb::ByteString data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static FooGroup ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static FooGroup ParseFrom(byte[] data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static FooGroup ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static FooGroup ParseFrom(global::System.IO.Stream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static FooGroup ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static FooGroup ParseDelimitedFrom(global::System.IO.Stream input) {
          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
        }
        public static FooGroup ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
        }
        public static FooGroup ParseFrom(pb::ICodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static FooGroup ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        private FooGroup 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(FooGroup prototype) {
          return new Builder(prototype);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public sealed partial class Builder : pb::GeneratedBuilder<FooGroup, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {
            result = DefaultInstance;
            resultIsReadOnly = true;
          }
          internal Builder(FooGroup cloneFrom) {
            result = cloneFrom;
            resultIsReadOnly = true;
          }

          private bool resultIsReadOnly;
          private FooGroup result;

          private FooGroup PrepareBuilder() {
            if (resultIsReadOnly) {
              FooGroup original = result;
              result = new FooGroup();
              resultIsReadOnly = false;
              MergeFrom(original);
            }
            return result;
          }

          public override bool IsInitialized {
            get { return result.IsInitialized; }
          }

          protected override FooGroup 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.TestOneof2.Types.FooGroup.Descriptor; }
          }

          public override FooGroup DefaultInstanceForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.FooGroup.DefaultInstance; }
          }

          public override FooGroup BuildPartial() {
            if (resultIsReadOnly) {
              return result;
            }
            resultIsReadOnly = true;
            return result.MakeReadOnly();
          }

          public override Builder MergeFrom(pb::IMessage other) {
            if (other is FooGroup) {
              return MergeFrom((FooGroup) other);
            } else {
              base.MergeFrom(other);
              return this;
            }
          }

          public override Builder MergeFrom(FooGroup other) {
            if (other == global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.FooGroup.DefaultInstance) return this;
            PrepareBuilder();
            if (other.HasA) {
              A = other.A;
            }
            if (other.HasB) {
              B = other.B;
            }
            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(_fooGroupFieldNames, field_name, global::System.StringComparer.Ordinal);
                if(field_ordinal >= 0)
                  tag = _fooGroupFieldTags[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 72: {
                  result.hasA = input.ReadInt32(ref result.a_);
                  break;
                }
                case 82: {
                  result.hasB = input.ReadString(ref result.b_);
                  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 HasB {
            get { return result.hasB; }
          }
          public string B {
            get { return result.B; }
            set { SetB(value); }
          }
          public Builder SetB(string value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            result.hasB = true;
            result.b_ = value;
            return this;
          }
          public Builder ClearB() {
            PrepareBuilder();
            result.hasB = false;
            result.b_ = "";
            return this;
          }
        }
        static FooGroup() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor, null);
        }
      }

      [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[] { "corge_int", "qux_int" };
        private static readonly uint[] _nestedMessageFieldTags = new uint[] { 16, 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.Unittest.internal__static_protobuf_unittest_TestOneof2_NestedMessage__Descriptor; }
        }

        protected override pb::FieldAccess.FieldAccessorTable<NestedMessage, NestedMessage.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestOneof2_NestedMessage__FieldAccessorTable; }
        }

        public const int QuxIntFieldNumber = 1;
        private bool hasQuxInt;
        private long quxInt_;
        public bool HasQuxInt {
          get { return hasQuxInt; }
        }
        public long QuxInt {
          get { return quxInt_; }
        }

        public const int CorgeIntFieldNumber = 2;
        private pbc::PopsicleList<int> corgeInt_ = new pbc::PopsicleList<int>();
        public scg::IList<int> CorgeIntList {
          get { return pbc::Lists.AsReadOnly(corgeInt_); }
        }
        public int CorgeIntCount {
          get { return corgeInt_.Count; }
        }
        public int GetCorgeInt(int index) {
          return corgeInt_[index];
        }

        public override bool IsInitialized {
          get {
            return true;
          }
        }

        public override void WriteTo(pb::ICodedOutputStream output) {
          CalcSerializedSize();
          string[] field_names = _nestedMessageFieldNames;
          if (hasQuxInt) {
            output.WriteInt64(1, field_names[1], QuxInt);
          }
          if (corgeInt_.Count > 0) {
            output.WriteInt32Array(2, field_names[0], corgeInt_);
          }
          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 (hasQuxInt) {
            size += pb::CodedOutputStream.ComputeInt64Size(1, QuxInt);
          }
          {
            int dataSize = 0;
            foreach (int element in CorgeIntList) {
              dataSize += pb::CodedOutputStream.ComputeInt32SizeNoTag(element);
            }
            size += dataSize;
            size += 1 * corgeInt_.Count;
          }
          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() {
          corgeInt_.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.TestOneof2.Types.NestedMessage.Descriptor; }
          }

          public override NestedMessage DefaultInstanceForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestOneof2.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.TestOneof2.Types.NestedMessage.DefaultInstance) return this;
            PrepareBuilder();
            if (other.HasQuxInt) {
              QuxInt = other.QuxInt;
            }
            if (other.corgeInt_.Count != 0) {
              result.corgeInt_.Add(other.corgeInt_);
            }
            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.hasQuxInt = input.ReadInt64(ref result.quxInt_);
                  break;
                }
                case 18:
                case 16: {
                  input.ReadInt32Array(tag, field_name, result.corgeInt_);
                  break;
                }
              }
            }

            if (unknownFields != null) {
              this.UnknownFields = unknownFields.Build();
            }
            return this;
          }


          public bool HasQuxInt {
            get { return result.hasQuxInt; }
          }
          public long QuxInt {
            get { return result.QuxInt; }
            set { SetQuxInt(value); }
          }
          public Builder SetQuxInt(long value) {
            PrepareBuilder();
            result.hasQuxInt = true;
            result.quxInt_ = value;
            return this;
          }
          public Builder ClearQuxInt() {
            PrepareBuilder();
            result.hasQuxInt = false;
            result.quxInt_ = 0L;
            return this;
          }

          public pbc::IPopsicleList<int> CorgeIntList {
            get { return PrepareBuilder().corgeInt_; }
          }
          public int CorgeIntCount {
            get { return result.CorgeIntCount; }
          }
          public int GetCorgeInt(int index) {
            return result.GetCorgeInt(index);
          }
          public Builder SetCorgeInt(int index, int value) {
            PrepareBuilder();
            result.corgeInt_[index] = value;
            return this;
          }
          public Builder AddCorgeInt(int value) {
            PrepareBuilder();
            result.corgeInt_.Add(value);
            return this;
          }
          public Builder AddRangeCorgeInt(scg::IEnumerable<int> values) {
            PrepareBuilder();
            result.corgeInt_.Add(values);
            return this;
          }
          public Builder ClearCorgeInt() {
            PrepareBuilder();
            result.corgeInt_.Clear();
            return this;
          }
        }
        static NestedMessage() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor, null);
        }
      }

    }
    #endregion

    public const int FooIntFieldNumber = 1;
    private bool hasFooInt;
    private int fooInt_;
    public bool HasFooInt {
      get { return hasFooInt; }
    }
    public int FooInt {
      get { return fooInt_; }
    }

    public const int FooStringFieldNumber = 2;
    private bool hasFooString;
    private string fooString_ = "";
    public bool HasFooString {
      get { return hasFooString; }
    }
    public string FooString {
      get { return fooString_; }
    }

    public const int FooCordFieldNumber = 3;
    private bool hasFooCord;
    private string fooCord_ = "";
    public bool HasFooCord {
      get { return hasFooCord; }
    }
    public string FooCord {
      get { return fooCord_; }
    }

    public const int FooStringPieceFieldNumber = 4;
    private bool hasFooStringPiece;
    private string fooStringPiece_ = "";
    public bool HasFooStringPiece {
      get { return hasFooStringPiece; }
    }
    public string FooStringPiece {
      get { return fooStringPiece_; }
    }

    public const int FooBytesFieldNumber = 5;
    private bool hasFooBytes;
    private pb::ByteString fooBytes_ = pb::ByteString.Empty;
    public bool HasFooBytes {
      get { return hasFooBytes; }
    }
    public pb::ByteString FooBytes {
      get { return fooBytes_; }
    }

    public const int FooEnumFieldNumber = 6;
    private bool hasFooEnum;
    private global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedEnum fooEnum_ = global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedEnum.FOO;
    public bool HasFooEnum {
      get { return hasFooEnum; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedEnum FooEnum {
      get { return fooEnum_; }
    }

    public const int FooMessageFieldNumber = 7;
    private bool hasFooMessage;
    private global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage fooMessage_;
    public bool HasFooMessage {
      get { return hasFooMessage; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage FooMessage {
      get { return fooMessage_ ?? global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage.DefaultInstance; }
    }

    public const int FooGroupFieldNumber = 8;
    private bool hasFooGroup;
    private global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.FooGroup fooGroup_;
    public bool HasFooGroup {
      get { return hasFooGroup; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.FooGroup FooGroup {
      get { return fooGroup_ ?? global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.FooGroup.DefaultInstance; }
    }

    public const int FooLazyMessageFieldNumber = 11;
    private bool hasFooLazyMessage;
    private global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage fooLazyMessage_;
    public bool HasFooLazyMessage {
      get { return hasFooLazyMessage; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage FooLazyMessage {
      get { return fooLazyMessage_ ?? global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage.DefaultInstance; }
    }

    public const int BarIntFieldNumber = 12;
    private bool hasBarInt;
    private int barInt_ = 5;
    public bool HasBarInt {
      get { return hasBarInt; }
    }
    public int BarInt {
      get { return barInt_; }
    }

    public const int BarStringFieldNumber = 13;
    private bool hasBarString;
    private string barString_ = "STRING";
    public bool HasBarString {
      get { return hasBarString; }
    }
    public string BarString {
      get { return barString_; }
    }

    public const int BarCordFieldNumber = 14;
    private bool hasBarCord;
    private string barCord_ = "CORD";
    public bool HasBarCord {
      get { return hasBarCord; }
    }
    public string BarCord {
      get { return barCord_; }
    }

    public const int BarStringPieceFieldNumber = 15;
    private bool hasBarStringPiece;
    private string barStringPiece_ = "SPIECE";
    public bool HasBarStringPiece {
      get { return hasBarStringPiece; }
    }
    public string BarStringPiece {
      get { return barStringPiece_; }
    }

    public const int BarBytesFieldNumber = 16;
    private bool hasBarBytes;
    private pb::ByteString barBytes_ = (pb::ByteString) global::Google.ProtocolBuffers.TestProtos.TestOneof2.Descriptor.Fields[13].DefaultValue;
    public bool HasBarBytes {
      get { return hasBarBytes; }
    }
    public pb::ByteString BarBytes {
      get { return barBytes_; }
    }

    public const int BarEnumFieldNumber = 17;
    private bool hasBarEnum;
    private global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedEnum barEnum_ = global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedEnum.BAR;
    public bool HasBarEnum {
      get { return hasBarEnum; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedEnum BarEnum {
      get { return barEnum_; }
    }

    public const int BazIntFieldNumber = 18;
    private bool hasBazInt;
    private int bazInt_;
    public bool HasBazInt {
      get { return hasBazInt; }
    }
    public int BazInt {
      get { return bazInt_; }
    }

    public const int BazStringFieldNumber = 19;
    private bool hasBazString;
    private string bazString_ = "BAZ";
    public bool HasBazString {
      get { return hasBazString; }
    }
    public string BazString {
      get { return bazString_; }
    }

    public override bool IsInitialized {
      get {
        return true;
      }
    }

    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _testOneof2FieldNames;
      if (hasFooInt) {
        output.WriteInt32(1, field_names[11], FooInt);
      }
      if (hasFooString) {
        output.WriteString(2, field_names[14], FooString);
      }
      if (hasFooCord) {
        output.WriteString(3, field_names[9], FooCord);
      }
      if (hasFooStringPiece) {
        output.WriteString(4, field_names[15], FooStringPiece);
      }
      if (hasFooBytes) {
        output.WriteBytes(5, field_names[8], FooBytes);
      }
      if (hasFooEnum) {
        output.WriteEnum(6, field_names[10], (int) FooEnum, FooEnum);
      }
      if (hasFooMessage) {
        output.WriteMessage(7, field_names[13], FooMessage);
      }
      if (hasFooGroup) {
        output.WriteGroup(8, field_names[16], FooGroup);
      }
      if (hasFooLazyMessage) {
        output.WriteMessage(11, field_names[12], FooLazyMessage);
      }
      if (hasBarInt) {
        output.WriteInt32(12, field_names[3], BarInt);
      }
      if (hasBarString) {
        output.WriteString(13, field_names[4], BarString);
      }
      if (hasBarCord) {
        output.WriteString(14, field_names[1], BarCord);
      }
      if (hasBarStringPiece) {
        output.WriteString(15, field_names[5], BarStringPiece);
      }
      if (hasBarBytes) {
        output.WriteBytes(16, field_names[0], BarBytes);
      }
      if (hasBarEnum) {
        output.WriteEnum(17, field_names[2], (int) BarEnum, BarEnum);
      }
      if (hasBazInt) {
        output.WriteInt32(18, field_names[6], BazInt);
      }
      if (hasBazString) {
        output.WriteString(19, field_names[7], BazString);
      }
      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 (hasFooInt) {
        size += pb::CodedOutputStream.ComputeInt32Size(1, FooInt);
      }
      if (hasFooString) {
        size += pb::CodedOutputStream.ComputeStringSize(2, FooString);
      }
      if (hasFooCord) {
        size += pb::CodedOutputStream.ComputeStringSize(3, FooCord);
      }
      if (hasFooStringPiece) {
        size += pb::CodedOutputStream.ComputeStringSize(4, FooStringPiece);
      }
      if (hasFooBytes) {
        size += pb::CodedOutputStream.ComputeBytesSize(5, FooBytes);
      }
      if (hasFooEnum) {
        size += pb::CodedOutputStream.ComputeEnumSize(6, (int) FooEnum);
      }
      if (hasFooMessage) {
        size += pb::CodedOutputStream.ComputeMessageSize(7, FooMessage);
      }
      if (hasFooGroup) {
        size += pb::CodedOutputStream.ComputeGroupSize(8, FooGroup);
      }
      if (hasFooLazyMessage) {
        size += pb::CodedOutputStream.ComputeMessageSize(11, FooLazyMessage);
      }
      if (hasBarInt) {
        size += pb::CodedOutputStream.ComputeInt32Size(12, BarInt);
      }
      if (hasBarString) {
        size += pb::CodedOutputStream.ComputeStringSize(13, BarString);
      }
      if (hasBarCord) {
        size += pb::CodedOutputStream.ComputeStringSize(14, BarCord);
      }
      if (hasBarStringPiece) {
        size += pb::CodedOutputStream.ComputeStringSize(15, BarStringPiece);
      }
      if (hasBarBytes) {
        size += pb::CodedOutputStream.ComputeBytesSize(16, BarBytes);
      }
      if (hasBarEnum) {
        size += pb::CodedOutputStream.ComputeEnumSize(17, (int) BarEnum);
      }
      if (hasBazInt) {
        size += pb::CodedOutputStream.ComputeInt32Size(18, BazInt);
      }
      if (hasBazString) {
        size += pb::CodedOutputStream.ComputeStringSize(19, BazString);
      }
      size += UnknownFields.SerializedSize;
      memoizedSerializedSize = size;
      return size;
    }
    public static TestOneof2 ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestOneof2 ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestOneof2 ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestOneof2 ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestOneof2 ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestOneof2 ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestOneof2 ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestOneof2 ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestOneof2 ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestOneof2 ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestOneof2 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(TestOneof2 prototype) {
      return new Builder(prototype);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestOneof2, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestOneof2 cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }

      private bool resultIsReadOnly;
      private TestOneof2 result;

      private TestOneof2 PrepareBuilder() {
        if (resultIsReadOnly) {
          TestOneof2 original = result;
          result = new TestOneof2();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }

      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }

      protected override TestOneof2 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.TestOneof2.Descriptor; }
      }

      public override TestOneof2 DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestOneof2.DefaultInstance; }
      }

      public override TestOneof2 BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }

      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestOneof2) {
          return MergeFrom((TestOneof2) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }

      public override Builder MergeFrom(TestOneof2 other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestOneof2.DefaultInstance) return this;
        PrepareBuilder();
        if (other.HasFooInt) {
          FooInt = other.FooInt;
        }
        if (other.HasFooString) {
          FooString = other.FooString;
        }
        if (other.HasFooCord) {
          FooCord = other.FooCord;
        }
        if (other.HasFooStringPiece) {
          FooStringPiece = other.FooStringPiece;
        }
        if (other.HasFooBytes) {
          FooBytes = other.FooBytes;
        }
        if (other.HasFooEnum) {
          FooEnum = other.FooEnum;
        }
        if (other.HasFooMessage) {
          MergeFooMessage(other.FooMessage);
        }
        if (other.HasFooGroup) {
          MergeFooGroup(other.FooGroup);
        }
        if (other.HasFooLazyMessage) {
          MergeFooLazyMessage(other.FooLazyMessage);
        }
        if (other.HasBarInt) {
          BarInt = other.BarInt;
        }
        if (other.HasBarString) {
          BarString = other.BarString;
        }
        if (other.HasBarCord) {
          BarCord = other.BarCord;
        }
        if (other.HasBarStringPiece) {
          BarStringPiece = other.BarStringPiece;
        }
        if (other.HasBarBytes) {
          BarBytes = other.BarBytes;
        }
        if (other.HasBarEnum) {
          BarEnum = other.BarEnum;
        }
        if (other.HasBazInt) {
          BazInt = other.BazInt;
        }
        if (other.HasBazString) {
          BazString = other.BazString;
        }
        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(_testOneof2FieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testOneof2FieldTags[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.hasFooInt = input.ReadInt32(ref result.fooInt_);
              break;
            }
            case 18: {
              result.hasFooString = input.ReadString(ref result.fooString_);
              break;
            }
            case 26: {
              result.hasFooCord = input.ReadString(ref result.fooCord_);
              break;
            }
            case 34: {
              result.hasFooStringPiece = input.ReadString(ref result.fooStringPiece_);
              break;
            }
            case 42: {
              result.hasFooBytes = input.ReadBytes(ref result.fooBytes_);
              break;
            }
            case 48: {
              object unknown;
              if(input.ReadEnum(ref result.fooEnum_, out unknown)) {
                result.hasFooEnum = true;
              } else if(unknown is int) {
                if (unknownFields == null) {
                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                }
                unknownFields.MergeVarintField(6, (ulong)(int)unknown);
              }
              break;
            }
            case 58: {
              global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage.CreateBuilder();
              if (result.hasFooMessage) {
                subBuilder.MergeFrom(FooMessage);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              FooMessage = subBuilder.BuildPartial();
              break;
            }
            case 67: {
              global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.FooGroup.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.FooGroup.CreateBuilder();
              if (result.hasFooGroup) {
                subBuilder.MergeFrom(FooGroup);
              }
              input.ReadGroup(8, subBuilder, extensionRegistry);
              FooGroup = subBuilder.BuildPartial();
              break;
            }
            case 90: {
              global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage.CreateBuilder();
              if (result.hasFooLazyMessage) {
                subBuilder.MergeFrom(FooLazyMessage);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              FooLazyMessage = subBuilder.BuildPartial();
              break;
            }
            case 96: {
              result.hasBarInt = input.ReadInt32(ref result.barInt_);
              break;
            }
            case 106: {
              result.hasBarString = input.ReadString(ref result.barString_);
              break;
            }
            case 114: {
              result.hasBarCord = input.ReadString(ref result.barCord_);
              break;
            }
            case 122: {
              result.hasBarStringPiece = input.ReadString(ref result.barStringPiece_);
              break;
            }
            case 130: {
              result.hasBarBytes = input.ReadBytes(ref result.barBytes_);
              break;
            }
            case 136: {
              object unknown;
              if(input.ReadEnum(ref result.barEnum_, out unknown)) {
                result.hasBarEnum = true;
              } else if(unknown is int) {
                if (unknownFields == null) {
                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                }
                unknownFields.MergeVarintField(17, (ulong)(int)unknown);
              }
              break;
            }
            case 144: {
              result.hasBazInt = input.ReadInt32(ref result.bazInt_);
              break;
            }
            case 154: {
              result.hasBazString = input.ReadString(ref result.bazString_);
              break;
            }
          }
        }

        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }


      public bool HasFooInt {
        get { return result.hasFooInt; }
      }
      public int FooInt {
        get { return result.FooInt; }
        set { SetFooInt(value); }
      }
      public Builder SetFooInt(int value) {
        PrepareBuilder();
        result.hasFooInt = true;
        result.fooInt_ = value;
        return this;
      }
      public Builder ClearFooInt() {
        PrepareBuilder();
        result.hasFooInt = false;
        result.fooInt_ = 0;
        return this;
      }

      public bool HasFooString {
        get { return result.hasFooString; }
      }
      public string FooString {
        get { return result.FooString; }
        set { SetFooString(value); }
      }
      public Builder SetFooString(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasFooString = true;
        result.fooString_ = value;
        return this;
      }
      public Builder ClearFooString() {
        PrepareBuilder();
        result.hasFooString = false;
        result.fooString_ = "";
        return this;
      }

      public bool HasFooCord {
        get { return result.hasFooCord; }
      }
      public string FooCord {
        get { return result.FooCord; }
        set { SetFooCord(value); }
      }
      public Builder SetFooCord(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasFooCord = true;
        result.fooCord_ = value;
        return this;
      }
      public Builder ClearFooCord() {
        PrepareBuilder();
        result.hasFooCord = false;
        result.fooCord_ = "";
        return this;
      }

      public bool HasFooStringPiece {
        get { return result.hasFooStringPiece; }
      }
      public string FooStringPiece {
        get { return result.FooStringPiece; }
        set { SetFooStringPiece(value); }
      }
      public Builder SetFooStringPiece(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasFooStringPiece = true;
        result.fooStringPiece_ = value;
        return this;
      }
      public Builder ClearFooStringPiece() {
        PrepareBuilder();
        result.hasFooStringPiece = false;
        result.fooStringPiece_ = "";
        return this;
      }

      public bool HasFooBytes {
        get { return result.hasFooBytes; }
      }
      public pb::ByteString FooBytes {
        get { return result.FooBytes; }
        set { SetFooBytes(value); }
      }
      public Builder SetFooBytes(pb::ByteString value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasFooBytes = true;
        result.fooBytes_ = value;
        return this;
      }
      public Builder ClearFooBytes() {
        PrepareBuilder();
        result.hasFooBytes = false;
        result.fooBytes_ = pb::ByteString.Empty;
        return this;
      }

      public bool HasFooEnum {
       get { return result.hasFooEnum; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedEnum FooEnum {
        get { return result.FooEnum; }
        set { SetFooEnum(value); }
      }
      public Builder SetFooEnum(global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedEnum value) {
        PrepareBuilder();
        result.hasFooEnum = true;
        result.fooEnum_ = value;
        return this;
      }
      public Builder ClearFooEnum() {
        PrepareBuilder();
        result.hasFooEnum = false;
        result.fooEnum_ = global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedEnum.FOO;
        return this;
      }

      public bool HasFooMessage {
       get { return result.hasFooMessage; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage FooMessage {
        get { return result.FooMessage; }
        set { SetFooMessage(value); }
      }
      public Builder SetFooMessage(global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasFooMessage = true;
        result.fooMessage_ = value;
        return this;
      }
      public Builder SetFooMessage(global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasFooMessage = true;
        result.fooMessage_ = builderForValue.Build();
        return this;
      }
      public Builder MergeFooMessage(global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        if (result.hasFooMessage &&
            result.fooMessage_ != global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage.DefaultInstance) {
            result.fooMessage_ = global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage.CreateBuilder(result.fooMessage_).MergeFrom(value).BuildPartial();
        } else {
          result.fooMessage_ = value;
        }
        result.hasFooMessage = true;
        return this;
      }
      public Builder ClearFooMessage() {
        PrepareBuilder();
        result.hasFooMessage = false;
        result.fooMessage_ = null;
        return this;
      }

      public bool HasFooGroup {
       get { return result.hasFooGroup; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.FooGroup FooGroup {
        get { return result.FooGroup; }
        set { SetFooGroup(value); }
      }
      public Builder SetFooGroup(global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.FooGroup value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasFooGroup = true;
        result.fooGroup_ = value;
        return this;
      }
      public Builder SetFooGroup(global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.FooGroup.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasFooGroup = true;
        result.fooGroup_ = builderForValue.Build();
        return this;
      }
      public Builder MergeFooGroup(global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.FooGroup value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        if (result.hasFooGroup &&
            result.fooGroup_ != global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.FooGroup.DefaultInstance) {
            result.fooGroup_ = global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.FooGroup.CreateBuilder(result.fooGroup_).MergeFrom(value).BuildPartial();
        } else {
          result.fooGroup_ = value;
        }
        result.hasFooGroup = true;
        return this;
      }
      public Builder ClearFooGroup() {
        PrepareBuilder();
        result.hasFooGroup = false;
        result.fooGroup_ = null;
        return this;
      }

      public bool HasFooLazyMessage {
       get { return result.hasFooLazyMessage; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage FooLazyMessage {
        get { return result.FooLazyMessage; }
        set { SetFooLazyMessage(value); }
      }
      public Builder SetFooLazyMessage(global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasFooLazyMessage = true;
        result.fooLazyMessage_ = value;
        return this;
      }
      public Builder SetFooLazyMessage(global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasFooLazyMessage = true;
        result.fooLazyMessage_ = builderForValue.Build();
        return this;
      }
      public Builder MergeFooLazyMessage(global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        if (result.hasFooLazyMessage &&
            result.fooLazyMessage_ != global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage.DefaultInstance) {
            result.fooLazyMessage_ = global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedMessage.CreateBuilder(result.fooLazyMessage_).MergeFrom(value).BuildPartial();
        } else {
          result.fooLazyMessage_ = value;
        }
        result.hasFooLazyMessage = true;
        return this;
      }
      public Builder ClearFooLazyMessage() {
        PrepareBuilder();
        result.hasFooLazyMessage = false;
        result.fooLazyMessage_ = null;
        return this;
      }

      public bool HasBarInt {
        get { return result.hasBarInt; }
      }
      public int BarInt {
        get { return result.BarInt; }
        set { SetBarInt(value); }
      }
      public Builder SetBarInt(int value) {
        PrepareBuilder();
        result.hasBarInt = true;
        result.barInt_ = value;
        return this;
      }
      public Builder ClearBarInt() {
        PrepareBuilder();
        result.hasBarInt = false;
        result.barInt_ = 5;
        return this;
      }

      public bool HasBarString {
        get { return result.hasBarString; }
      }
      public string BarString {
        get { return result.BarString; }
        set { SetBarString(value); }
      }
      public Builder SetBarString(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasBarString = true;
        result.barString_ = value;
        return this;
      }
      public Builder ClearBarString() {
        PrepareBuilder();
        result.hasBarString = false;
        result.barString_ = "STRING";
        return this;
      }

      public bool HasBarCord {
        get { return result.hasBarCord; }
      }
      public string BarCord {
        get { return result.BarCord; }
        set { SetBarCord(value); }
      }
      public Builder SetBarCord(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasBarCord = true;
        result.barCord_ = value;
        return this;
      }
      public Builder ClearBarCord() {
        PrepareBuilder();
        result.hasBarCord = false;
        result.barCord_ = "CORD";
        return this;
      }

      public bool HasBarStringPiece {
        get { return result.hasBarStringPiece; }
      }
      public string BarStringPiece {
        get { return result.BarStringPiece; }
        set { SetBarStringPiece(value); }
      }
      public Builder SetBarStringPiece(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasBarStringPiece = true;
        result.barStringPiece_ = value;
        return this;
      }
      public Builder ClearBarStringPiece() {
        PrepareBuilder();
        result.hasBarStringPiece = false;
        result.barStringPiece_ = "SPIECE";
        return this;
      }

      public bool HasBarBytes {
        get { return result.hasBarBytes; }
      }
      public pb::ByteString BarBytes {
        get { return result.BarBytes; }
        set { SetBarBytes(value); }
      }
      public Builder SetBarBytes(pb::ByteString value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasBarBytes = true;
        result.barBytes_ = value;
        return this;
      }
      public Builder ClearBarBytes() {
        PrepareBuilder();
        result.hasBarBytes = false;
        result.barBytes_ = (pb::ByteString) global::Google.ProtocolBuffers.TestProtos.TestOneof2.Descriptor.Fields[13].DefaultValue;
        return this;
      }

      public bool HasBarEnum {
       get { return result.hasBarEnum; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedEnum BarEnum {
        get { return result.BarEnum; }
        set { SetBarEnum(value); }
      }
      public Builder SetBarEnum(global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedEnum value) {
        PrepareBuilder();
        result.hasBarEnum = true;
        result.barEnum_ = value;
        return this;
      }
      public Builder ClearBarEnum() {
        PrepareBuilder();
        result.hasBarEnum = false;
        result.barEnum_ = global::Google.ProtocolBuffers.TestProtos.TestOneof2.Types.NestedEnum.BAR;
        return this;
      }

      public bool HasBazInt {
        get { return result.hasBazInt; }
      }
      public int BazInt {
        get { return result.BazInt; }
        set { SetBazInt(value); }
      }
      public Builder SetBazInt(int value) {
        PrepareBuilder();
        result.hasBazInt = true;
        result.bazInt_ = value;
        return this;
      }
      public Builder ClearBazInt() {
        PrepareBuilder();
        result.hasBazInt = false;
        result.bazInt_ = 0;
        return this;
      }

      public bool HasBazString {
        get { return result.hasBazString; }
      }
      public string BazString {
        get { return result.BazString; }
        set { SetBazString(value); }
      }
      public Builder SetBazString(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasBazString = true;
        result.bazString_ = value;
        return this;
      }
      public Builder ClearBazString() {
        PrepareBuilder();
        result.hasBazString = false;
        result.bazString_ = "BAZ";
        return this;
      }
    }
    static TestOneof2() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor, null);
    }
  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestRequiredOneof : pb::GeneratedMessage<TestRequiredOneof, TestRequiredOneof.Builder> {
    private TestRequiredOneof() { }
    private static readonly TestRequiredOneof defaultInstance = new TestRequiredOneof().MakeReadOnly();
    private static readonly string[] _testRequiredOneofFieldNames = new string[] { "foo_int", "foo_message", "foo_string" };
    private static readonly uint[] _testRequiredOneofFieldTags = new uint[] { 8, 26, 18 };
    public static TestRequiredOneof DefaultInstance {
      get { return defaultInstance; }
    }

    public override TestRequiredOneof DefaultInstanceForType {
      get { return DefaultInstance; }
    }

    protected override TestRequiredOneof ThisMessage {
      get { return this; }
    }

    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestRequiredOneof__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestRequiredOneof, TestRequiredOneof.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestRequiredOneof__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[] { "required_double" };
        private static readonly uint[] _nestedMessageFieldTags = new uint[] { 9 };
        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.Unittest.internal__static_protobuf_unittest_TestRequiredOneof_NestedMessage__Descriptor; }
        }

        protected override pb::FieldAccess.FieldAccessorTable<NestedMessage, NestedMessage.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestRequiredOneof_NestedMessage__FieldAccessorTable; }
        }

        public const int RequiredDoubleFieldNumber = 1;
        private bool hasRequiredDouble;
        private double requiredDouble_;
        public bool HasRequiredDouble {
          get { return hasRequiredDouble; }
        }
        public double RequiredDouble {
          get { return requiredDouble_; }
        }

        public override bool IsInitialized {
          get {
            if (!hasRequiredDouble) return false;
            return true;
          }
        }

        public override void WriteTo(pb::ICodedOutputStream output) {
          CalcSerializedSize();
          string[] field_names = _nestedMessageFieldNames;
          if (hasRequiredDouble) {
            output.WriteDouble(1, field_names[0], RequiredDouble);
          }
          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 (hasRequiredDouble) {
            size += pb::CodedOutputStream.ComputeDoubleSize(1, RequiredDouble);
          }
          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.TestRequiredOneof.Types.NestedMessage.Descriptor; }
          }

          public override NestedMessage DefaultInstanceForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.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.TestRequiredOneof.Types.NestedMessage.DefaultInstance) return this;
            PrepareBuilder();
            if (other.HasRequiredDouble) {
              RequiredDouble = other.RequiredDouble;
            }
            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 9: {
                  result.hasRequiredDouble = input.ReadDouble(ref result.requiredDouble_);
                  break;
                }
              }
            }

            if (unknownFields != null) {
              this.UnknownFields = unknownFields.Build();
            }
            return this;
          }


          public bool HasRequiredDouble {
            get { return result.hasRequiredDouble; }
          }
          public double RequiredDouble {
            get { return result.RequiredDouble; }
            set { SetRequiredDouble(value); }
          }
          public Builder SetRequiredDouble(double value) {
            PrepareBuilder();
            result.hasRequiredDouble = true;
            result.requiredDouble_ = value;
            return this;
          }
          public Builder ClearRequiredDouble() {
            PrepareBuilder();
            result.hasRequiredDouble = false;
            result.requiredDouble_ = 0D;
            return this;
          }
        }
        static NestedMessage() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor, null);
        }
      }

    }
    #endregion

    public const int FooIntFieldNumber = 1;
    private bool hasFooInt;
    private int fooInt_;
    public bool HasFooInt {
      get { return hasFooInt; }
    }
    public int FooInt {
      get { return fooInt_; }
    }

    public const int FooStringFieldNumber = 2;
    private bool hasFooString;
    private string fooString_ = "";
    public bool HasFooString {
      get { return hasFooString; }
    }
    public string FooString {
      get { return fooString_; }
    }

    public const int FooMessageFieldNumber = 3;
    private bool hasFooMessage;
    private global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.Types.NestedMessage fooMessage_;
    public bool HasFooMessage {
      get { return hasFooMessage; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.Types.NestedMessage FooMessage {
      get { return fooMessage_ ?? global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.Types.NestedMessage.DefaultInstance; }
    }

    public override bool IsInitialized {
      get {
        if (HasFooMessage) {
          if (!FooMessage.IsInitialized) return false;
        }
        return true;
      }
    }

    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _testRequiredOneofFieldNames;
      if (hasFooInt) {
        output.WriteInt32(1, field_names[0], FooInt);
      }
      if (hasFooString) {
        output.WriteString(2, field_names[2], FooString);
      }
      if (hasFooMessage) {
        output.WriteMessage(3, field_names[1], FooMessage);
      }
      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 (hasFooInt) {
        size += pb::CodedOutputStream.ComputeInt32Size(1, FooInt);
      }
      if (hasFooString) {
        size += pb::CodedOutputStream.ComputeStringSize(2, FooString);
      }
      if (hasFooMessage) {
        size += pb::CodedOutputStream.ComputeMessageSize(3, FooMessage);
      }
      size += UnknownFields.SerializedSize;
      memoizedSerializedSize = size;
      return size;
    }
    public static TestRequiredOneof ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestRequiredOneof ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestRequiredOneof ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestRequiredOneof ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestRequiredOneof ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestRequiredOneof ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestRequiredOneof ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestRequiredOneof ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestRequiredOneof ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestRequiredOneof ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestRequiredOneof 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(TestRequiredOneof prototype) {
      return new Builder(prototype);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestRequiredOneof, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestRequiredOneof cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }

      private bool resultIsReadOnly;
      private TestRequiredOneof result;

      private TestRequiredOneof PrepareBuilder() {
        if (resultIsReadOnly) {
          TestRequiredOneof original = result;
          result = new TestRequiredOneof();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }

      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }

      protected override TestRequiredOneof 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.TestRequiredOneof.Descriptor; }
      }

      public override TestRequiredOneof DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.DefaultInstance; }
      }

      public override TestRequiredOneof BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }

      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestRequiredOneof) {
          return MergeFrom((TestRequiredOneof) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }

      public override Builder MergeFrom(TestRequiredOneof other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.DefaultInstance) return this;
        PrepareBuilder();
        if (other.HasFooInt) {
          FooInt = other.FooInt;
        }
        if (other.HasFooString) {
          FooString = other.FooString;
        }
        if (other.HasFooMessage) {
          MergeFooMessage(other.FooMessage);
        }
        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(_testRequiredOneofFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testRequiredOneofFieldTags[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.hasFooInt = input.ReadInt32(ref result.fooInt_);
              break;
            }
            case 18: {
              result.hasFooString = input.ReadString(ref result.fooString_);
              break;
            }
            case 26: {
              global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.Types.NestedMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.Types.NestedMessage.CreateBuilder();
              if (result.hasFooMessage) {
                subBuilder.MergeFrom(FooMessage);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              FooMessage = subBuilder.BuildPartial();
              break;
            }
          }
        }

        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }


      public bool HasFooInt {
        get { return result.hasFooInt; }
      }
      public int FooInt {
        get { return result.FooInt; }
        set { SetFooInt(value); }
      }
      public Builder SetFooInt(int value) {
        PrepareBuilder();
        result.hasFooInt = true;
        result.fooInt_ = value;
        return this;
      }
      public Builder ClearFooInt() {
        PrepareBuilder();
        result.hasFooInt = false;
        result.fooInt_ = 0;
        return this;
      }

      public bool HasFooString {
        get { return result.hasFooString; }
      }
      public string FooString {
        get { return result.FooString; }
        set { SetFooString(value); }
      }
      public Builder SetFooString(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasFooString = true;
        result.fooString_ = value;
        return this;
      }
      public Builder ClearFooString() {
        PrepareBuilder();
        result.hasFooString = false;
        result.fooString_ = "";
        return this;
      }

      public bool HasFooMessage {
       get { return result.hasFooMessage; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.Types.NestedMessage FooMessage {
        get { return result.FooMessage; }
        set { SetFooMessage(value); }
      }
      public Builder SetFooMessage(global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.Types.NestedMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasFooMessage = true;
        result.fooMessage_ = value;
        return this;
      }
      public Builder SetFooMessage(global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.Types.NestedMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasFooMessage = true;
        result.fooMessage_ = builderForValue.Build();
        return this;
      }
      public Builder MergeFooMessage(global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.Types.NestedMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        if (result.hasFooMessage &&
            result.fooMessage_ != global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.Types.NestedMessage.DefaultInstance) {
            result.fooMessage_ = global::Google.ProtocolBuffers.TestProtos.TestRequiredOneof.Types.NestedMessage.CreateBuilder(result.fooMessage_).MergeFrom(value).BuildPartial();
        } else {
          result.fooMessage_ = value;
        }
        result.hasFooMessage = true;
        return this;
      }
      public Builder ClearFooMessage() {
        PrepareBuilder();
        result.hasFooMessage = false;
        result.fooMessage_ = null;
        return this;
      }
    }
    static TestRequiredOneof() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.internal__static_protobuf_unittest_TestPackedTypes__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestPackedTypes, TestPackedTypes.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_TestUnpackedTypes__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestUnpackedTypes, TestUnpackedTypes.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_TestPackedExtensions__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestPackedExtensions, TestPackedExtensions.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.Descriptor, null);
    }
  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestUnpackedExtensions : pb::ExtendableMessage<TestUnpackedExtensions, TestUnpackedExtensions.Builder> {
    private TestUnpackedExtensions() { }
    private static readonly TestUnpackedExtensions defaultInstance = new TestUnpackedExtensions().MakeReadOnly();
    private static readonly string[] _testUnpackedExtensionsFieldNames = new string[] {  };
    private static readonly uint[] _testUnpackedExtensionsFieldTags = new uint[] {  };
    public static TestUnpackedExtensions DefaultInstance {
      get { return defaultInstance; }
    }

    public override TestUnpackedExtensions DefaultInstanceForType {
      get { return DefaultInstance; }
    }

    protected override TestUnpackedExtensions ThisMessage {
      get { return this; }
    }

    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestUnpackedExtensions__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestUnpackedExtensions, TestUnpackedExtensions.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestUnpackedExtensions__FieldAccessorTable; }
    }

    public override bool IsInitialized {
      get {
        if (!ExtensionsAreInitialized) return false;
        return true;
      }
    }

    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _testUnpackedExtensionsFieldNames;
      pb::ExtendableMessage<TestUnpackedExtensions, TestUnpackedExtensions.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 TestUnpackedExtensions ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestUnpackedExtensions ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestUnpackedExtensions ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestUnpackedExtensions ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestUnpackedExtensions ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestUnpackedExtensions ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestUnpackedExtensions ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestUnpackedExtensions ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestUnpackedExtensions ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestUnpackedExtensions ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestUnpackedExtensions 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(TestUnpackedExtensions prototype) {
      return new Builder(prototype);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::ExtendableBuilder<TestUnpackedExtensions, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestUnpackedExtensions cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }

      private bool resultIsReadOnly;
      private TestUnpackedExtensions result;

      private TestUnpackedExtensions PrepareBuilder() {
        if (resultIsReadOnly) {
          TestUnpackedExtensions original = result;
          result = new TestUnpackedExtensions();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }

      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }

      protected override TestUnpackedExtensions 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.TestUnpackedExtensions.Descriptor; }
      }

      public override TestUnpackedExtensions DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestUnpackedExtensions.DefaultInstance; }
      }

      public override TestUnpackedExtensions BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }

      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestUnpackedExtensions) {
          return MergeFrom((TestUnpackedExtensions) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }

      public override Builder MergeFrom(TestUnpackedExtensions other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestUnpackedExtensions.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(_testUnpackedExtensionsFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testUnpackedExtensionsFieldTags[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 TestUnpackedExtensions() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.internal__static_protobuf_unittest_TestDynamicExtensions__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestDynamicExtensions, TestDynamicExtensions.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.internal__static_protobuf_unittest_TestDynamicExtensions_DynamicMessageType__Descriptor; }
        }

        protected override pb::FieldAccess.FieldAccessorTable<DynamicMessageType, DynamicMessageType.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_TestRepeatedScalarDifferentTagSizes__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestRepeatedScalarDifferentTagSizes, TestRepeatedScalarDifferentTagSizes.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.Descriptor, null);
    }
  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestParsingMerge : pb::ExtendableMessage<TestParsingMerge, TestParsingMerge.Builder> {
    private TestParsingMerge() { }
    private static readonly TestParsingMerge defaultInstance = new TestParsingMerge().MakeReadOnly();
    private static readonly string[] _testParsingMergeFieldNames = new string[] { "optional_all_types", "optionalgroup", "repeated_all_types", "repeatedgroup", "required_all_types" };
    private static readonly uint[] _testParsingMergeFieldTags = new uint[] { 18, 83, 26, 163, 10 };
    public static TestParsingMerge DefaultInstance {
      get { return defaultInstance; }
    }

    public override TestParsingMerge DefaultInstanceForType {
      get { return DefaultInstance; }
    }

    protected override TestParsingMerge ThisMessage {
      get { return this; }
    }

    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestParsingMerge__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestParsingMerge, TestParsingMerge.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestParsingMerge__FieldAccessorTable; }
    }

    public const int OptionalExtFieldNumber = 1000;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> OptionalExt;
    public const int RepeatedExtFieldNumber = 1001;
    public static pb::GeneratedExtensionBase<scg::IList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes>> RepeatedExt;
    #region Nested types
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public static partial class Types {
      [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
      public sealed partial class RepeatedFieldsGenerator : pb::GeneratedMessage<RepeatedFieldsGenerator, RepeatedFieldsGenerator.Builder> {
        private RepeatedFieldsGenerator() { }
        private static readonly RepeatedFieldsGenerator defaultInstance = new RepeatedFieldsGenerator().MakeReadOnly();
        private static readonly string[] _repeatedFieldsGeneratorFieldNames = new string[] { "ext1", "ext2", "field1", "field2", "field3", "group1", "group2" };
        private static readonly uint[] _repeatedFieldsGeneratorFieldTags = new uint[] { 8002, 8010, 10, 18, 26, 83, 163 };
        public static RepeatedFieldsGenerator DefaultInstance {
          get { return defaultInstance; }
        }

        public override RepeatedFieldsGenerator DefaultInstanceForType {
          get { return DefaultInstance; }
        }

        protected override RepeatedFieldsGenerator ThisMessage {
          get { return this; }
        }

        public static pbd::MessageDescriptor Descriptor {
          get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestParsingMerge_RepeatedFieldsGenerator__Descriptor; }
        }

        protected override pb::FieldAccess.FieldAccessorTable<RepeatedFieldsGenerator, RepeatedFieldsGenerator.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestParsingMerge_RepeatedFieldsGenerator__FieldAccessorTable; }
        }

        #region Nested types
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public static partial class Types {
          [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
          public sealed partial class Group1 : pb::GeneratedMessage<Group1, Group1.Builder> {
            private Group1() { }
            private static readonly Group1 defaultInstance = new Group1().MakeReadOnly();
            private static readonly string[] _group1FieldNames = new string[] { "field1" };
            private static readonly uint[] _group1FieldTags = new uint[] { 90 };
            public static Group1 DefaultInstance {
              get { return defaultInstance; }
            }

            public override Group1 DefaultInstanceForType {
              get { return DefaultInstance; }
            }

            protected override Group1 ThisMessage {
              get { return this; }
            }

            public static pbd::MessageDescriptor Descriptor {
              get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestParsingMerge_RepeatedFieldsGenerator_Group1__Descriptor; }
            }

            protected override pb::FieldAccess.FieldAccessorTable<Group1, Group1.Builder> InternalFieldAccessors {
              get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestParsingMerge_RepeatedFieldsGenerator_Group1__FieldAccessorTable; }
            }

            public const int Field1FieldNumber = 11;
            private bool hasField1;
            private global::Google.ProtocolBuffers.TestProtos.TestAllTypes field1_;
            public bool HasField1 {
              get { return hasField1; }
            }
            public global::Google.ProtocolBuffers.TestProtos.TestAllTypes Field1 {
              get { return field1_ ?? global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance; }
            }

            public override bool IsInitialized {
              get {
                return true;
              }
            }

            public override void WriteTo(pb::ICodedOutputStream output) {
              CalcSerializedSize();
              string[] field_names = _group1FieldNames;
              if (hasField1) {
                output.WriteMessage(11, field_names[0], Field1);
              }
              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 (hasField1) {
                size += pb::CodedOutputStream.ComputeMessageSize(11, Field1);
              }
              size += UnknownFields.SerializedSize;
              memoizedSerializedSize = size;
              return size;
            }
            public static Group1 ParseFrom(pb::ByteString data) {
              return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
            }
            public static Group1 ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
              return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
            }
            public static Group1 ParseFrom(byte[] data) {
              return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
            }
            public static Group1 ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
              return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
            }
            public static Group1 ParseFrom(global::System.IO.Stream input) {
              return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
            }
            public static Group1 ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
              return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
            }
            public static Group1 ParseDelimitedFrom(global::System.IO.Stream input) {
              return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
            }
            public static Group1 ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
              return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
            }
            public static Group1 ParseFrom(pb::ICodedInputStream input) {
              return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
            }
            public static Group1 ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
              return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
            }
            private Group1 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(Group1 prototype) {
              return new Builder(prototype);
            }

            [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
            public sealed partial class Builder : pb::GeneratedBuilder<Group1, Builder> {
              protected override Builder ThisBuilder {
                get { return this; }
              }
              public Builder() {
                result = DefaultInstance;
                resultIsReadOnly = true;
              }
              internal Builder(Group1 cloneFrom) {
                result = cloneFrom;
                resultIsReadOnly = true;
              }

              private bool resultIsReadOnly;
              private Group1 result;

              private Group1 PrepareBuilder() {
                if (resultIsReadOnly) {
                  Group1 original = result;
                  result = new Group1();
                  resultIsReadOnly = false;
                  MergeFrom(original);
                }
                return result;
              }

              public override bool IsInitialized {
                get { return result.IsInitialized; }
              }

              protected override Group1 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.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group1.Descriptor; }
              }

              public override Group1 DefaultInstanceForType {
                get { return global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group1.DefaultInstance; }
              }

              public override Group1 BuildPartial() {
                if (resultIsReadOnly) {
                  return result;
                }
                resultIsReadOnly = true;
                return result.MakeReadOnly();
              }

              public override Builder MergeFrom(pb::IMessage other) {
                if (other is Group1) {
                  return MergeFrom((Group1) other);
                } else {
                  base.MergeFrom(other);
                  return this;
                }
              }

              public override Builder MergeFrom(Group1 other) {
                if (other == global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group1.DefaultInstance) return this;
                PrepareBuilder();
                if (other.HasField1) {
                  MergeField1(other.Field1);
                }
                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(_group1FieldNames, field_name, global::System.StringComparer.Ordinal);
                    if(field_ordinal >= 0)
                      tag = _group1FieldTags[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 90: {
                      global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder();
                      if (result.hasField1) {
                        subBuilder.MergeFrom(Field1);
                      }
                      input.ReadMessage(subBuilder, extensionRegistry);
                      Field1 = subBuilder.BuildPartial();
                      break;
                    }
                  }
                }

                if (unknownFields != null) {
                  this.UnknownFields = unknownFields.Build();
                }
                return this;
              }


              public bool HasField1 {
               get { return result.hasField1; }
              }
              public global::Google.ProtocolBuffers.TestProtos.TestAllTypes Field1 {
                get { return result.Field1; }
                set { SetField1(value); }
              }
              public Builder SetField1(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
                pb::ThrowHelper.ThrowIfNull(value, "value");
                PrepareBuilder();
                result.hasField1 = true;
                result.field1_ = value;
                return this;
              }
              public Builder SetField1(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
                PrepareBuilder();
                result.hasField1 = true;
                result.field1_ = builderForValue.Build();
                return this;
              }
              public Builder MergeField1(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
                pb::ThrowHelper.ThrowIfNull(value, "value");
                PrepareBuilder();
                if (result.hasField1 &&
                    result.field1_ != global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance) {
                    result.field1_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder(result.field1_).MergeFrom(value).BuildPartial();
                } else {
                  result.field1_ = value;
                }
                result.hasField1 = true;
                return this;
              }
              public Builder ClearField1() {
                PrepareBuilder();
                result.hasField1 = false;
                result.field1_ = null;
                return this;
              }
            }
            static Group1() {
              object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor, null);
            }
          }

          [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
          public sealed partial class Group2 : pb::GeneratedMessage<Group2, Group2.Builder> {
            private Group2() { }
            private static readonly Group2 defaultInstance = new Group2().MakeReadOnly();
            private static readonly string[] _group2FieldNames = new string[] { "field1" };
            private static readonly uint[] _group2FieldTags = new uint[] { 170 };
            public static Group2 DefaultInstance {
              get { return defaultInstance; }
            }

            public override Group2 DefaultInstanceForType {
              get { return DefaultInstance; }
            }

            protected override Group2 ThisMessage {
              get { return this; }
            }

            public static pbd::MessageDescriptor Descriptor {
              get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestParsingMerge_RepeatedFieldsGenerator_Group2__Descriptor; }
            }

            protected override pb::FieldAccess.FieldAccessorTable<Group2, Group2.Builder> InternalFieldAccessors {
              get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestParsingMerge_RepeatedFieldsGenerator_Group2__FieldAccessorTable; }
            }

            public const int Field1FieldNumber = 21;
            private bool hasField1;
            private global::Google.ProtocolBuffers.TestProtos.TestAllTypes field1_;
            public bool HasField1 {
              get { return hasField1; }
            }
            public global::Google.ProtocolBuffers.TestProtos.TestAllTypes Field1 {
              get { return field1_ ?? global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance; }
            }

            public override bool IsInitialized {
              get {
                return true;
              }
            }

            public override void WriteTo(pb::ICodedOutputStream output) {
              CalcSerializedSize();
              string[] field_names = _group2FieldNames;
              if (hasField1) {
                output.WriteMessage(21, field_names[0], Field1);
              }
              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 (hasField1) {
                size += pb::CodedOutputStream.ComputeMessageSize(21, Field1);
              }
              size += UnknownFields.SerializedSize;
              memoizedSerializedSize = size;
              return size;
            }
            public static Group2 ParseFrom(pb::ByteString data) {
              return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
            }
            public static Group2 ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
              return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
            }
            public static Group2 ParseFrom(byte[] data) {
              return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
            }
            public static Group2 ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
              return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
            }
            public static Group2 ParseFrom(global::System.IO.Stream input) {
              return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
            }
            public static Group2 ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
              return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
            }
            public static Group2 ParseDelimitedFrom(global::System.IO.Stream input) {
              return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
            }
            public static Group2 ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
              return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
            }
            public static Group2 ParseFrom(pb::ICodedInputStream input) {
              return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
            }
            public static Group2 ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
              return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
            }
            private Group2 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(Group2 prototype) {
              return new Builder(prototype);
            }

            [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
            public sealed partial class Builder : pb::GeneratedBuilder<Group2, Builder> {
              protected override Builder ThisBuilder {
                get { return this; }
              }
              public Builder() {
                result = DefaultInstance;
                resultIsReadOnly = true;
              }
              internal Builder(Group2 cloneFrom) {
                result = cloneFrom;
                resultIsReadOnly = true;
              }

              private bool resultIsReadOnly;
              private Group2 result;

              private Group2 PrepareBuilder() {
                if (resultIsReadOnly) {
                  Group2 original = result;
                  result = new Group2();
                  resultIsReadOnly = false;
                  MergeFrom(original);
                }
                return result;
              }

              public override bool IsInitialized {
                get { return result.IsInitialized; }
              }

              protected override Group2 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.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group2.Descriptor; }
              }

              public override Group2 DefaultInstanceForType {
                get { return global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group2.DefaultInstance; }
              }

              public override Group2 BuildPartial() {
                if (resultIsReadOnly) {
                  return result;
                }
                resultIsReadOnly = true;
                return result.MakeReadOnly();
              }

              public override Builder MergeFrom(pb::IMessage other) {
                if (other is Group2) {
                  return MergeFrom((Group2) other);
                } else {
                  base.MergeFrom(other);
                  return this;
                }
              }

              public override Builder MergeFrom(Group2 other) {
                if (other == global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group2.DefaultInstance) return this;
                PrepareBuilder();
                if (other.HasField1) {
                  MergeField1(other.Field1);
                }
                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(_group2FieldNames, field_name, global::System.StringComparer.Ordinal);
                    if(field_ordinal >= 0)
                      tag = _group2FieldTags[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 170: {
                      global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder();
                      if (result.hasField1) {
                        subBuilder.MergeFrom(Field1);
                      }
                      input.ReadMessage(subBuilder, extensionRegistry);
                      Field1 = subBuilder.BuildPartial();
                      break;
                    }
                  }
                }

                if (unknownFields != null) {
                  this.UnknownFields = unknownFields.Build();
                }
                return this;
              }


              public bool HasField1 {
               get { return result.hasField1; }
              }
              public global::Google.ProtocolBuffers.TestProtos.TestAllTypes Field1 {
                get { return result.Field1; }
                set { SetField1(value); }
              }
              public Builder SetField1(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
                pb::ThrowHelper.ThrowIfNull(value, "value");
                PrepareBuilder();
                result.hasField1 = true;
                result.field1_ = value;
                return this;
              }
              public Builder SetField1(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
                pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
                PrepareBuilder();
                result.hasField1 = true;
                result.field1_ = builderForValue.Build();
                return this;
              }
              public Builder MergeField1(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
                pb::ThrowHelper.ThrowIfNull(value, "value");
                PrepareBuilder();
                if (result.hasField1 &&
                    result.field1_ != global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance) {
                    result.field1_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder(result.field1_).MergeFrom(value).BuildPartial();
                } else {
                  result.field1_ = value;
                }
                result.hasField1 = true;
                return this;
              }
              public Builder ClearField1() {
                PrepareBuilder();
                result.hasField1 = false;
                result.field1_ = null;
                return this;
              }
            }
            static Group2() {
              object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor, null);
            }
          }

        }
        #endregion

        public const int Field1FieldNumber = 1;
        private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> field1_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes>();
        public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> Field1List {
          get { return field1_; }
        }
        public int Field1Count {
          get { return field1_.Count; }
        }
        public global::Google.ProtocolBuffers.TestProtos.TestAllTypes GetField1(int index) {
          return field1_[index];
        }

        public const int Field2FieldNumber = 2;
        private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> field2_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes>();
        public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> Field2List {
          get { return field2_; }
        }
        public int Field2Count {
          get { return field2_.Count; }
        }
        public global::Google.ProtocolBuffers.TestProtos.TestAllTypes GetField2(int index) {
          return field2_[index];
        }

        public const int Field3FieldNumber = 3;
        private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> field3_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes>();
        public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> Field3List {
          get { return field3_; }
        }
        public int Field3Count {
          get { return field3_.Count; }
        }
        public global::Google.ProtocolBuffers.TestProtos.TestAllTypes GetField3(int index) {
          return field3_[index];
        }

        public const int Group1FieldNumber = 10;
        private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group1> group1_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group1>();
        public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group1> Group1List {
          get { return group1_; }
        }
        public int Group1Count {
          get { return group1_.Count; }
        }
        public global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group1 GetGroup1(int index) {
          return group1_[index];
        }

        public const int Group2FieldNumber = 20;
        private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group2> group2_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group2>();
        public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group2> Group2List {
          get { return group2_; }
        }
        public int Group2Count {
          get { return group2_.Count; }
        }
        public global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group2 GetGroup2(int index) {
          return group2_[index];
        }

        public const int Ext1FieldNumber = 1000;
        private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> ext1_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes>();
        public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> Ext1List {
          get { return ext1_; }
        }
        public int Ext1Count {
          get { return ext1_.Count; }
        }
        public global::Google.ProtocolBuffers.TestProtos.TestAllTypes GetExt1(int index) {
          return ext1_[index];
        }

        public const int Ext2FieldNumber = 1001;
        private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> ext2_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes>();
        public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> Ext2List {
          get { return ext2_; }
        }
        public int Ext2Count {
          get { return ext2_.Count; }
        }
        public global::Google.ProtocolBuffers.TestProtos.TestAllTypes GetExt2(int index) {
          return ext2_[index];
        }

        public override bool IsInitialized {
          get {
            return true;
          }
        }

        public override void WriteTo(pb::ICodedOutputStream output) {
          CalcSerializedSize();
          string[] field_names = _repeatedFieldsGeneratorFieldNames;
          if (field1_.Count > 0) {
            output.WriteMessageArray(1, field_names[2], field1_);
          }
          if (field2_.Count > 0) {
            output.WriteMessageArray(2, field_names[3], field2_);
          }
          if (field3_.Count > 0) {
            output.WriteMessageArray(3, field_names[4], field3_);
          }
          if (group1_.Count > 0) {
            output.WriteGroupArray(10, field_names[5], group1_);
          }
          if (group2_.Count > 0) {
            output.WriteGroupArray(20, field_names[6], group2_);
          }
          if (ext1_.Count > 0) {
            output.WriteMessageArray(1000, field_names[0], ext1_);
          }
          if (ext2_.Count > 0) {
            output.WriteMessageArray(1001, field_names[1], ext2_);
          }
          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;
          foreach (global::Google.ProtocolBuffers.TestProtos.TestAllTypes element in Field1List) {
            size += pb::CodedOutputStream.ComputeMessageSize(1, element);
          }
          foreach (global::Google.ProtocolBuffers.TestProtos.TestAllTypes element in Field2List) {
            size += pb::CodedOutputStream.ComputeMessageSize(2, element);
          }
          foreach (global::Google.ProtocolBuffers.TestProtos.TestAllTypes element in Field3List) {
            size += pb::CodedOutputStream.ComputeMessageSize(3, element);
          }
          foreach (global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group1 element in Group1List) {
            size += pb::CodedOutputStream.ComputeGroupSize(10, element);
          }
          foreach (global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group2 element in Group2List) {
            size += pb::CodedOutputStream.ComputeGroupSize(20, element);
          }
          foreach (global::Google.ProtocolBuffers.TestProtos.TestAllTypes element in Ext1List) {
            size += pb::CodedOutputStream.ComputeMessageSize(1000, element);
          }
          foreach (global::Google.ProtocolBuffers.TestProtos.TestAllTypes element in Ext2List) {
            size += pb::CodedOutputStream.ComputeMessageSize(1001, element);
          }
          size += UnknownFields.SerializedSize;
          memoizedSerializedSize = size;
          return size;
        }
        public static RepeatedFieldsGenerator ParseFrom(pb::ByteString data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static RepeatedFieldsGenerator ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static RepeatedFieldsGenerator ParseFrom(byte[] data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static RepeatedFieldsGenerator ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static RepeatedFieldsGenerator ParseFrom(global::System.IO.Stream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static RepeatedFieldsGenerator ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static RepeatedFieldsGenerator ParseDelimitedFrom(global::System.IO.Stream input) {
          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
        }
        public static RepeatedFieldsGenerator ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
        }
        public static RepeatedFieldsGenerator ParseFrom(pb::ICodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static RepeatedFieldsGenerator ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        private RepeatedFieldsGenerator MakeReadOnly() {
          field1_.MakeReadOnly();
          field2_.MakeReadOnly();
          field3_.MakeReadOnly();
          group1_.MakeReadOnly();
          group2_.MakeReadOnly();
          ext1_.MakeReadOnly();
          ext2_.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(RepeatedFieldsGenerator prototype) {
          return new Builder(prototype);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        public sealed partial class Builder : pb::GeneratedBuilder<RepeatedFieldsGenerator, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {
            result = DefaultInstance;
            resultIsReadOnly = true;
          }
          internal Builder(RepeatedFieldsGenerator cloneFrom) {
            result = cloneFrom;
            resultIsReadOnly = true;
          }

          private bool resultIsReadOnly;
          private RepeatedFieldsGenerator result;

          private RepeatedFieldsGenerator PrepareBuilder() {
            if (resultIsReadOnly) {
              RepeatedFieldsGenerator original = result;
              result = new RepeatedFieldsGenerator();
              resultIsReadOnly = false;
              MergeFrom(original);
            }
            return result;
          }

          public override bool IsInitialized {
            get { return result.IsInitialized; }
          }

          protected override RepeatedFieldsGenerator 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.TestParsingMerge.Types.RepeatedFieldsGenerator.Descriptor; }
          }

          public override RepeatedFieldsGenerator DefaultInstanceForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.DefaultInstance; }
          }

          public override RepeatedFieldsGenerator BuildPartial() {
            if (resultIsReadOnly) {
              return result;
            }
            resultIsReadOnly = true;
            return result.MakeReadOnly();
          }

          public override Builder MergeFrom(pb::IMessage other) {
            if (other is RepeatedFieldsGenerator) {
              return MergeFrom((RepeatedFieldsGenerator) other);
            } else {
              base.MergeFrom(other);
              return this;
            }
          }

          public override Builder MergeFrom(RepeatedFieldsGenerator other) {
            if (other == global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.DefaultInstance) return this;
            PrepareBuilder();
            if (other.field1_.Count != 0) {
              result.field1_.Add(other.field1_);
            }
            if (other.field2_.Count != 0) {
              result.field2_.Add(other.field2_);
            }
            if (other.field3_.Count != 0) {
              result.field3_.Add(other.field3_);
            }
            if (other.group1_.Count != 0) {
              result.group1_.Add(other.group1_);
            }
            if (other.group2_.Count != 0) {
              result.group2_.Add(other.group2_);
            }
            if (other.ext1_.Count != 0) {
              result.ext1_.Add(other.ext1_);
            }
            if (other.ext2_.Count != 0) {
              result.ext2_.Add(other.ext2_);
            }
            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(_repeatedFieldsGeneratorFieldNames, field_name, global::System.StringComparer.Ordinal);
                if(field_ordinal >= 0)
                  tag = _repeatedFieldsGeneratorFieldTags[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: {
                  input.ReadMessageArray(tag, field_name, result.field1_, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance, extensionRegistry);
                  break;
                }
                case 18: {
                  input.ReadMessageArray(tag, field_name, result.field2_, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance, extensionRegistry);
                  break;
                }
                case 26: {
                  input.ReadMessageArray(tag, field_name, result.field3_, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance, extensionRegistry);
                  break;
                }
                case 83: {
                  input.ReadGroupArray(tag, field_name, result.group1_, global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group1.DefaultInstance, extensionRegistry);
                  break;
                }
                case 163: {
                  input.ReadGroupArray(tag, field_name, result.group2_, global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group2.DefaultInstance, extensionRegistry);
                  break;
                }
                case 8002: {
                  input.ReadMessageArray(tag, field_name, result.ext1_, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance, extensionRegistry);
                  break;
                }
                case 8010: {
                  input.ReadMessageArray(tag, field_name, result.ext2_, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance, extensionRegistry);
                  break;
                }
              }
            }

            if (unknownFields != null) {
              this.UnknownFields = unknownFields.Build();
            }
            return this;
          }


          public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> Field1List {
            get { return PrepareBuilder().field1_; }
          }
          public int Field1Count {
            get { return result.Field1Count; }
          }
          public global::Google.ProtocolBuffers.TestProtos.TestAllTypes GetField1(int index) {
            return result.GetField1(index);
          }
          public Builder SetField1(int index, global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            result.field1_[index] = value;
            return this;
          }
          public Builder SetField1(int index, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
            pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
            PrepareBuilder();
            result.field1_[index] = builderForValue.Build();
            return this;
          }
          public Builder AddField1(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            result.field1_.Add(value);
            return this;
          }
          public Builder AddField1(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
            pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
            PrepareBuilder();
            result.field1_.Add(builderForValue.Build());
            return this;
          }
          public Builder AddRangeField1(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> values) {
            PrepareBuilder();
            result.field1_.Add(values);
            return this;
          }
          public Builder ClearField1() {
            PrepareBuilder();
            result.field1_.Clear();
            return this;
          }

          public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> Field2List {
            get { return PrepareBuilder().field2_; }
          }
          public int Field2Count {
            get { return result.Field2Count; }
          }
          public global::Google.ProtocolBuffers.TestProtos.TestAllTypes GetField2(int index) {
            return result.GetField2(index);
          }
          public Builder SetField2(int index, global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            result.field2_[index] = value;
            return this;
          }
          public Builder SetField2(int index, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
            pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
            PrepareBuilder();
            result.field2_[index] = builderForValue.Build();
            return this;
          }
          public Builder AddField2(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            result.field2_.Add(value);
            return this;
          }
          public Builder AddField2(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
            pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
            PrepareBuilder();
            result.field2_.Add(builderForValue.Build());
            return this;
          }
          public Builder AddRangeField2(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> values) {
            PrepareBuilder();
            result.field2_.Add(values);
            return this;
          }
          public Builder ClearField2() {
            PrepareBuilder();
            result.field2_.Clear();
            return this;
          }

          public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> Field3List {
            get { return PrepareBuilder().field3_; }
          }
          public int Field3Count {
            get { return result.Field3Count; }
          }
          public global::Google.ProtocolBuffers.TestProtos.TestAllTypes GetField3(int index) {
            return result.GetField3(index);
          }
          public Builder SetField3(int index, global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            result.field3_[index] = value;
            return this;
          }
          public Builder SetField3(int index, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
            pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
            PrepareBuilder();
            result.field3_[index] = builderForValue.Build();
            return this;
          }
          public Builder AddField3(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            result.field3_.Add(value);
            return this;
          }
          public Builder AddField3(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
            pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
            PrepareBuilder();
            result.field3_.Add(builderForValue.Build());
            return this;
          }
          public Builder AddRangeField3(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> values) {
            PrepareBuilder();
            result.field3_.Add(values);
            return this;
          }
          public Builder ClearField3() {
            PrepareBuilder();
            result.field3_.Clear();
            return this;
          }

          public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group1> Group1List {
            get { return PrepareBuilder().group1_; }
          }
          public int Group1Count {
            get { return result.Group1Count; }
          }
          public global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group1 GetGroup1(int index) {
            return result.GetGroup1(index);
          }
          public Builder SetGroup1(int index, global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group1 value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            result.group1_[index] = value;
            return this;
          }
          public Builder SetGroup1(int index, global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group1.Builder builderForValue) {
            pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
            PrepareBuilder();
            result.group1_[index] = builderForValue.Build();
            return this;
          }
          public Builder AddGroup1(global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group1 value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            result.group1_.Add(value);
            return this;
          }
          public Builder AddGroup1(global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group1.Builder builderForValue) {
            pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
            PrepareBuilder();
            result.group1_.Add(builderForValue.Build());
            return this;
          }
          public Builder AddRangeGroup1(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group1> values) {
            PrepareBuilder();
            result.group1_.Add(values);
            return this;
          }
          public Builder ClearGroup1() {
            PrepareBuilder();
            result.group1_.Clear();
            return this;
          }

          public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group2> Group2List {
            get { return PrepareBuilder().group2_; }
          }
          public int Group2Count {
            get { return result.Group2Count; }
          }
          public global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group2 GetGroup2(int index) {
            return result.GetGroup2(index);
          }
          public Builder SetGroup2(int index, global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group2 value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            result.group2_[index] = value;
            return this;
          }
          public Builder SetGroup2(int index, global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group2.Builder builderForValue) {
            pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
            PrepareBuilder();
            result.group2_[index] = builderForValue.Build();
            return this;
          }
          public Builder AddGroup2(global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group2 value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            result.group2_.Add(value);
            return this;
          }
          public Builder AddGroup2(global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group2.Builder builderForValue) {
            pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
            PrepareBuilder();
            result.group2_.Add(builderForValue.Build());
            return this;
          }
          public Builder AddRangeGroup2(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedFieldsGenerator.Types.Group2> values) {
            PrepareBuilder();
            result.group2_.Add(values);
            return this;
          }
          public Builder ClearGroup2() {
            PrepareBuilder();
            result.group2_.Clear();
            return this;
          }

          public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> Ext1List {
            get { return PrepareBuilder().ext1_; }
          }
          public int Ext1Count {
            get { return result.Ext1Count; }
          }
          public global::Google.ProtocolBuffers.TestProtos.TestAllTypes GetExt1(int index) {
            return result.GetExt1(index);
          }
          public Builder SetExt1(int index, global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            result.ext1_[index] = value;
            return this;
          }
          public Builder SetExt1(int index, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
            pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
            PrepareBuilder();
            result.ext1_[index] = builderForValue.Build();
            return this;
          }
          public Builder AddExt1(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            result.ext1_.Add(value);
            return this;
          }
          public Builder AddExt1(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
            pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
            PrepareBuilder();
            result.ext1_.Add(builderForValue.Build());
            return this;
          }
          public Builder AddRangeExt1(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> values) {
            PrepareBuilder();
            result.ext1_.Add(values);
            return this;
          }
          public Builder ClearExt1() {
            PrepareBuilder();
            result.ext1_.Clear();
            return this;
          }

          public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> Ext2List {
            get { return PrepareBuilder().ext2_; }
          }
          public int Ext2Count {
            get { return result.Ext2Count; }
          }
          public global::Google.ProtocolBuffers.TestProtos.TestAllTypes GetExt2(int index) {
            return result.GetExt2(index);
          }
          public Builder SetExt2(int index, global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            result.ext2_[index] = value;
            return this;
          }
          public Builder SetExt2(int index, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
            pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
            PrepareBuilder();
            result.ext2_[index] = builderForValue.Build();
            return this;
          }
          public Builder AddExt2(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            result.ext2_.Add(value);
            return this;
          }
          public Builder AddExt2(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
            pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
            PrepareBuilder();
            result.ext2_.Add(builderForValue.Build());
            return this;
          }
          public Builder AddRangeExt2(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> values) {
            PrepareBuilder();
            result.ext2_.Add(values);
            return this;
          }
          public Builder ClearExt2() {
            PrepareBuilder();
            result.ext2_.Clear();
            return this;
          }
        }
        static RepeatedFieldsGenerator() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.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[] { "optional_group_all_types" };
        private static readonly uint[] _optionalGroupFieldTags = new uint[] { 90 };
        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.Unittest.internal__static_protobuf_unittest_TestParsingMerge_OptionalGroup__Descriptor; }
        }

        protected override pb::FieldAccess.FieldAccessorTable<OptionalGroup, OptionalGroup.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestParsingMerge_OptionalGroup__FieldAccessorTable; }
        }

        public const int OptionalGroupAllTypesFieldNumber = 11;
        private bool hasOptionalGroupAllTypes;
        private global::Google.ProtocolBuffers.TestProtos.TestAllTypes optionalGroupAllTypes_;
        public bool HasOptionalGroupAllTypes {
          get { return hasOptionalGroupAllTypes; }
        }
        public global::Google.ProtocolBuffers.TestProtos.TestAllTypes OptionalGroupAllTypes {
          get { return optionalGroupAllTypes_ ?? global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance; }
        }

        public override bool IsInitialized {
          get {
            return true;
          }
        }

        public override void WriteTo(pb::ICodedOutputStream output) {
          CalcSerializedSize();
          string[] field_names = _optionalGroupFieldNames;
          if (hasOptionalGroupAllTypes) {
            output.WriteMessage(11, field_names[0], OptionalGroupAllTypes);
          }
          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 (hasOptionalGroupAllTypes) {
            size += pb::CodedOutputStream.ComputeMessageSize(11, OptionalGroupAllTypes);
          }
          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.TestParsingMerge.Types.OptionalGroup.Descriptor; }
          }

          public override OptionalGroup DefaultInstanceForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.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.TestParsingMerge.Types.OptionalGroup.DefaultInstance) return this;
            PrepareBuilder();
            if (other.HasOptionalGroupAllTypes) {
              MergeOptionalGroupAllTypes(other.OptionalGroupAllTypes);
            }
            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 90: {
                  global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder();
                  if (result.hasOptionalGroupAllTypes) {
                    subBuilder.MergeFrom(OptionalGroupAllTypes);
                  }
                  input.ReadMessage(subBuilder, extensionRegistry);
                  OptionalGroupAllTypes = subBuilder.BuildPartial();
                  break;
                }
              }
            }

            if (unknownFields != null) {
              this.UnknownFields = unknownFields.Build();
            }
            return this;
          }


          public bool HasOptionalGroupAllTypes {
           get { return result.hasOptionalGroupAllTypes; }
          }
          public global::Google.ProtocolBuffers.TestProtos.TestAllTypes OptionalGroupAllTypes {
            get { return result.OptionalGroupAllTypes; }
            set { SetOptionalGroupAllTypes(value); }
          }
          public Builder SetOptionalGroupAllTypes(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            result.hasOptionalGroupAllTypes = true;
            result.optionalGroupAllTypes_ = value;
            return this;
          }
          public Builder SetOptionalGroupAllTypes(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
            pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
            PrepareBuilder();
            result.hasOptionalGroupAllTypes = true;
            result.optionalGroupAllTypes_ = builderForValue.Build();
            return this;
          }
          public Builder MergeOptionalGroupAllTypes(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            if (result.hasOptionalGroupAllTypes &&
                result.optionalGroupAllTypes_ != global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance) {
                result.optionalGroupAllTypes_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder(result.optionalGroupAllTypes_).MergeFrom(value).BuildPartial();
            } else {
              result.optionalGroupAllTypes_ = value;
            }
            result.hasOptionalGroupAllTypes = true;
            return this;
          }
          public Builder ClearOptionalGroupAllTypes() {
            PrepareBuilder();
            result.hasOptionalGroupAllTypes = false;
            result.optionalGroupAllTypes_ = null;
            return this;
          }
        }
        static OptionalGroup() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.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[] { "repeated_group_all_types" };
        private static readonly uint[] _repeatedGroupFieldTags = new uint[] { 170 };
        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.Unittest.internal__static_protobuf_unittest_TestParsingMerge_RepeatedGroup__Descriptor; }
        }

        protected override pb::FieldAccess.FieldAccessorTable<RepeatedGroup, RepeatedGroup.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestParsingMerge_RepeatedGroup__FieldAccessorTable; }
        }

        public const int RepeatedGroupAllTypesFieldNumber = 21;
        private bool hasRepeatedGroupAllTypes;
        private global::Google.ProtocolBuffers.TestProtos.TestAllTypes repeatedGroupAllTypes_;
        public bool HasRepeatedGroupAllTypes {
          get { return hasRepeatedGroupAllTypes; }
        }
        public global::Google.ProtocolBuffers.TestProtos.TestAllTypes RepeatedGroupAllTypes {
          get { return repeatedGroupAllTypes_ ?? global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance; }
        }

        public override bool IsInitialized {
          get {
            return true;
          }
        }

        public override void WriteTo(pb::ICodedOutputStream output) {
          CalcSerializedSize();
          string[] field_names = _repeatedGroupFieldNames;
          if (hasRepeatedGroupAllTypes) {
            output.WriteMessage(21, field_names[0], RepeatedGroupAllTypes);
          }
          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 (hasRepeatedGroupAllTypes) {
            size += pb::CodedOutputStream.ComputeMessageSize(21, RepeatedGroupAllTypes);
          }
          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.TestParsingMerge.Types.RepeatedGroup.Descriptor; }
          }

          public override RepeatedGroup DefaultInstanceForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.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.TestParsingMerge.Types.RepeatedGroup.DefaultInstance) return this;
            PrepareBuilder();
            if (other.HasRepeatedGroupAllTypes) {
              MergeRepeatedGroupAllTypes(other.RepeatedGroupAllTypes);
            }
            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 170: {
                  global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder();
                  if (result.hasRepeatedGroupAllTypes) {
                    subBuilder.MergeFrom(RepeatedGroupAllTypes);
                  }
                  input.ReadMessage(subBuilder, extensionRegistry);
                  RepeatedGroupAllTypes = subBuilder.BuildPartial();
                  break;
                }
              }
            }

            if (unknownFields != null) {
              this.UnknownFields = unknownFields.Build();
            }
            return this;
          }


          public bool HasRepeatedGroupAllTypes {
           get { return result.hasRepeatedGroupAllTypes; }
          }
          public global::Google.ProtocolBuffers.TestProtos.TestAllTypes RepeatedGroupAllTypes {
            get { return result.RepeatedGroupAllTypes; }
            set { SetRepeatedGroupAllTypes(value); }
          }
          public Builder SetRepeatedGroupAllTypes(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            result.hasRepeatedGroupAllTypes = true;
            result.repeatedGroupAllTypes_ = value;
            return this;
          }
          public Builder SetRepeatedGroupAllTypes(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
            pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
            PrepareBuilder();
            result.hasRepeatedGroupAllTypes = true;
            result.repeatedGroupAllTypes_ = builderForValue.Build();
            return this;
          }
          public Builder MergeRepeatedGroupAllTypes(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            PrepareBuilder();
            if (result.hasRepeatedGroupAllTypes &&
                result.repeatedGroupAllTypes_ != global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance) {
                result.repeatedGroupAllTypes_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder(result.repeatedGroupAllTypes_).MergeFrom(value).BuildPartial();
            } else {
              result.repeatedGroupAllTypes_ = value;
            }
            result.hasRepeatedGroupAllTypes = true;
            return this;
          }
          public Builder ClearRepeatedGroupAllTypes() {
            PrepareBuilder();
            result.hasRepeatedGroupAllTypes = false;
            result.repeatedGroupAllTypes_ = null;
            return this;
          }
        }
        static RepeatedGroup() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor, null);
        }
      }

    }
    #endregion

    public const int RequiredAllTypesFieldNumber = 1;
    private bool hasRequiredAllTypes;
    private global::Google.ProtocolBuffers.TestProtos.TestAllTypes requiredAllTypes_;
    public bool HasRequiredAllTypes {
      get { return hasRequiredAllTypes; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes RequiredAllTypes {
      get { return requiredAllTypes_ ?? global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance; }
    }

    public const int OptionalAllTypesFieldNumber = 2;
    private bool hasOptionalAllTypes;
    private global::Google.ProtocolBuffers.TestProtos.TestAllTypes optionalAllTypes_;
    public bool HasOptionalAllTypes {
      get { return hasOptionalAllTypes; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes OptionalAllTypes {
      get { return optionalAllTypes_ ?? global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance; }
    }

    public const int RepeatedAllTypesFieldNumber = 3;
    private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> repeatedAllTypes_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes>();
    public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> RepeatedAllTypesList {
      get { return repeatedAllTypes_; }
    }
    public int RepeatedAllTypesCount {
      get { return repeatedAllTypes_.Count; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes GetRepeatedAllTypes(int index) {
      return repeatedAllTypes_[index];
    }

    public const int OptionalGroupFieldNumber = 10;
    private bool hasOptionalGroup;
    private global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.OptionalGroup optionalGroup_;
    public bool HasOptionalGroup {
      get { return hasOptionalGroup; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.OptionalGroup OptionalGroup {
      get { return optionalGroup_ ?? global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.OptionalGroup.DefaultInstance; }
    }

    public const int RepeatedGroupFieldNumber = 20;
    private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedGroup> repeatedGroup_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedGroup>();
    public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedGroup> RepeatedGroupList {
      get { return repeatedGroup_; }
    }
    public int RepeatedGroupCount {
      get { return repeatedGroup_.Count; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedGroup GetRepeatedGroup(int index) {
      return repeatedGroup_[index];
    }

    public override bool IsInitialized {
      get {
        if (!hasRequiredAllTypes) return false;
        if (!ExtensionsAreInitialized) return false;
        return true;
      }
    }

    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _testParsingMergeFieldNames;
      pb::ExtendableMessage<TestParsingMerge, TestParsingMerge.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
      if (hasRequiredAllTypes) {
        output.WriteMessage(1, field_names[4], RequiredAllTypes);
      }
      if (hasOptionalAllTypes) {
        output.WriteMessage(2, field_names[0], OptionalAllTypes);
      }
      if (repeatedAllTypes_.Count > 0) {
        output.WriteMessageArray(3, field_names[2], repeatedAllTypes_);
      }
      if (hasOptionalGroup) {
        output.WriteGroup(10, field_names[1], OptionalGroup);
      }
      if (repeatedGroup_.Count > 0) {
        output.WriteGroupArray(20, field_names[3], repeatedGroup_);
      }
      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;
      if (hasRequiredAllTypes) {
        size += pb::CodedOutputStream.ComputeMessageSize(1, RequiredAllTypes);
      }
      if (hasOptionalAllTypes) {
        size += pb::CodedOutputStream.ComputeMessageSize(2, OptionalAllTypes);
      }
      foreach (global::Google.ProtocolBuffers.TestProtos.TestAllTypes element in RepeatedAllTypesList) {
        size += pb::CodedOutputStream.ComputeMessageSize(3, element);
      }
      if (hasOptionalGroup) {
        size += pb::CodedOutputStream.ComputeGroupSize(10, OptionalGroup);
      }
      foreach (global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedGroup element in RepeatedGroupList) {
        size += pb::CodedOutputStream.ComputeGroupSize(20, element);
      }
      size += ExtensionsSerializedSize;
      size += UnknownFields.SerializedSize;
      memoizedSerializedSize = size;
      return size;
    }
    public static TestParsingMerge ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestParsingMerge ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestParsingMerge ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestParsingMerge ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestParsingMerge ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestParsingMerge ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestParsingMerge ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestParsingMerge ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestParsingMerge ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestParsingMerge ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestParsingMerge MakeReadOnly() {
      repeatedAllTypes_.MakeReadOnly();
      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(TestParsingMerge prototype) {
      return new Builder(prototype);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::ExtendableBuilder<TestParsingMerge, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestParsingMerge cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }

      private bool resultIsReadOnly;
      private TestParsingMerge result;

      private TestParsingMerge PrepareBuilder() {
        if (resultIsReadOnly) {
          TestParsingMerge original = result;
          result = new TestParsingMerge();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }

      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }

      protected override TestParsingMerge 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.TestParsingMerge.Descriptor; }
      }

      public override TestParsingMerge DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.DefaultInstance; }
      }

      public override TestParsingMerge BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }

      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestParsingMerge) {
          return MergeFrom((TestParsingMerge) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }

      public override Builder MergeFrom(TestParsingMerge other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.DefaultInstance) return this;
        PrepareBuilder();
        if (other.HasRequiredAllTypes) {
          MergeRequiredAllTypes(other.RequiredAllTypes);
        }
        if (other.HasOptionalAllTypes) {
          MergeOptionalAllTypes(other.OptionalAllTypes);
        }
        if (other.repeatedAllTypes_.Count != 0) {
          result.repeatedAllTypes_.Add(other.repeatedAllTypes_);
        }
        if (other.HasOptionalGroup) {
          MergeOptionalGroup(other.OptionalGroup);
        }
        if (other.repeatedGroup_.Count != 0) {
          result.repeatedGroup_.Add(other.repeatedGroup_);
        }
          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(_testParsingMergeFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testParsingMergeFieldTags[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.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder();
              if (result.hasRequiredAllTypes) {
                subBuilder.MergeFrom(RequiredAllTypes);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              RequiredAllTypes = subBuilder.BuildPartial();
              break;
            }
            case 18: {
              global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder();
              if (result.hasOptionalAllTypes) {
                subBuilder.MergeFrom(OptionalAllTypes);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              OptionalAllTypes = subBuilder.BuildPartial();
              break;
            }
            case 26: {
              input.ReadMessageArray(tag, field_name, result.repeatedAllTypes_, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance, extensionRegistry);
              break;
            }
            case 83: {
              global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.OptionalGroup.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.OptionalGroup.CreateBuilder();
              if (result.hasOptionalGroup) {
                subBuilder.MergeFrom(OptionalGroup);
              }
              input.ReadGroup(10, subBuilder, extensionRegistry);
              OptionalGroup = subBuilder.BuildPartial();
              break;
            }
            case 163: {
              input.ReadGroupArray(tag, field_name, result.repeatedGroup_, global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedGroup.DefaultInstance, extensionRegistry);
              break;
            }
          }
        }

        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }


      public bool HasRequiredAllTypes {
       get { return result.hasRequiredAllTypes; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestAllTypes RequiredAllTypes {
        get { return result.RequiredAllTypes; }
        set { SetRequiredAllTypes(value); }
      }
      public Builder SetRequiredAllTypes(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasRequiredAllTypes = true;
        result.requiredAllTypes_ = value;
        return this;
      }
      public Builder SetRequiredAllTypes(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasRequiredAllTypes = true;
        result.requiredAllTypes_ = builderForValue.Build();
        return this;
      }
      public Builder MergeRequiredAllTypes(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        if (result.hasRequiredAllTypes &&
            result.requiredAllTypes_ != global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance) {
            result.requiredAllTypes_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder(result.requiredAllTypes_).MergeFrom(value).BuildPartial();
        } else {
          result.requiredAllTypes_ = value;
        }
        result.hasRequiredAllTypes = true;
        return this;
      }
      public Builder ClearRequiredAllTypes() {
        PrepareBuilder();
        result.hasRequiredAllTypes = false;
        result.requiredAllTypes_ = null;
        return this;
      }

      public bool HasOptionalAllTypes {
       get { return result.hasOptionalAllTypes; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestAllTypes OptionalAllTypes {
        get { return result.OptionalAllTypes; }
        set { SetOptionalAllTypes(value); }
      }
      public Builder SetOptionalAllTypes(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasOptionalAllTypes = true;
        result.optionalAllTypes_ = value;
        return this;
      }
      public Builder SetOptionalAllTypes(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasOptionalAllTypes = true;
        result.optionalAllTypes_ = builderForValue.Build();
        return this;
      }
      public Builder MergeOptionalAllTypes(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        if (result.hasOptionalAllTypes &&
            result.optionalAllTypes_ != global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance) {
            result.optionalAllTypes_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder(result.optionalAllTypes_).MergeFrom(value).BuildPartial();
        } else {
          result.optionalAllTypes_ = value;
        }
        result.hasOptionalAllTypes = true;
        return this;
      }
      public Builder ClearOptionalAllTypes() {
        PrepareBuilder();
        result.hasOptionalAllTypes = false;
        result.optionalAllTypes_ = null;
        return this;
      }

      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> RepeatedAllTypesList {
        get { return PrepareBuilder().repeatedAllTypes_; }
      }
      public int RepeatedAllTypesCount {
        get { return result.RepeatedAllTypesCount; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestAllTypes GetRepeatedAllTypes(int index) {
        return result.GetRepeatedAllTypes(index);
      }
      public Builder SetRepeatedAllTypes(int index, global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.repeatedAllTypes_[index] = value;
        return this;
      }
      public Builder SetRepeatedAllTypes(int index, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.repeatedAllTypes_[index] = builderForValue.Build();
        return this;
      }
      public Builder AddRepeatedAllTypes(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.repeatedAllTypes_.Add(value);
        return this;
      }
      public Builder AddRepeatedAllTypes(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.repeatedAllTypes_.Add(builderForValue.Build());
        return this;
      }
      public Builder AddRangeRepeatedAllTypes(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> values) {
        PrepareBuilder();
        result.repeatedAllTypes_.Add(values);
        return this;
      }
      public Builder ClearRepeatedAllTypes() {
        PrepareBuilder();
        result.repeatedAllTypes_.Clear();
        return this;
      }

      public bool HasOptionalGroup {
       get { return result.hasOptionalGroup; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.OptionalGroup OptionalGroup {
        get { return result.OptionalGroup; }
        set { SetOptionalGroup(value); }
      }
      public Builder SetOptionalGroup(global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.OptionalGroup value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasOptionalGroup = true;
        result.optionalGroup_ = value;
        return this;
      }
      public Builder SetOptionalGroup(global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.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.TestParsingMerge.Types.OptionalGroup value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        if (result.hasOptionalGroup &&
            result.optionalGroup_ != global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.OptionalGroup.DefaultInstance) {
            result.optionalGroup_ = global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.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 pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedGroup> RepeatedGroupList {
        get { return PrepareBuilder().repeatedGroup_; }
      }
      public int RepeatedGroupCount {
        get { return result.RepeatedGroupCount; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedGroup GetRepeatedGroup(int index) {
        return result.GetRepeatedGroup(index);
      }
      public Builder SetRepeatedGroup(int index, global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedGroup value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.repeatedGroup_[index] = value;
        return this;
      }
      public Builder SetRepeatedGroup(int index, global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedGroup.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.repeatedGroup_[index] = builderForValue.Build();
        return this;
      }
      public Builder AddRepeatedGroup(global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.Types.RepeatedGroup value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.repeatedGroup_.Add(value);
        return this;
      }
      public Builder AddRepeatedGroup(global::Google.ProtocolBuffers.TestProtos.TestParsingMerge.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.TestParsingMerge.Types.RepeatedGroup> values) {
        PrepareBuilder();
        result.repeatedGroup_.Add(values);
        return this;
      }
      public Builder ClearRepeatedGroup() {
        PrepareBuilder();
        result.repeatedGroup_.Clear();
        return this;
      }
    }
    static TestParsingMerge() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor, null);
    }
  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestCommentInjectionMessage : pb::GeneratedMessage<TestCommentInjectionMessage, TestCommentInjectionMessage.Builder> {
    private TestCommentInjectionMessage() { }
    private static readonly TestCommentInjectionMessage defaultInstance = new TestCommentInjectionMessage().MakeReadOnly();
    private static readonly string[] _testCommentInjectionMessageFieldNames = new string[] { "a" };
    private static readonly uint[] _testCommentInjectionMessageFieldTags = new uint[] { 10 };
    public static TestCommentInjectionMessage DefaultInstance {
      get { return defaultInstance; }
    }

    public override TestCommentInjectionMessage DefaultInstanceForType {
      get { return DefaultInstance; }
    }

    protected override TestCommentInjectionMessage ThisMessage {
      get { return this; }
    }

    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestCommentInjectionMessage__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestCommentInjectionMessage, TestCommentInjectionMessage.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_TestCommentInjectionMessage__FieldAccessorTable; }
    }

    public const int AFieldNumber = 1;
    private bool hasA;
    private string a_ = "*/ <- Neither should this.";
    public bool HasA {
      get { return hasA; }
    }
    public string A {
      get { return a_; }
    }

    public override bool IsInitialized {
      get {
        return true;
      }
    }

    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _testCommentInjectionMessageFieldNames;
      if (hasA) {
        output.WriteString(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.ComputeStringSize(1, A);
      }
      size += UnknownFields.SerializedSize;
      memoizedSerializedSize = size;
      return size;
    }
    public static TestCommentInjectionMessage ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestCommentInjectionMessage ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestCommentInjectionMessage ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestCommentInjectionMessage ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestCommentInjectionMessage ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestCommentInjectionMessage ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestCommentInjectionMessage ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestCommentInjectionMessage ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestCommentInjectionMessage ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestCommentInjectionMessage ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestCommentInjectionMessage 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(TestCommentInjectionMessage prototype) {
      return new Builder(prototype);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestCommentInjectionMessage, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestCommentInjectionMessage cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }

      private bool resultIsReadOnly;
      private TestCommentInjectionMessage result;

      private TestCommentInjectionMessage PrepareBuilder() {
        if (resultIsReadOnly) {
          TestCommentInjectionMessage original = result;
          result = new TestCommentInjectionMessage();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }

      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }

      protected override TestCommentInjectionMessage 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.TestCommentInjectionMessage.Descriptor; }
      }

      public override TestCommentInjectionMessage DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestCommentInjectionMessage.DefaultInstance; }
      }

      public override TestCommentInjectionMessage BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }

      public override Builder MergeFrom(pb::IMessage other) {
        if (other is TestCommentInjectionMessage) {
          return MergeFrom((TestCommentInjectionMessage) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }

      public override Builder MergeFrom(TestCommentInjectionMessage other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestCommentInjectionMessage.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(_testCommentInjectionMessageFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testCommentInjectionMessageFieldTags[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.hasA = input.ReadString(ref result.a_);
              break;
            }
          }
        }

        if (unknownFields != null) {
          this.UnknownFields = unknownFields.Build();
        }
        return this;
      }


      public bool HasA {
        get { return result.hasA; }
      }
      public string A {
        get { return result.A; }
        set { SetA(value); }
      }
      public Builder SetA(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasA = true;
        result.a_ = value;
        return this;
      }
      public Builder ClearA() {
        PrepareBuilder();
        result.hasA = false;
        result.a_ = "*/ <- Neither should this.";
        return this;
      }
    }
    static TestCommentInjectionMessage() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.internal__static_protobuf_unittest_FooRequest__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<FooRequest, FooRequest.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_FooResponse__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<FooResponse, FooResponse.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.Descriptor, null);
    }
  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class FooClientMessage : pb::GeneratedMessage<FooClientMessage, FooClientMessage.Builder> {
    private FooClientMessage() { }
    private static readonly FooClientMessage defaultInstance = new FooClientMessage().MakeReadOnly();
    private static readonly string[] _fooClientMessageFieldNames = new string[] {  };
    private static readonly uint[] _fooClientMessageFieldTags = new uint[] {  };
    public static FooClientMessage DefaultInstance {
      get { return defaultInstance; }
    }

    public override FooClientMessage DefaultInstanceForType {
      get { return DefaultInstance; }
    }

    protected override FooClientMessage ThisMessage {
      get { return this; }
    }

    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_FooClientMessage__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<FooClientMessage, FooClientMessage.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_FooClientMessage__FieldAccessorTable; }
    }

    public override bool IsInitialized {
      get {
        return true;
      }
    }

    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _fooClientMessageFieldNames;
      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 FooClientMessage ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static FooClientMessage ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static FooClientMessage ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static FooClientMessage ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static FooClientMessage ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static FooClientMessage ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static FooClientMessage ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static FooClientMessage ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static FooClientMessage ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static FooClientMessage ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private FooClientMessage 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(FooClientMessage prototype) {
      return new Builder(prototype);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<FooClientMessage, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(FooClientMessage cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }

      private bool resultIsReadOnly;
      private FooClientMessage result;

      private FooClientMessage PrepareBuilder() {
        if (resultIsReadOnly) {
          FooClientMessage original = result;
          result = new FooClientMessage();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }

      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }

      protected override FooClientMessage 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.FooClientMessage.Descriptor; }
      }

      public override FooClientMessage DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.FooClientMessage.DefaultInstance; }
      }

      public override FooClientMessage BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }

      public override Builder MergeFrom(pb::IMessage other) {
        if (other is FooClientMessage) {
          return MergeFrom((FooClientMessage) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }

      public override Builder MergeFrom(FooClientMessage other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.FooClientMessage.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(_fooClientMessageFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _fooClientMessageFieldTags[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 FooClientMessage() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor, null);
    }
  }

  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class FooServerMessage : pb::GeneratedMessage<FooServerMessage, FooServerMessage.Builder> {
    private FooServerMessage() { }
    private static readonly FooServerMessage defaultInstance = new FooServerMessage().MakeReadOnly();
    private static readonly string[] _fooServerMessageFieldNames = new string[] {  };
    private static readonly uint[] _fooServerMessageFieldTags = new uint[] {  };
    public static FooServerMessage DefaultInstance {
      get { return defaultInstance; }
    }

    public override FooServerMessage DefaultInstanceForType {
      get { return DefaultInstance; }
    }

    protected override FooServerMessage ThisMessage {
      get { return this; }
    }

    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_FooServerMessage__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<FooServerMessage, FooServerMessage.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.internal__static_protobuf_unittest_FooServerMessage__FieldAccessorTable; }
    }

    public override bool IsInitialized {
      get {
        return true;
      }
    }

    public override void WriteTo(pb::ICodedOutputStream output) {
      CalcSerializedSize();
      string[] field_names = _fooServerMessageFieldNames;
      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 FooServerMessage ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static FooServerMessage ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static FooServerMessage ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static FooServerMessage ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static FooServerMessage ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static FooServerMessage ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static FooServerMessage ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static FooServerMessage ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static FooServerMessage ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static FooServerMessage ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private FooServerMessage 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(FooServerMessage prototype) {
      return new Builder(prototype);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<FooServerMessage, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(FooServerMessage cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }

      private bool resultIsReadOnly;
      private FooServerMessage result;

      private FooServerMessage PrepareBuilder() {
        if (resultIsReadOnly) {
          FooServerMessage original = result;
          result = new FooServerMessage();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }

      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }

      protected override FooServerMessage 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.FooServerMessage.Descriptor; }
      }

      public override FooServerMessage DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.FooServerMessage.DefaultInstance; }
      }

      public override FooServerMessage BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }

      public override Builder MergeFrom(pb::IMessage other) {
        if (other is FooServerMessage) {
          return MergeFrom((FooServerMessage) other);
        } else {
          base.MergeFrom(other);
          return this;
        }
      }

      public override Builder MergeFrom(FooServerMessage other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.FooServerMessage.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(_fooServerMessageFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _fooServerMessageFieldTags[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 FooServerMessage() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.internal__static_protobuf_unittest_BarRequest__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<BarRequest, BarRequest.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.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.Unittest.internal__static_protobuf_unittest_BarResponse__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<BarResponse, BarResponse.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.Unittest.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.Unittest.Descriptor, null);
    }
  }

  #endregion

}

#endregion Designer generated code
