// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: google/protobuf/unittest_no_field_presence.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 UnittestNoFieldPresence {

    #region Extension registration
    public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
    }
    #endregion
    #region Static variables
    internal static pbd::MessageDescriptor internal__static_proto2_nofieldpresence_unittest_TestAllTypes__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder> internal__static_proto2_nofieldpresence_unittest_TestAllTypes__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_proto2_nofieldpresence_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_proto2_nofieldpresence_unittest_TestAllTypes_NestedMessage__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_proto2_nofieldpresence_unittest_TestProto2Required__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestProto2Required, global::Google.ProtocolBuffers.TestProtos.TestProto2Required.Builder> internal__static_proto2_nofieldpresence_unittest_TestProto2Required__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_proto2_nofieldpresence_unittest_ForeignMessage__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.ForeignMessage, global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder> internal__static_proto2_nofieldpresence_unittest_ForeignMessage__FieldAccessorTable;
    #endregion
    #region Descriptor
    public static pbd::FileDescriptor Descriptor {
      get { return descriptor; }
    }
    private static pbd::FileDescriptor descriptor;

    static UnittestNoFieldPresence() {
      byte[] descriptorData = global::System.Convert.FromBase64String(
          string.Concat(
            "CjBnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfbm9fZmllbGRfcHJlc2VuY2Uu", 
            "cHJvdG8SH3Byb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3QaHmdvb2ds", 
            "ZS9wcm90b2J1Zi91bml0dGVzdC5wcm90byKaEQoMVGVzdEFsbFR5cGVzEhYK", 
            "Dm9wdGlvbmFsX2ludDMyGAEgASgFEhYKDm9wdGlvbmFsX2ludDY0GAIgASgD", 
            "EhcKD29wdGlvbmFsX3VpbnQzMhgDIAEoDRIXCg9vcHRpb25hbF91aW50NjQY", 
            "BCABKAQSFwoPb3B0aW9uYWxfc2ludDMyGAUgASgREhcKD29wdGlvbmFsX3Np", 
            "bnQ2NBgGIAEoEhIYChBvcHRpb25hbF9maXhlZDMyGAcgASgHEhgKEG9wdGlv", 
            "bmFsX2ZpeGVkNjQYCCABKAYSGQoRb3B0aW9uYWxfc2ZpeGVkMzIYCSABKA8S", 
            "GQoRb3B0aW9uYWxfc2ZpeGVkNjQYCiABKBASFgoOb3B0aW9uYWxfZmxvYXQY", 
            "CyABKAISFwoPb3B0aW9uYWxfZG91YmxlGAwgASgBEhUKDW9wdGlvbmFsX2Jv", 
            "b2wYDSABKAgSFwoPb3B0aW9uYWxfc3RyaW5nGA4gASgJEhYKDm9wdGlvbmFs", 
            "X2J5dGVzGA8gASgMElwKF29wdGlvbmFsX25lc3RlZF9tZXNzYWdlGBIgASgL", 
            "MjsucHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0dGVzdC5UZXN0QWxsVHlw", 
            "ZXMuTmVzdGVkTWVzc2FnZRJRChhvcHRpb25hbF9mb3JlaWduX21lc3NhZ2UY", 
            "EyABKAsyLy5wcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0LkZvcmVp", 
            "Z25NZXNzYWdlEkAKF29wdGlvbmFsX3Byb3RvMl9tZXNzYWdlGBQgASgLMh8u", 
            "cHJvdG9idWZfdW5pdHRlc3QuVGVzdEFsbFR5cGVzElYKFG9wdGlvbmFsX25l", 
            "c3RlZF9lbnVtGBUgASgOMjgucHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0", 
            "dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bRJLChVvcHRpb25hbF9mb3Jl", 
            "aWduX2VudW0YFiABKA4yLC5wcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0", 
            "ZXN0LkZvcmVpZ25FbnVtEiEKFW9wdGlvbmFsX3N0cmluZ19waWVjZRgYIAEo", 
            "CUICCAISGQoNb3B0aW9uYWxfY29yZBgZIAEoCUICCAESXgoVb3B0aW9uYWxf", 
            "bGF6eV9tZXNzYWdlGB4gASgLMjsucHJvdG8yX25vZmllbGRwcmVzZW5jZV91", 
            "bml0dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkTWVzc2FnZUICKAESFgoOcmVw", 
            "ZWF0ZWRfaW50MzIYHyADKAUSFgoOcmVwZWF0ZWRfaW50NjQYICADKAMSFwoP", 
            "cmVwZWF0ZWRfdWludDMyGCEgAygNEhcKD3JlcGVhdGVkX3VpbnQ2NBgiIAMo", 
            "BBIXCg9yZXBlYXRlZF9zaW50MzIYIyADKBESFwoPcmVwZWF0ZWRfc2ludDY0", 
            "GCQgAygSEhgKEHJlcGVhdGVkX2ZpeGVkMzIYJSADKAcSGAoQcmVwZWF0ZWRf", 
            "Zml4ZWQ2NBgmIAMoBhIZChFyZXBlYXRlZF9zZml4ZWQzMhgnIAMoDxIZChFy", 
            "ZXBlYXRlZF9zZml4ZWQ2NBgoIAMoEBIWCg5yZXBlYXRlZF9mbG9hdBgpIAMo", 
            "AhIXCg9yZXBlYXRlZF9kb3VibGUYKiADKAESFQoNcmVwZWF0ZWRfYm9vbBgr", 
            "IAMoCBIXCg9yZXBlYXRlZF9zdHJpbmcYLCADKAkSFgoOcmVwZWF0ZWRfYnl0", 
            "ZXMYLSADKAwSXAoXcmVwZWF0ZWRfbmVzdGVkX21lc3NhZ2UYMCADKAsyOy5w", 
            "cm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0LlRlc3RBbGxUeXBlcy5O", 
            "ZXN0ZWRNZXNzYWdlElEKGHJlcGVhdGVkX2ZvcmVpZ25fbWVzc2FnZRgxIAMo", 
            "CzIvLnByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3QuRm9yZWlnbk1l", 
            "c3NhZ2USQAoXcmVwZWF0ZWRfcHJvdG8yX21lc3NhZ2UYMiADKAsyHy5wcm90", 
            "b2J1Zl91bml0dGVzdC5UZXN0QWxsVHlwZXMSVgoUcmVwZWF0ZWRfbmVzdGVk", 
            "X2VudW0YMyADKA4yOC5wcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0ZXN0", 
            "LlRlc3RBbGxUeXBlcy5OZXN0ZWRFbnVtEksKFXJlcGVhdGVkX2ZvcmVpZ25f", 
            "ZW51bRg0IAMoDjIsLnByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3Qu", 
            "Rm9yZWlnbkVudW0SIQoVcmVwZWF0ZWRfc3RyaW5nX3BpZWNlGDYgAygJQgII", 
            "AhIZCg1yZXBlYXRlZF9jb3JkGDcgAygJQgIIARJeChVyZXBlYXRlZF9sYXp5", 
            "X21lc3NhZ2UYOSADKAsyOy5wcm90bzJfbm9maWVsZHByZXNlbmNlX3VuaXR0", 
            "ZXN0LlRlc3RBbGxUeXBlcy5OZXN0ZWRNZXNzYWdlQgIoARIWCgxvbmVvZl91", 
            "aW50MzIYbyABKA1IABJbChRvbmVvZl9uZXN0ZWRfbWVzc2FnZRhwIAEoCzI7", 
            "LnByb3RvMl9ub2ZpZWxkcHJlc2VuY2VfdW5pdHRlc3QuVGVzdEFsbFR5cGVz", 
            "Lk5lc3RlZE1lc3NhZ2VIABIWCgxvbmVvZl9zdHJpbmcYcSABKAlIABJOCgpv", 
            "bmVvZl9lbnVtGHIgASgOMjgucHJvdG8yX25vZmllbGRwcmVzZW5jZV91bml0", 
            "dGVzdC5UZXN0QWxsVHlwZXMuTmVzdGVkRW51bUgAGhsKDU5lc3RlZE1lc3Nh", 
            "Z2USCgoCYmIYASABKAUiJwoKTmVzdGVkRW51bRIHCgNGT08QABIHCgNCQVIQ", 
            "ARIHCgNCQVoQAkINCgtvbmVvZl9maWVsZCJFChJUZXN0UHJvdG8yUmVxdWly", 
            "ZWQSLwoGcHJvdG8yGAEgASgLMh8ucHJvdG9idWZfdW5pdHRlc3QuVGVzdFJl", 
            "cXVpcmVkIhsKDkZvcmVpZ25NZXNzYWdlEgkKAWMYASABKAUqQAoLRm9yZWln", 
            "bkVudW0SDwoLRk9SRUlHTl9GT08QABIPCgtGT1JFSUdOX0JBUhABEg8KC0ZP", 
            "UkVJR05fQkFaEAJCJKoCIUdvb2dsZS5Qcm90b2NvbEJ1ZmZlcnMuVGVzdFBy", 
          "b3Rvc2IGcHJvdG8z"));
      pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
        descriptor = root;
        internal__static_proto2_nofieldpresence_unittest_TestAllTypes__Descriptor = Descriptor.MessageTypes[0];
        internal__static_proto2_nofieldpresence_unittest_TestAllTypes__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder>(internal__static_proto2_nofieldpresence_unittest_TestAllTypes__Descriptor,
                new string[] { "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalNestedMessage", "OptionalForeignMessage", "OptionalProto2Message", "OptionalNestedEnum", "OptionalForeignEnum", "OptionalStringPiece", "OptionalCord", "OptionalLazyMessage", "RepeatedInt32", "RepeatedInt64", "RepeatedUint32", "RepeatedUint64", "RepeatedSint32", "RepeatedSint64", "RepeatedFixed32", "RepeatedFixed64", "RepeatedSfixed32", "RepeatedSfixed64", "RepeatedFloat", "RepeatedDouble", "RepeatedBool", "RepeatedString", "RepeatedBytes", "RepeatedNestedMessage", "RepeatedForeignMessage", "RepeatedProto2Message", "RepeatedNestedEnum", "RepeatedForeignEnum", "RepeatedStringPiece", "RepeatedCord", "RepeatedLazyMessage", "OneofUint32", "OneofNestedMessage", "OneofString", "OneofEnum", });
        internal__static_proto2_nofieldpresence_unittest_TestAllTypes_NestedMessage__Descriptor = internal__static_proto2_nofieldpresence_unittest_TestAllTypes__Descriptor.NestedTypes[0];
        internal__static_proto2_nofieldpresence_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_proto2_nofieldpresence_unittest_TestAllTypes_NestedMessage__Descriptor,
                new string[] { "Bb", });
        internal__static_proto2_nofieldpresence_unittest_TestProto2Required__Descriptor = Descriptor.MessageTypes[1];
        internal__static_proto2_nofieldpresence_unittest_TestProto2Required__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestProto2Required, global::Google.ProtocolBuffers.TestProtos.TestProto2Required.Builder>(internal__static_proto2_nofieldpresence_unittest_TestProto2Required__Descriptor,
                new string[] { "Proto2", });
        internal__static_proto2_nofieldpresence_unittest_ForeignMessage__Descriptor = Descriptor.MessageTypes[2];
        internal__static_proto2_nofieldpresence_unittest_ForeignMessage__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.ForeignMessage, global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder>(internal__static_proto2_nofieldpresence_unittest_ForeignMessage__Descriptor,
                new string[] { "C", });
        pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();
        RegisterAllExtensions(registry);
        global::Google.ProtocolBuffers.TestProtos.Unittest.RegisterAllExtensions(registry);
        return registry;
      };
      pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
          new pbd::FileDescriptor[] {
          global::Google.ProtocolBuffers.TestProtos.Unittest.Descriptor, 
          }, assigner);
    }
    #endregion

  }
  #region Enums
  public enum ForeignEnum {
    FOREIGN_FOO = 0,
    FOREIGN_BAR = 1,
    FOREIGN_BAZ = 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[] { "oneof_enum", "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_int32", "optional_int64", "optional_lazy_message", "optional_nested_enum", "optional_nested_message", "optional_proto2_message", "optional_sfixed32", "optional_sfixed64", "optional_sint32", "optional_sint64", "optional_string", "optional_string_piece", "optional_uint32", "optional_uint64", "repeated_bool", "repeated_bytes", "repeated_cord", "repeated_double", "repeated_fixed32", "repeated_fixed64", "repeated_float", "repeated_foreign_enum", "repeated_foreign_message", "repeated_int32", "repeated_int64", "repeated_lazy_message", "repeated_nested_enum", "repeated_nested_message", "repeated_proto2_message", "repeated_sfixed32", "repeated_sfixed64", "repeated_sint32", "repeated_sint64", "repeated_string", "repeated_string_piece", "repeated_uint32", "repeated_uint64" };
    private static readonly uint[] _testAllTypesFieldTags = new uint[] { 912, 898, 906, 888, 104, 122, 202, 97, 61, 65, 93, 176, 154, 8, 16, 242, 168, 146, 162, 77, 81, 40, 48, 114, 194, 24, 32, 344, 362, 442, 337, 301, 305, 333, 416, 394, 248, 256, 458, 408, 386, 402, 317, 321, 280, 288, 354, 434, 264, 272 };
    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.UnittestNoFieldPresence.internal__static_proto2_nofieldpresence_unittest_TestAllTypes__Descriptor; }
    }

    protected override pb::FieldAccess.FieldAccessorTable<TestAllTypes, TestAllTypes.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnittestNoFieldPresence.internal__static_proto2_nofieldpresence_unittest_TestAllTypes__FieldAccessorTable; }
    }

    #region Nested types
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public static partial class Types {
      public enum NestedEnum {
        FOO = 0,
        BAR = 1,
        BAZ = 2,
      }

      [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.UnittestNoFieldPresence.internal__static_proto2_nofieldpresence_unittest_TestAllTypes_NestedMessage__Descriptor; }
        }

        protected override pb::FieldAccess.FieldAccessorTable<NestedMessage, NestedMessage.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.UnittestNoFieldPresence.internal__static_proto2_nofieldpresence_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.UnittestNoFieldPresence.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 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 OptionalProto2MessageFieldNumber = 20;
    private bool hasOptionalProto2Message;
    private global::Google.ProtocolBuffers.TestProtos.TestAllTypes optionalProto2Message_;
    public bool HasOptionalProto2Message {
      get { return hasOptionalProto2Message; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes OptionalProto2Message {
      get { return optionalProto2Message_ ?? global::Google.ProtocolBuffers.TestProtos.TestAllTypes.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 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 OptionalLazyMessageFieldNumber = 30;
    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 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 RepeatedProto2MessageFieldNumber = 50;
    private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> repeatedProto2Message_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes>();
    public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> RepeatedProto2MessageList {
      get { return repeatedProto2Message_; }
    }
    public int RepeatedProto2MessageCount {
      get { return repeatedProto2Message_.Count; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes GetRepeatedProto2Message(int index) {
      return repeatedProto2Message_[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 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 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 OneofEnumFieldNumber = 114;
    private bool hasOneofEnum;
    private global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum oneofEnum_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum.FOO;
    public bool HasOneofEnum {
      get { return hasOneofEnum; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum OneofEnum {
      get { return oneofEnum_; }
    }

    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[13], OptionalInt32);
      }
      if (hasOptionalInt64) {
        output.WriteInt64(2, field_names[14], OptionalInt64);
      }
      if (hasOptionalUint32) {
        output.WriteUInt32(3, field_names[25], OptionalUint32);
      }
      if (hasOptionalUint64) {
        output.WriteUInt64(4, field_names[26], OptionalUint64);
      }
      if (hasOptionalSint32) {
        output.WriteSInt32(5, field_names[21], OptionalSint32);
      }
      if (hasOptionalSint64) {
        output.WriteSInt64(6, field_names[22], OptionalSint64);
      }
      if (hasOptionalFixed32) {
        output.WriteFixed32(7, field_names[8], OptionalFixed32);
      }
      if (hasOptionalFixed64) {
        output.WriteFixed64(8, field_names[9], OptionalFixed64);
      }
      if (hasOptionalSfixed32) {
        output.WriteSFixed32(9, field_names[19], OptionalSfixed32);
      }
      if (hasOptionalSfixed64) {
        output.WriteSFixed64(10, field_names[20], OptionalSfixed64);
      }
      if (hasOptionalFloat) {
        output.WriteFloat(11, field_names[10], OptionalFloat);
      }
      if (hasOptionalDouble) {
        output.WriteDouble(12, field_names[7], OptionalDouble);
      }
      if (hasOptionalBool) {
        output.WriteBool(13, field_names[4], OptionalBool);
      }
      if (hasOptionalString) {
        output.WriteString(14, field_names[23], OptionalString);
      }
      if (hasOptionalBytes) {
        output.WriteBytes(15, field_names[5], OptionalBytes);
      }
      if (hasOptionalNestedMessage) {
        output.WriteMessage(18, field_names[17], OptionalNestedMessage);
      }
      if (hasOptionalForeignMessage) {
        output.WriteMessage(19, field_names[12], OptionalForeignMessage);
      }
      if (hasOptionalProto2Message) {
        output.WriteMessage(20, field_names[18], OptionalProto2Message);
      }
      if (hasOptionalNestedEnum) {
        output.WriteEnum(21, field_names[16], (int) OptionalNestedEnum, OptionalNestedEnum);
      }
      if (hasOptionalForeignEnum) {
        output.WriteEnum(22, field_names[11], (int) OptionalForeignEnum, OptionalForeignEnum);
      }
      if (hasOptionalStringPiece) {
        output.WriteString(24, field_names[24], OptionalStringPiece);
      }
      if (hasOptionalCord) {
        output.WriteString(25, field_names[6], OptionalCord);
      }
      if (hasOptionalLazyMessage) {
        output.WriteMessage(30, field_names[15], OptionalLazyMessage);
      }
      if (repeatedInt32_.Count > 0) {
        output.WriteInt32Array(31, field_names[36], repeatedInt32_);
      }
      if (repeatedInt64_.Count > 0) {
        output.WriteInt64Array(32, field_names[37], repeatedInt64_);
      }
      if (repeatedUint32_.Count > 0) {
        output.WriteUInt32Array(33, field_names[48], repeatedUint32_);
      }
      if (repeatedUint64_.Count > 0) {
        output.WriteUInt64Array(34, field_names[49], repeatedUint64_);
      }
      if (repeatedSint32_.Count > 0) {
        output.WriteSInt32Array(35, field_names[44], repeatedSint32_);
      }
      if (repeatedSint64_.Count > 0) {
        output.WriteSInt64Array(36, field_names[45], repeatedSint64_);
      }
      if (repeatedFixed32_.Count > 0) {
        output.WriteFixed32Array(37, field_names[31], repeatedFixed32_);
      }
      if (repeatedFixed64_.Count > 0) {
        output.WriteFixed64Array(38, field_names[32], repeatedFixed64_);
      }
      if (repeatedSfixed32_.Count > 0) {
        output.WriteSFixed32Array(39, field_names[42], repeatedSfixed32_);
      }
      if (repeatedSfixed64_.Count > 0) {
        output.WriteSFixed64Array(40, field_names[43], repeatedSfixed64_);
      }
      if (repeatedFloat_.Count > 0) {
        output.WriteFloatArray(41, field_names[33], repeatedFloat_);
      }
      if (repeatedDouble_.Count > 0) {
        output.WriteDoubleArray(42, field_names[30], repeatedDouble_);
      }
      if (repeatedBool_.Count > 0) {
        output.WriteBoolArray(43, field_names[27], repeatedBool_);
      }
      if (repeatedString_.Count > 0) {
        output.WriteStringArray(44, field_names[46], repeatedString_);
      }
      if (repeatedBytes_.Count > 0) {
        output.WriteBytesArray(45, field_names[28], repeatedBytes_);
      }
      if (repeatedNestedMessage_.Count > 0) {
        output.WriteMessageArray(48, field_names[40], repeatedNestedMessage_);
      }
      if (repeatedForeignMessage_.Count > 0) {
        output.WriteMessageArray(49, field_names[35], repeatedForeignMessage_);
      }
      if (repeatedProto2Message_.Count > 0) {
        output.WriteMessageArray(50, field_names[41], repeatedProto2Message_);
      }
      if (repeatedNestedEnum_.Count > 0) {
        output.WriteEnumArray(51, field_names[39], repeatedNestedEnum_);
      }
      if (repeatedForeignEnum_.Count > 0) {
        output.WriteEnumArray(52, field_names[34], repeatedForeignEnum_);
      }
      if (repeatedStringPiece_.Count > 0) {
        output.WriteStringArray(54, field_names[47], repeatedStringPiece_);
      }
      if (repeatedCord_.Count > 0) {
        output.WriteStringArray(55, field_names[29], repeatedCord_);
      }
      if (repeatedLazyMessage_.Count > 0) {
        output.WriteMessageArray(57, field_names[38], repeatedLazyMessage_);
      }
      if (hasOneofUint32) {
        output.WriteUInt32(111, field_names[3], OneofUint32);
      }
      if (hasOneofNestedMessage) {
        output.WriteMessage(112, field_names[1], OneofNestedMessage);
      }
      if (hasOneofString) {
        output.WriteString(113, field_names[2], OneofString);
      }
      if (hasOneofEnum) {
        output.WriteEnum(114, field_names[0], (int) OneofEnum, OneofEnum);
      }
      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 (hasOptionalNestedMessage) {
        size += pb::CodedOutputStream.ComputeMessageSize(18, OptionalNestedMessage);
      }
      if (hasOptionalForeignMessage) {
        size += pb::CodedOutputStream.ComputeMessageSize(19, OptionalForeignMessage);
      }
      if (hasOptionalProto2Message) {
        size += pb::CodedOutputStream.ComputeMessageSize(20, OptionalProto2Message);
      }
      if (hasOptionalNestedEnum) {
        size += pb::CodedOutputStream.ComputeEnumSize(21, (int) OptionalNestedEnum);
      }
      if (hasOptionalForeignEnum) {
        size += pb::CodedOutputStream.ComputeEnumSize(22, (int) OptionalForeignEnum);
      }
      if (hasOptionalStringPiece) {
        size += pb::CodedOutputStream.ComputeStringSize(24, OptionalStringPiece);
      }
      if (hasOptionalCord) {
        size += pb::CodedOutputStream.ComputeStringSize(25, OptionalCord);
      }
      if (hasOptionalLazyMessage) {
        size += pb::CodedOutputStream.ComputeMessageSize(30, 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.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.TestAllTypes element in RepeatedProto2MessageList) {
        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;
        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 (hasOneofUint32) {
        size += pb::CodedOutputStream.ComputeUInt32Size(111, OneofUint32);
      }
      if (hasOneofNestedMessage) {
        size += pb::CodedOutputStream.ComputeMessageSize(112, OneofNestedMessage);
      }
      if (hasOneofString) {
        size += pb::CodedOutputStream.ComputeStringSize(113, OneofString);
      }
      if (hasOneofEnum) {
        size += pb::CodedOutputStream.ComputeEnumSize(114, (int) OneofEnum);
      }
      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();
      repeatedNestedMessage_.MakeReadOnly();
      repeatedForeignMessage_.MakeReadOnly();
      repeatedProto2Message_.MakeReadOnly();
      repeatedNestedEnum_.MakeReadOnly();
      repeatedForeignEnum_.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.HasOptionalNestedMessage) {
          MergeOptionalNestedMessage(other.OptionalNestedMessage);
        }
        if (other.HasOptionalForeignMessage) {
          MergeOptionalForeignMessage(other.OptionalForeignMessage);
        }
        if (other.HasOptionalProto2Message) {
          MergeOptionalProto2Message(other.OptionalProto2Message);
        }
        if (other.HasOptionalNestedEnum) {
          OptionalNestedEnum = other.OptionalNestedEnum;
        }
        if (other.HasOptionalForeignEnum) {
          OptionalForeignEnum = other.OptionalForeignEnum;
        }
        if (other.HasOptionalStringPiece) {
          OptionalStringPiece = other.OptionalStringPiece;
        }
        if (other.HasOptionalCord) {
          OptionalCord = other.OptionalCord;
        }
        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.repeatedNestedMessage_.Count != 0) {
          result.repeatedNestedMessage_.Add(other.repeatedNestedMessage_);
        }
        if (other.repeatedForeignMessage_.Count != 0) {
          result.repeatedForeignMessage_.Add(other.repeatedForeignMessage_);
        }
        if (other.repeatedProto2Message_.Count != 0) {
          result.repeatedProto2Message_.Add(other.repeatedProto2Message_);
        }
        if (other.repeatedNestedEnum_.Count != 0) {
          result.repeatedNestedEnum_.Add(other.repeatedNestedEnum_);
        }
        if (other.repeatedForeignEnum_.Count != 0) {
          result.repeatedForeignEnum_.Add(other.repeatedForeignEnum_);
        }
        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.HasOneofUint32) {
          OneofUint32 = other.OneofUint32;
        }
        if (other.HasOneofNestedMessage) {
          MergeOneofNestedMessage(other.OneofNestedMessage);
        }
        if (other.HasOneofString) {
          OneofString = other.OneofString;
        }
        if (other.HasOneofEnum) {
          OneofEnum = other.OneofEnum;
        }
        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 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.TestAllTypes.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder();
              if (result.hasOptionalProto2Message) {
                subBuilder.MergeFrom(OptionalProto2Message);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              OptionalProto2Message = 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 194: {
              result.hasOptionalStringPiece = input.ReadString(ref result.optionalStringPiece_);
              break;
            }
            case 202: {
              result.hasOptionalCord = input.ReadString(ref result.optionalCord_);
              break;
            }
            case 242: {
              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 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.repeatedProto2Message_, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.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 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 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 912: {
              object unknown;
              if(input.ReadEnum(ref result.oneofEnum_, out unknown)) {
                result.hasOneofEnum = true;
              } else if(unknown is int) {
                if (unknownFields == null) {
                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
                }
                unknownFields.MergeVarintField(114, (ulong)(int)unknown);
              }
              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 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 HasOptionalProto2Message {
       get { return result.hasOptionalProto2Message; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestAllTypes OptionalProto2Message {
        get { return result.OptionalProto2Message; }
        set { SetOptionalProto2Message(value); }
      }
      public Builder SetOptionalProto2Message(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasOptionalProto2Message = true;
        result.optionalProto2Message_ = value;
        return this;
      }
      public Builder SetOptionalProto2Message(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasOptionalProto2Message = true;
        result.optionalProto2Message_ = builderForValue.Build();
        return this;
      }
      public Builder MergeOptionalProto2Message(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        if (result.hasOptionalProto2Message &&
            result.optionalProto2Message_ != global::Google.ProtocolBuffers.TestProtos.TestAllTypes.DefaultInstance) {
            result.optionalProto2Message_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.CreateBuilder(result.optionalProto2Message_).MergeFrom(value).BuildPartial();
        } else {
          result.optionalProto2Message_ = value;
        }
        result.hasOptionalProto2Message = true;
        return this;
      }
      public Builder ClearOptionalProto2Message() {
        PrepareBuilder();
        result.hasOptionalProto2Message = false;
        result.optionalProto2Message_ = 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 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 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.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.TestAllTypes> RepeatedProto2MessageList {
        get { return PrepareBuilder().repeatedProto2Message_; }
      }
      public int RepeatedProto2MessageCount {
        get { return result.RepeatedProto2MessageCount; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestAllTypes GetRepeatedProto2Message(int index) {
        return result.GetRepeatedProto2Message(index);
      }
      public Builder SetRepeatedProto2Message(int index, global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.repeatedProto2Message_[index] = value;
        return this;
      }
      public Builder SetRepeatedProto2Message(int index, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.repeatedProto2Message_[index] = builderForValue.Build();
        return this;
      }
      public Builder AddRepeatedProto2Message(global::Google.ProtocolBuffers.TestProtos.TestAllTypes value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.repeatedProto2Message_.Add(value);
        return this;
      }
      public Builder AddRepeatedProto2Message(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.repeatedProto2Message_.Add(builderForValue.Build());
        return this;
      }
      public Builder AddRangeRepeatedProto2Message(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestAllTypes> values) {
        PrepareBuilder();
        result.repeatedProto2Message_.Add(values);
        return this;
      }
      public Builder ClearRepeatedProto2Message() {
        PrepareBuilder();
        result.repeatedProto2Message_.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<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 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 HasOneofEnum {
       get { return result.hasOneofEnum; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum OneofEnum {
        get { return result.OneofEnum; }
        set { SetOneofEnum(value); }
      }
      public Builder SetOneofEnum(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum value) {
        PrepareBuilder();
        result.hasOneofEnum = true;
        result.oneofEnum_ = value;
        return this;
      }
      public Builder ClearOneofEnum() {
        PrepareBuilder();
        result.hasOneofEnum = false;
        result.oneofEnum_ = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum.FOO;
        return this;
      }
    }
    static TestAllTypes() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnittestNoFieldPresence.Descriptor, null);
    }
  }

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

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

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

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

    protected override pb::FieldAccess.FieldAccessorTable<TestProto2Required, TestProto2Required.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnittestNoFieldPresence.internal__static_proto2_nofieldpresence_unittest_TestProto2Required__FieldAccessorTable; }
    }

    public const int Proto2FieldNumber = 1;
    private bool hasProto2;
    private global::Google.ProtocolBuffers.TestProtos.TestRequired proto2_;
    public bool HasProto2 {
      get { return hasProto2; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestRequired Proto2 {
      get { return proto2_ ?? global::Google.ProtocolBuffers.TestProtos.TestRequired.DefaultInstance; }
    }

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

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

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

      private bool resultIsReadOnly;
      private TestProto2Required result;

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

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

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

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

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

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

      public override Builder MergeFrom(TestProto2Required other) {
        if (other == global::Google.ProtocolBuffers.TestProtos.TestProto2Required.DefaultInstance) return this;
        PrepareBuilder();
        if (other.HasProto2) {
          MergeProto2(other.Proto2);
        }
        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(_testProto2RequiredFieldNames, field_name, global::System.StringComparer.Ordinal);
            if(field_ordinal >= 0)
              tag = _testProto2RequiredFieldTags[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.hasProto2) {
                subBuilder.MergeFrom(Proto2);
              }
              input.ReadMessage(subBuilder, extensionRegistry);
              Proto2 = subBuilder.BuildPartial();
              break;
            }
          }
        }

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


      public bool HasProto2 {
       get { return result.hasProto2; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestRequired Proto2 {
        get { return result.Proto2; }
        set { SetProto2(value); }
      }
      public Builder SetProto2(global::Google.ProtocolBuffers.TestProtos.TestRequired value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasProto2 = true;
        result.proto2_ = value;
        return this;
      }
      public Builder SetProto2(global::Google.ProtocolBuffers.TestProtos.TestRequired.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasProto2 = true;
        result.proto2_ = builderForValue.Build();
        return this;
      }
      public Builder MergeProto2(global::Google.ProtocolBuffers.TestProtos.TestRequired value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        if (result.hasProto2 &&
            result.proto2_ != global::Google.ProtocolBuffers.TestProtos.TestRequired.DefaultInstance) {
            result.proto2_ = global::Google.ProtocolBuffers.TestProtos.TestRequired.CreateBuilder(result.proto2_).MergeFrom(value).BuildPartial();
        } else {
          result.proto2_ = value;
        }
        result.hasProto2 = true;
        return this;
      }
      public Builder ClearProto2() {
        PrepareBuilder();
        result.hasProto2 = false;
        result.proto2_ = null;
        return this;
      }
    }
    static TestProto2Required() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnittestNoFieldPresence.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.UnittestNoFieldPresence.internal__static_proto2_nofieldpresence_unittest_ForeignMessage__Descriptor; }
    }

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

  #endregion

}

#endregion Designer generated code
