// Generated by ProtoGen, Version=2.3.0.277, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48.  DO NOT EDIT!

using pb = global::Google.ProtocolBuffers;
using pbc = global::Google.ProtocolBuffers.Collections;
using pbd = global::Google.ProtocolBuffers.Descriptors;
using scg = global::System.Collections.Generic;
namespace Google.ProtocolBuffers.TestProtos {
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public static partial class UnitTestExtrasFullProtoFile {
  
    #region Extension registration
    public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
      registry.Add(global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.EmployeeId);
    }
    #endregion
    #region Extensions
    public const int EmployeeIdFieldNumber = 126;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.TestInteropEmployeeId> EmployeeId;
    #endregion
    
    #region Static variables
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_extra_TestInteropPerson__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestInteropPerson, global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Builder> internal__static_protobuf_unittest_extra_TestInteropPerson__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_extra_TestInteropPerson_PhoneNumber__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneNumber, global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneNumber.Builder> internal__static_protobuf_unittest_extra_TestInteropPerson_PhoneNumber__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_extra_TestInteropPerson_Addresses__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.Addresses, global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.Addresses.Builder> internal__static_protobuf_unittest_extra_TestInteropPerson_Addresses__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_extra_TestInteropEmployeeId__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestInteropEmployeeId, global::Google.ProtocolBuffers.TestProtos.TestInteropEmployeeId.Builder> internal__static_protobuf_unittest_extra_TestInteropEmployeeId__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_extra_TestMissingFieldsA__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA, global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Builder> internal__static_protobuf_unittest_extra_TestMissingFieldsA__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_extra_TestMissingFieldsA_SubA__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Types.SubA, global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Types.SubA.Builder> internal__static_protobuf_unittest_extra_TestMissingFieldsA_SubA__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_extra_TestMissingFieldsB__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB, global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Builder> internal__static_protobuf_unittest_extra_TestMissingFieldsB__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_extra_TestMissingFieldsB_SubB__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Types.SubB, global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Types.SubB.Builder> internal__static_protobuf_unittest_extra_TestMissingFieldsB_SubB__FieldAccessorTable;
    #endregion
    #region Descriptor
    public static pbd::FileDescriptor Descriptor {
      get { return descriptor; }
    }
    private static pbd::FileDescriptor descriptor;
    
    static UnitTestExtrasFullProtoFile() {
      byte[] descriptorData = global::System.Convert.FromBase64String(
          "CiFleHRlc3QvdW5pdHRlc3RfZXh0cmFzX2Z1bGwucHJvdG8SF3Byb3RvYnVm" + 
          "X3VuaXR0ZXN0X2V4dHJhGiRnb29nbGUvcHJvdG9idWYvY3NoYXJwX29wdGlv" + 
          "bnMucHJvdG8i1gMKEVRlc3RJbnRlcm9wUGVyc29uEgwKBG5hbWUYASACKAkS" + 
          "CgoCaWQYAiACKAUSDQoFZW1haWwYAyABKAkSEQoFY29kZXMYCiADKAVCAhAB" + 
          "EkUKBXBob25lGAQgAygLMjYucHJvdG9idWZfdW5pdHRlc3RfZXh0cmEuVGVz" + 
          "dEludGVyb3BQZXJzb24uUGhvbmVOdW1iZXISRwoJYWRkcmVzc2VzGAUgAygK" + 
          "MjQucHJvdG9idWZfdW5pdHRlc3RfZXh0cmEuVGVzdEludGVyb3BQZXJzb24u" + 
          "QWRkcmVzc2VzGmcKC1Bob25lTnVtYmVyEg4KBm51bWJlchgBIAIoCRJICgR0" + 
          "eXBlGAIgASgOMjQucHJvdG9idWZfdW5pdHRlc3RfZXh0cmEuVGVzdEludGVy" + 
          "b3BQZXJzb24uUGhvbmVUeXBlOgRIT01FGlgKCUFkZHJlc3NlcxIPCgdhZGRy" + 
          "ZXNzGAEgAigJEhAKCGFkZHJlc3MyGAIgASgJEgwKBGNpdHkYAyACKAkSDQoF" + 
          "c3RhdGUYBCACKAkSCwoDemlwGAUgAigHIisKCVBob25lVHlwZRIKCgZNT0JJ" + 
          "TEUQABIICgRIT01FEAESCAoEV09SSxACKgUIZBDIASInChVUZXN0SW50ZXJv" + 
          "cEVtcGxveWVlSWQSDgoGbnVtYmVyGAEgAigJIqUBChJUZXN0TWlzc2luZ0Zp" + 
          "ZWxkc0ESDAoEbmFtZRgBIAIoCRIKCgJpZBgCIAIoBRINCgVlbWFpbBgDIAEo" + 
          "CRI/CgV0ZXN0QRgLIAEoCzIwLnByb3RvYnVmX3VuaXR0ZXN0X2V4dHJhLlRl" + 
          "c3RNaXNzaW5nRmllbGRzQS5TdWJBGiUKBFN1YkESDQoFY291bnQYBSACKAUS" + 
          "DgoGdmFsdWVzGAYgAygJIpgBChJUZXN0TWlzc2luZ0ZpZWxkc0ISDAoEbmFt" + 
          "ZRgBIAIoCRIKCgJpZBgCIAIoBRIPCgd3ZWJzaXRlGAQgASgJEj8KBXRlc3RC" + 
          "GAwgASgLMjAucHJvdG9idWZfdW5pdHRlc3RfZXh0cmEuVGVzdE1pc3NpbmdG" + 
          "aWVsZHNCLlN1YkIaFgoEU3ViQhIOCgZ2YWx1ZXMYByADKAk6bwoLZW1wbG95" + 
          "ZWVfaWQSKi5wcm90b2J1Zl91bml0dGVzdF9leHRyYS5UZXN0SW50ZXJvcFBl" + 
          "cnNvbhh+IAIoCzIuLnByb3RvYnVmX3VuaXR0ZXN0X2V4dHJhLlRlc3RJbnRl" + 
          "cm9wRW1wbG95ZWVJZEJaChNjb20uZ29vZ2xlLnByb3RvYnVmSALCPkAKIUdv" + 
          "b2dsZS5Qcm90b2NvbEJ1ZmZlcnMuVGVzdFByb3RvcxIbVW5pdFRlc3RFeHRy" + 
          "YXNGdWxsUHJvdG9GaWxl");
      pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
        descriptor = root;
        internal__static_protobuf_unittest_extra_TestInteropPerson__Descriptor = Descriptor.MessageTypes[0];
        internal__static_protobuf_unittest_extra_TestInteropPerson__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestInteropPerson, global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Builder>(internal__static_protobuf_unittest_extra_TestInteropPerson__Descriptor,
                new string[] { "Name", "Id", "Email", "Codes", "Phone", "Addresses", });
        internal__static_protobuf_unittest_extra_TestInteropPerson_PhoneNumber__Descriptor = internal__static_protobuf_unittest_extra_TestInteropPerson__Descriptor.NestedTypes[0];
        internal__static_protobuf_unittest_extra_TestInteropPerson_PhoneNumber__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneNumber, global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneNumber.Builder>(internal__static_protobuf_unittest_extra_TestInteropPerson_PhoneNumber__Descriptor,
                new string[] { "Number", "Type", });
        internal__static_protobuf_unittest_extra_TestInteropPerson_Addresses__Descriptor = internal__static_protobuf_unittest_extra_TestInteropPerson__Descriptor.NestedTypes[1];
        internal__static_protobuf_unittest_extra_TestInteropPerson_Addresses__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.Addresses, global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.Addresses.Builder>(internal__static_protobuf_unittest_extra_TestInteropPerson_Addresses__Descriptor,
                new string[] { "Address", "Address2", "City", "State", "Zip", });
        internal__static_protobuf_unittest_extra_TestInteropEmployeeId__Descriptor = Descriptor.MessageTypes[1];
        internal__static_protobuf_unittest_extra_TestInteropEmployeeId__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestInteropEmployeeId, global::Google.ProtocolBuffers.TestProtos.TestInteropEmployeeId.Builder>(internal__static_protobuf_unittest_extra_TestInteropEmployeeId__Descriptor,
                new string[] { "Number", });
        internal__static_protobuf_unittest_extra_TestMissingFieldsA__Descriptor = Descriptor.MessageTypes[2];
        internal__static_protobuf_unittest_extra_TestMissingFieldsA__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA, global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Builder>(internal__static_protobuf_unittest_extra_TestMissingFieldsA__Descriptor,
                new string[] { "Name", "Id", "Email", "TestA", });
        internal__static_protobuf_unittest_extra_TestMissingFieldsA_SubA__Descriptor = internal__static_protobuf_unittest_extra_TestMissingFieldsA__Descriptor.NestedTypes[0];
        internal__static_protobuf_unittest_extra_TestMissingFieldsA_SubA__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Types.SubA, global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Types.SubA.Builder>(internal__static_protobuf_unittest_extra_TestMissingFieldsA_SubA__Descriptor,
                new string[] { "Count", "Values", });
        internal__static_protobuf_unittest_extra_TestMissingFieldsB__Descriptor = Descriptor.MessageTypes[3];
        internal__static_protobuf_unittest_extra_TestMissingFieldsB__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB, global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Builder>(internal__static_protobuf_unittest_extra_TestMissingFieldsB__Descriptor,
                new string[] { "Name", "Id", "Website", "TestB", });
        internal__static_protobuf_unittest_extra_TestMissingFieldsB_SubB__Descriptor = internal__static_protobuf_unittest_extra_TestMissingFieldsB__Descriptor.NestedTypes[0];
        internal__static_protobuf_unittest_extra_TestMissingFieldsB_SubB__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Types.SubB, global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Types.SubB.Builder>(internal__static_protobuf_unittest_extra_TestMissingFieldsB_SubB__Descriptor,
                new string[] { "Values", });
        global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.EmployeeId = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.TestInteropEmployeeId>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.Descriptor.Extensions[0]);
        pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();
        RegisterAllExtensions(registry);
        global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.RegisterAllExtensions(registry);
        return registry;
      };
      pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
          new pbd::FileDescriptor[] {
          global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor, 
          }, assigner);
    }
    #endregion
    
  }
  #region Messages
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public sealed partial class TestInteropPerson : pb::ExtendableMessage<TestInteropPerson, TestInteropPerson.Builder> {
    private static readonly TestInteropPerson defaultInstance = new Builder().BuildPartial();
    public static TestInteropPerson DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestInteropPerson DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestInteropPerson ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.internal__static_protobuf_unittest_extra_TestInteropPerson__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestInteropPerson, TestInteropPerson.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.internal__static_protobuf_unittest_extra_TestInteropPerson__FieldAccessorTable; }
    }
    
    #region Nested types
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public static class Types {
      [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
      [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
      public enum PhoneType {
        MOBILE = 0,
        HOME = 1,
        WORK = 2,
      }
      
      [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
      [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
      [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
      public sealed partial class PhoneNumber : pb::GeneratedMessage<PhoneNumber, PhoneNumber.Builder> {
        private static readonly PhoneNumber defaultInstance = new Builder().BuildPartial();
        public static PhoneNumber DefaultInstance {
          get { return defaultInstance; }
        }
        
        public override PhoneNumber DefaultInstanceForType {
          get { return defaultInstance; }
        }
        
        protected override PhoneNumber ThisMessage {
          get { return this; }
        }
        
        public static pbd::MessageDescriptor Descriptor {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.internal__static_protobuf_unittest_extra_TestInteropPerson_PhoneNumber__Descriptor; }
        }
        
        protected override pb::FieldAccess.FieldAccessorTable<PhoneNumber, PhoneNumber.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.internal__static_protobuf_unittest_extra_TestInteropPerson_PhoneNumber__FieldAccessorTable; }
        }
        
        public const int NumberFieldNumber = 1;
        private bool hasNumber;
        private string number_ = "";
        public bool HasNumber {
          get { return hasNumber; }
        }
        public string Number {
          get { return number_; }
        }
        
        public const int TypeFieldNumber = 2;
        private bool hasType;
        private global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneType type_ = global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneType.HOME;
        public bool HasType {
          get { return hasType; }
        }
        public global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneType Type {
          get { return type_; }
        }
        
        public static PhoneNumber ParseFrom(pb::ByteString data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static PhoneNumber ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static PhoneNumber ParseFrom(byte[] data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static PhoneNumber ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static PhoneNumber ParseFrom(global::System.IO.Stream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static PhoneNumber ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static PhoneNumber ParseDelimitedFrom(global::System.IO.Stream input) {
          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
        }
        public static PhoneNumber ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
        }
        public static PhoneNumber ParseFrom(pb::ICodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static PhoneNumber ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static Builder CreateBuilder() { return new Builder(); }
        public override Builder ToBuilder() { return CreateBuilder(this); }
        public override Builder CreateBuilderForType() { return new Builder(); }
        public static Builder CreateBuilder(PhoneNumber prototype) {
          return (Builder) new Builder().MergeFrom(prototype);
        }
        
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
        public sealed partial class Builder : pb::GeneratedBuilder<PhoneNumber, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {}
          
          PhoneNumber result = new PhoneNumber();
          
          protected override PhoneNumber MessageBeingBuilt {
            get { return result; }
          }
          
          public override Builder Clear() {
            result = new PhoneNumber();
            return this;
          }
          
          public override Builder Clone() {
            return new Builder().MergeFrom(result);
          }
          
          public override pbd::MessageDescriptor DescriptorForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneNumber.Descriptor; }
          }
          
          public override PhoneNumber DefaultInstanceForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneNumber.DefaultInstance; }
          }
          
          public override PhoneNumber BuildPartial() {
            if (result == null) {
              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
            }
            PhoneNumber returnMe = result;
            result = null;
            return returnMe;
          }
          
          
          public bool HasNumber {
            get { return result.hasNumber; }
          }
          public string Number {
            get { return result.Number; }
            set { SetNumber(value); }
          }
          public Builder SetNumber(string value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            result.hasNumber = true;
            result.number_ = value;
            return this;
          }
          public Builder ClearNumber() {
            result.hasNumber = false;
            result.number_ = "";
            return this;
          }
          
          public bool HasType {
           get { return result.hasType; }
          }
          public global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneType Type {
            get { return result.Type; }
            set { SetType(value); }
          }
          public Builder SetType(global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneType value) {
            result.hasType = true;
            result.type_ = value;
            return this;
          }
          public Builder ClearType() {
            result.hasType = false;
            result.type_ = global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneType.HOME;
            return this;
          }
        }
        static PhoneNumber() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.Descriptor, null);
        }
      }
      
      [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
      [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
      [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
      public sealed partial class Addresses : pb::GeneratedMessage<Addresses, Addresses.Builder> {
        private static readonly Addresses defaultInstance = new Builder().BuildPartial();
        public static Addresses DefaultInstance {
          get { return defaultInstance; }
        }
        
        public override Addresses DefaultInstanceForType {
          get { return defaultInstance; }
        }
        
        protected override Addresses ThisMessage {
          get { return this; }
        }
        
        public static pbd::MessageDescriptor Descriptor {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.internal__static_protobuf_unittest_extra_TestInteropPerson_Addresses__Descriptor; }
        }
        
        protected override pb::FieldAccess.FieldAccessorTable<Addresses, Addresses.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.internal__static_protobuf_unittest_extra_TestInteropPerson_Addresses__FieldAccessorTable; }
        }
        
        public const int AddressFieldNumber = 1;
        private bool hasAddress;
        private string address_ = "";
        public bool HasAddress {
          get { return hasAddress; }
        }
        public string Address {
          get { return address_; }
        }
        
        public const int Address2FieldNumber = 2;
        private bool hasAddress2;
        private string address2_ = "";
        public bool HasAddress2 {
          get { return hasAddress2; }
        }
        public string Address2 {
          get { return address2_; }
        }
        
        public const int CityFieldNumber = 3;
        private bool hasCity;
        private string city_ = "";
        public bool HasCity {
          get { return hasCity; }
        }
        public string City {
          get { return city_; }
        }
        
        public const int StateFieldNumber = 4;
        private bool hasState;
        private string state_ = "";
        public bool HasState {
          get { return hasState; }
        }
        public string State {
          get { return state_; }
        }
        
        public const int ZipFieldNumber = 5;
        private bool hasZip;
        private uint zip_;
        public bool HasZip {
          get { return hasZip; }
        }
        [global::System.CLSCompliant(false)]
        public uint Zip {
          get { return zip_; }
        }
        
        public static Addresses ParseFrom(pb::ByteString data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static Addresses ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static Addresses ParseFrom(byte[] data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static Addresses ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static Addresses ParseFrom(global::System.IO.Stream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static Addresses ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static Addresses ParseDelimitedFrom(global::System.IO.Stream input) {
          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
        }
        public static Addresses ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
        }
        public static Addresses ParseFrom(pb::ICodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static Addresses ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static Builder CreateBuilder() { return new Builder(); }
        public override Builder ToBuilder() { return CreateBuilder(this); }
        public override Builder CreateBuilderForType() { return new Builder(); }
        public static Builder CreateBuilder(Addresses prototype) {
          return (Builder) new Builder().MergeFrom(prototype);
        }
        
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
        public sealed partial class Builder : pb::GeneratedBuilder<Addresses, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {}
          
          Addresses result = new Addresses();
          
          protected override Addresses MessageBeingBuilt {
            get { return result; }
          }
          
          public override Builder Clear() {
            result = new Addresses();
            return this;
          }
          
          public override Builder Clone() {
            return new Builder().MergeFrom(result);
          }
          
          public override pbd::MessageDescriptor DescriptorForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.Addresses.Descriptor; }
          }
          
          public override Addresses DefaultInstanceForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.Addresses.DefaultInstance; }
          }
          
          public override Addresses BuildPartial() {
            if (result == null) {
              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
            }
            Addresses returnMe = result;
            result = null;
            return returnMe;
          }
          
          
          public bool HasAddress {
            get { return result.hasAddress; }
          }
          public string Address {
            get { return result.Address; }
            set { SetAddress(value); }
          }
          public Builder SetAddress(string value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            result.hasAddress = true;
            result.address_ = value;
            return this;
          }
          public Builder ClearAddress() {
            result.hasAddress = false;
            result.address_ = "";
            return this;
          }
          
          public bool HasAddress2 {
            get { return result.hasAddress2; }
          }
          public string Address2 {
            get { return result.Address2; }
            set { SetAddress2(value); }
          }
          public Builder SetAddress2(string value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            result.hasAddress2 = true;
            result.address2_ = value;
            return this;
          }
          public Builder ClearAddress2() {
            result.hasAddress2 = false;
            result.address2_ = "";
            return this;
          }
          
          public bool HasCity {
            get { return result.hasCity; }
          }
          public string City {
            get { return result.City; }
            set { SetCity(value); }
          }
          public Builder SetCity(string value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            result.hasCity = true;
            result.city_ = value;
            return this;
          }
          public Builder ClearCity() {
            result.hasCity = false;
            result.city_ = "";
            return this;
          }
          
          public bool HasState {
            get { return result.hasState; }
          }
          public string State {
            get { return result.State; }
            set { SetState(value); }
          }
          public Builder SetState(string value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            result.hasState = true;
            result.state_ = value;
            return this;
          }
          public Builder ClearState() {
            result.hasState = false;
            result.state_ = "";
            return this;
          }
          
          public bool HasZip {
            get { return result.hasZip; }
          }
          [global::System.CLSCompliant(false)]
          public uint Zip {
            get { return result.Zip; }
            set { SetZip(value); }
          }
          [global::System.CLSCompliant(false)]
          public Builder SetZip(uint value) {
            result.hasZip = true;
            result.zip_ = value;
            return this;
          }
          public Builder ClearZip() {
            result.hasZip = false;
            result.zip_ = 0;
            return this;
          }
        }
        static Addresses() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.Descriptor, null);
        }
      }
      
    }
    #endregion
    
    public const int NameFieldNumber = 1;
    private bool hasName;
    private string name_ = "";
    public bool HasName {
      get { return hasName; }
    }
    public string Name {
      get { return name_; }
    }
    
    public const int IdFieldNumber = 2;
    private bool hasId;
    private int id_;
    public bool HasId {
      get { return hasId; }
    }
    public int Id {
      get { return id_; }
    }
    
    public const int EmailFieldNumber = 3;
    private bool hasEmail;
    private string email_ = "";
    public bool HasEmail {
      get { return hasEmail; }
    }
    public string Email {
      get { return email_; }
    }
    
    public const int CodesFieldNumber = 10;
    private pbc::PopsicleList<int> codes_ = new pbc::PopsicleList<int>();
    public scg::IList<int> CodesList {
      get { return pbc::Lists.AsReadOnly(codes_); }
    }
    public int CodesCount {
      get { return codes_.Count; }
    }
    public int GetCodes(int index) {
      return codes_[index];
    }
    
    public const int PhoneFieldNumber = 4;
    private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneNumber> phone_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneNumber>();
    public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneNumber> PhoneList {
      get { return phone_; }
    }
    public int PhoneCount {
      get { return phone_.Count; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneNumber GetPhone(int index) {
      return phone_[index];
    }
    
    public const int AddressesFieldNumber = 5;
    private pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.Addresses> addresses_ = new pbc::PopsicleList<global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.Addresses>();
    public scg::IList<global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.Addresses> AddressesList {
      get { return addresses_; }
    }
    public int AddressesCount {
      get { return addresses_.Count; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.Addresses GetAddresses(int index) {
      return addresses_[index];
    }
    
    public static TestInteropPerson ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestInteropPerson ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestInteropPerson ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestInteropPerson ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestInteropPerson ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestInteropPerson ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestInteropPerson ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestInteropPerson ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestInteropPerson ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestInteropPerson ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static Builder CreateBuilder() { return new Builder(); }
    public override Builder ToBuilder() { return CreateBuilder(this); }
    public override Builder CreateBuilderForType() { return new Builder(); }
    public static Builder CreateBuilder(TestInteropPerson prototype) {
      return (Builder) new Builder().MergeFrom(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public sealed partial class Builder : pb::ExtendableBuilder<TestInteropPerson, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestInteropPerson result = new TestInteropPerson();
      
      protected override TestInteropPerson MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestInteropPerson();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Descriptor; }
      }
      
      public override TestInteropPerson DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.DefaultInstance; }
      }
      
      public override TestInteropPerson BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        result.codes_.MakeReadOnly();
        result.phone_.MakeReadOnly();
        result.addresses_.MakeReadOnly();
        TestInteropPerson returnMe = result;
        result = null;
        return returnMe;
      }
      
      
      public bool HasName {
        get { return result.hasName; }
      }
      public string Name {
        get { return result.Name; }
        set { SetName(value); }
      }
      public Builder SetName(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasName = true;
        result.name_ = value;
        return this;
      }
      public Builder ClearName() {
        result.hasName = false;
        result.name_ = "";
        return this;
      }
      
      public bool HasId {
        get { return result.hasId; }
      }
      public int Id {
        get { return result.Id; }
        set { SetId(value); }
      }
      public Builder SetId(int value) {
        result.hasId = true;
        result.id_ = value;
        return this;
      }
      public Builder ClearId() {
        result.hasId = false;
        result.id_ = 0;
        return this;
      }
      
      public bool HasEmail {
        get { return result.hasEmail; }
      }
      public string Email {
        get { return result.Email; }
        set { SetEmail(value); }
      }
      public Builder SetEmail(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasEmail = true;
        result.email_ = value;
        return this;
      }
      public Builder ClearEmail() {
        result.hasEmail = false;
        result.email_ = "";
        return this;
      }
      
      public pbc::IPopsicleList<int> CodesList {
        get { return result.codes_; }
      }
      public int CodesCount {
        get { return result.CodesCount; }
      }
      public int GetCodes(int index) {
        return result.GetCodes(index);
      }
      public Builder SetCodes(int index, int value) {
        result.codes_[index] = value;
        return this;
      }
      public Builder AddCodes(int value) {
        result.codes_.Add(value);
        return this;
      }
      public Builder AddRangeCodes(scg::IEnumerable<int> values) {
        base.AddRange(values, result.codes_);
        return this;
      }
      public Builder ClearCodes() {
        result.codes_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneNumber> PhoneList {
        get { return result.phone_; }
      }
      public int PhoneCount {
        get { return result.PhoneCount; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneNumber GetPhone(int index) {
        return result.GetPhone(index);
      }
      public Builder SetPhone(int index, global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneNumber value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.phone_[index] = value;
        return this;
      }
      public Builder SetPhone(int index, global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneNumber.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.phone_[index] = builderForValue.Build();
        return this;
      }
      public Builder AddPhone(global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneNumber value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.phone_.Add(value);
        return this;
      }
      public Builder AddPhone(global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneNumber.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.phone_.Add(builderForValue.Build());
        return this;
      }
      public Builder AddRangePhone(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.PhoneNumber> values) {
        base.AddRange(values, result.phone_);
        return this;
      }
      public Builder ClearPhone() {
        result.phone_.Clear();
        return this;
      }
      
      public pbc::IPopsicleList<global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.Addresses> AddressesList {
        get { return result.addresses_; }
      }
      public int AddressesCount {
        get { return result.AddressesCount; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.Addresses GetAddresses(int index) {
        return result.GetAddresses(index);
      }
      public Builder SetAddresses(int index, global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.Addresses value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.addresses_[index] = value;
        return this;
      }
      public Builder SetAddresses(int index, global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.Addresses.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.addresses_[index] = builderForValue.Build();
        return this;
      }
      public Builder AddAddresses(global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.Addresses value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.addresses_.Add(value);
        return this;
      }
      public Builder AddAddresses(global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.Addresses.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.addresses_.Add(builderForValue.Build());
        return this;
      }
      public Builder AddRangeAddresses(scg::IEnumerable<global::Google.ProtocolBuffers.TestProtos.TestInteropPerson.Types.Addresses> values) {
        base.AddRange(values, result.addresses_);
        return this;
      }
      public Builder ClearAddresses() {
        result.addresses_.Clear();
        return this;
      }
    }
    static TestInteropPerson() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public sealed partial class TestInteropEmployeeId : pb::GeneratedMessage<TestInteropEmployeeId, TestInteropEmployeeId.Builder> {
    private static readonly TestInteropEmployeeId defaultInstance = new Builder().BuildPartial();
    public static TestInteropEmployeeId DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestInteropEmployeeId DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestInteropEmployeeId ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.internal__static_protobuf_unittest_extra_TestInteropEmployeeId__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestInteropEmployeeId, TestInteropEmployeeId.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.internal__static_protobuf_unittest_extra_TestInteropEmployeeId__FieldAccessorTable; }
    }
    
    public const int NumberFieldNumber = 1;
    private bool hasNumber;
    private string number_ = "";
    public bool HasNumber {
      get { return hasNumber; }
    }
    public string Number {
      get { return number_; }
    }
    
    public static TestInteropEmployeeId ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestInteropEmployeeId ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestInteropEmployeeId ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestInteropEmployeeId ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestInteropEmployeeId ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestInteropEmployeeId ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestInteropEmployeeId ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestInteropEmployeeId ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestInteropEmployeeId ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestInteropEmployeeId ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static Builder CreateBuilder() { return new Builder(); }
    public override Builder ToBuilder() { return CreateBuilder(this); }
    public override Builder CreateBuilderForType() { return new Builder(); }
    public static Builder CreateBuilder(TestInteropEmployeeId prototype) {
      return (Builder) new Builder().MergeFrom(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public sealed partial class Builder : pb::GeneratedBuilder<TestInteropEmployeeId, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestInteropEmployeeId result = new TestInteropEmployeeId();
      
      protected override TestInteropEmployeeId MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestInteropEmployeeId();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestInteropEmployeeId.Descriptor; }
      }
      
      public override TestInteropEmployeeId DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestInteropEmployeeId.DefaultInstance; }
      }
      
      public override TestInteropEmployeeId BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        TestInteropEmployeeId returnMe = result;
        result = null;
        return returnMe;
      }
      
      
      public bool HasNumber {
        get { return result.hasNumber; }
      }
      public string Number {
        get { return result.Number; }
        set { SetNumber(value); }
      }
      public Builder SetNumber(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasNumber = true;
        result.number_ = value;
        return this;
      }
      public Builder ClearNumber() {
        result.hasNumber = false;
        result.number_ = "";
        return this;
      }
    }
    static TestInteropEmployeeId() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public sealed partial class TestMissingFieldsA : pb::GeneratedMessage<TestMissingFieldsA, TestMissingFieldsA.Builder> {
    private static readonly TestMissingFieldsA defaultInstance = new Builder().BuildPartial();
    public static TestMissingFieldsA DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestMissingFieldsA DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestMissingFieldsA ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.internal__static_protobuf_unittest_extra_TestMissingFieldsA__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestMissingFieldsA, TestMissingFieldsA.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.internal__static_protobuf_unittest_extra_TestMissingFieldsA__FieldAccessorTable; }
    }
    
    #region Nested types
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public static class Types {
      [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
      [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
      [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
      public sealed partial class SubA : pb::GeneratedMessage<SubA, SubA.Builder> {
        private static readonly SubA defaultInstance = new Builder().BuildPartial();
        public static SubA DefaultInstance {
          get { return defaultInstance; }
        }
        
        public override SubA DefaultInstanceForType {
          get { return defaultInstance; }
        }
        
        protected override SubA ThisMessage {
          get { return this; }
        }
        
        public static pbd::MessageDescriptor Descriptor {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.internal__static_protobuf_unittest_extra_TestMissingFieldsA_SubA__Descriptor; }
        }
        
        protected override pb::FieldAccess.FieldAccessorTable<SubA, SubA.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.internal__static_protobuf_unittest_extra_TestMissingFieldsA_SubA__FieldAccessorTable; }
        }
        
        public const int CountFieldNumber = 5;
        private bool hasCount;
        private int count_;
        public bool HasCount {
          get { return hasCount; }
        }
        public int Count {
          get { return count_; }
        }
        
        public const int ValuesFieldNumber = 6;
        private pbc::PopsicleList<string> values_ = new pbc::PopsicleList<string>();
        public scg::IList<string> ValuesList {
          get { return pbc::Lists.AsReadOnly(values_); }
        }
        public int ValuesCount {
          get { return values_.Count; }
        }
        public string GetValues(int index) {
          return values_[index];
        }
        
        public static SubA ParseFrom(pb::ByteString data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static SubA ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static SubA ParseFrom(byte[] data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static SubA ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static SubA ParseFrom(global::System.IO.Stream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static SubA ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static SubA ParseDelimitedFrom(global::System.IO.Stream input) {
          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
        }
        public static SubA ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
        }
        public static SubA ParseFrom(pb::ICodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static SubA ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static Builder CreateBuilder() { return new Builder(); }
        public override Builder ToBuilder() { return CreateBuilder(this); }
        public override Builder CreateBuilderForType() { return new Builder(); }
        public static Builder CreateBuilder(SubA prototype) {
          return (Builder) new Builder().MergeFrom(prototype);
        }
        
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
        public sealed partial class Builder : pb::GeneratedBuilder<SubA, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {}
          
          SubA result = new SubA();
          
          protected override SubA MessageBeingBuilt {
            get { return result; }
          }
          
          public override Builder Clear() {
            result = new SubA();
            return this;
          }
          
          public override Builder Clone() {
            return new Builder().MergeFrom(result);
          }
          
          public override pbd::MessageDescriptor DescriptorForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Types.SubA.Descriptor; }
          }
          
          public override SubA DefaultInstanceForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Types.SubA.DefaultInstance; }
          }
          
          public override SubA BuildPartial() {
            if (result == null) {
              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
            }
            result.values_.MakeReadOnly();
            SubA returnMe = result;
            result = null;
            return returnMe;
          }
          
          
          public bool HasCount {
            get { return result.hasCount; }
          }
          public int Count {
            get { return result.Count; }
            set { SetCount(value); }
          }
          public Builder SetCount(int value) {
            result.hasCount = true;
            result.count_ = value;
            return this;
          }
          public Builder ClearCount() {
            result.hasCount = false;
            result.count_ = 0;
            return this;
          }
          
          public pbc::IPopsicleList<string> ValuesList {
            get { return result.values_; }
          }
          public int ValuesCount {
            get { return result.ValuesCount; }
          }
          public string GetValues(int index) {
            return result.GetValues(index);
          }
          public Builder SetValues(int index, string value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            result.values_[index] = value;
            return this;
          }
          public Builder AddValues(string value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            result.values_.Add(value);
            return this;
          }
          public Builder AddRangeValues(scg::IEnumerable<string> values) {
            base.AddRange(values, result.values_);
            return this;
          }
          public Builder ClearValues() {
            result.values_.Clear();
            return this;
          }
        }
        static SubA() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.Descriptor, null);
        }
      }
      
    }
    #endregion
    
    public const int NameFieldNumber = 1;
    private bool hasName;
    private string name_ = "";
    public bool HasName {
      get { return hasName; }
    }
    public string Name {
      get { return name_; }
    }
    
    public const int IdFieldNumber = 2;
    private bool hasId;
    private int id_;
    public bool HasId {
      get { return hasId; }
    }
    public int Id {
      get { return id_; }
    }
    
    public const int EmailFieldNumber = 3;
    private bool hasEmail;
    private string email_ = "";
    public bool HasEmail {
      get { return hasEmail; }
    }
    public string Email {
      get { return email_; }
    }
    
    public const int TestAFieldNumber = 11;
    private bool hasTestA;
    private global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Types.SubA testA_ = global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Types.SubA.DefaultInstance;
    public bool HasTestA {
      get { return hasTestA; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Types.SubA TestA {
      get { return testA_; }
    }
    
    public static TestMissingFieldsA ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestMissingFieldsA ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestMissingFieldsA ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestMissingFieldsA ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestMissingFieldsA ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestMissingFieldsA ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestMissingFieldsA ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestMissingFieldsA ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestMissingFieldsA ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestMissingFieldsA ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static Builder CreateBuilder() { return new Builder(); }
    public override Builder ToBuilder() { return CreateBuilder(this); }
    public override Builder CreateBuilderForType() { return new Builder(); }
    public static Builder CreateBuilder(TestMissingFieldsA prototype) {
      return (Builder) new Builder().MergeFrom(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public sealed partial class Builder : pb::GeneratedBuilder<TestMissingFieldsA, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestMissingFieldsA result = new TestMissingFieldsA();
      
      protected override TestMissingFieldsA MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestMissingFieldsA();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Descriptor; }
      }
      
      public override TestMissingFieldsA DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.DefaultInstance; }
      }
      
      public override TestMissingFieldsA BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        TestMissingFieldsA returnMe = result;
        result = null;
        return returnMe;
      }
      
      
      public bool HasName {
        get { return result.hasName; }
      }
      public string Name {
        get { return result.Name; }
        set { SetName(value); }
      }
      public Builder SetName(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasName = true;
        result.name_ = value;
        return this;
      }
      public Builder ClearName() {
        result.hasName = false;
        result.name_ = "";
        return this;
      }
      
      public bool HasId {
        get { return result.hasId; }
      }
      public int Id {
        get { return result.Id; }
        set { SetId(value); }
      }
      public Builder SetId(int value) {
        result.hasId = true;
        result.id_ = value;
        return this;
      }
      public Builder ClearId() {
        result.hasId = false;
        result.id_ = 0;
        return this;
      }
      
      public bool HasEmail {
        get { return result.hasEmail; }
      }
      public string Email {
        get { return result.Email; }
        set { SetEmail(value); }
      }
      public Builder SetEmail(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasEmail = true;
        result.email_ = value;
        return this;
      }
      public Builder ClearEmail() {
        result.hasEmail = false;
        result.email_ = "";
        return this;
      }
      
      public bool HasTestA {
       get { return result.hasTestA; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Types.SubA TestA {
        get { return result.TestA; }
        set { SetTestA(value); }
      }
      public Builder SetTestA(global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Types.SubA value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasTestA = true;
        result.testA_ = value;
        return this;
      }
      public Builder SetTestA(global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Types.SubA.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.hasTestA = true;
        result.testA_ = builderForValue.Build();
        return this;
      }
      public Builder MergeTestA(global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Types.SubA value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        if (result.hasTestA &&
            result.testA_ != global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Types.SubA.DefaultInstance) {
            result.testA_ = global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Types.SubA.CreateBuilder(result.testA_).MergeFrom(value).BuildPartial();
        } else {
          result.testA_ = value;
        }
        result.hasTestA = true;
        return this;
      }
      public Builder ClearTestA() {
        result.hasTestA = false;
        result.testA_ = global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsA.Types.SubA.DefaultInstance;
        return this;
      }
    }
    static TestMissingFieldsA() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
  [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
  public sealed partial class TestMissingFieldsB : pb::GeneratedMessage<TestMissingFieldsB, TestMissingFieldsB.Builder> {
    private static readonly TestMissingFieldsB defaultInstance = new Builder().BuildPartial();
    public static TestMissingFieldsB DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestMissingFieldsB DefaultInstanceForType {
      get { return defaultInstance; }
    }
    
    protected override TestMissingFieldsB ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.internal__static_protobuf_unittest_extra_TestMissingFieldsB__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestMissingFieldsB, TestMissingFieldsB.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.internal__static_protobuf_unittest_extra_TestMissingFieldsB__FieldAccessorTable; }
    }
    
    #region Nested types
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public static class Types {
      [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
      [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
      [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
      public sealed partial class SubB : pb::GeneratedMessage<SubB, SubB.Builder> {
        private static readonly SubB defaultInstance = new Builder().BuildPartial();
        public static SubB DefaultInstance {
          get { return defaultInstance; }
        }
        
        public override SubB DefaultInstanceForType {
          get { return defaultInstance; }
        }
        
        protected override SubB ThisMessage {
          get { return this; }
        }
        
        public static pbd::MessageDescriptor Descriptor {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.internal__static_protobuf_unittest_extra_TestMissingFieldsB_SubB__Descriptor; }
        }
        
        protected override pb::FieldAccess.FieldAccessorTable<SubB, SubB.Builder> InternalFieldAccessors {
          get { return global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.internal__static_protobuf_unittest_extra_TestMissingFieldsB_SubB__FieldAccessorTable; }
        }
        
        public const int ValuesFieldNumber = 7;
        private pbc::PopsicleList<string> values_ = new pbc::PopsicleList<string>();
        public scg::IList<string> ValuesList {
          get { return pbc::Lists.AsReadOnly(values_); }
        }
        public int ValuesCount {
          get { return values_.Count; }
        }
        public string GetValues(int index) {
          return values_[index];
        }
        
        public static SubB ParseFrom(pb::ByteString data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static SubB ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static SubB ParseFrom(byte[] data) {
          return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
        }
        public static SubB ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
        }
        public static SubB ParseFrom(global::System.IO.Stream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static SubB ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static SubB ParseDelimitedFrom(global::System.IO.Stream input) {
          return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
        }
        public static SubB ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
          return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
        }
        public static SubB ParseFrom(pb::ICodedInputStream input) {
          return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
        }
        public static SubB ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
          return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
        }
        public static Builder CreateBuilder() { return new Builder(); }
        public override Builder ToBuilder() { return CreateBuilder(this); }
        public override Builder CreateBuilderForType() { return new Builder(); }
        public static Builder CreateBuilder(SubB prototype) {
          return (Builder) new Builder().MergeFrom(prototype);
        }
        
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
        [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
        [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
        public sealed partial class Builder : pb::GeneratedBuilder<SubB, Builder> {
          protected override Builder ThisBuilder {
            get { return this; }
          }
          public Builder() {}
          
          SubB result = new SubB();
          
          protected override SubB MessageBeingBuilt {
            get { return result; }
          }
          
          public override Builder Clear() {
            result = new SubB();
            return this;
          }
          
          public override Builder Clone() {
            return new Builder().MergeFrom(result);
          }
          
          public override pbd::MessageDescriptor DescriptorForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Types.SubB.Descriptor; }
          }
          
          public override SubB DefaultInstanceForType {
            get { return global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Types.SubB.DefaultInstance; }
          }
          
          public override SubB BuildPartial() {
            if (result == null) {
              throw new global::System.InvalidOperationException("build() has already been called on this Builder");
            }
            result.values_.MakeReadOnly();
            SubB returnMe = result;
            result = null;
            return returnMe;
          }
          
          
          public pbc::IPopsicleList<string> ValuesList {
            get { return result.values_; }
          }
          public int ValuesCount {
            get { return result.ValuesCount; }
          }
          public string GetValues(int index) {
            return result.GetValues(index);
          }
          public Builder SetValues(int index, string value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            result.values_[index] = value;
            return this;
          }
          public Builder AddValues(string value) {
            pb::ThrowHelper.ThrowIfNull(value, "value");
            result.values_.Add(value);
            return this;
          }
          public Builder AddRangeValues(scg::IEnumerable<string> values) {
            base.AddRange(values, result.values_);
            return this;
          }
          public Builder ClearValues() {
            result.values_.Clear();
            return this;
          }
        }
        static SubB() {
          object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.Descriptor, null);
        }
      }
      
    }
    #endregion
    
    public const int NameFieldNumber = 1;
    private bool hasName;
    private string name_ = "";
    public bool HasName {
      get { return hasName; }
    }
    public string Name {
      get { return name_; }
    }
    
    public const int IdFieldNumber = 2;
    private bool hasId;
    private int id_;
    public bool HasId {
      get { return hasId; }
    }
    public int Id {
      get { return id_; }
    }
    
    public const int WebsiteFieldNumber = 4;
    private bool hasWebsite;
    private string website_ = "";
    public bool HasWebsite {
      get { return hasWebsite; }
    }
    public string Website {
      get { return website_; }
    }
    
    public const int TestBFieldNumber = 12;
    private bool hasTestB;
    private global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Types.SubB testB_ = global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Types.SubB.DefaultInstance;
    public bool HasTestB {
      get { return hasTestB; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Types.SubB TestB {
      get { return testB_; }
    }
    
    public static TestMissingFieldsB ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestMissingFieldsB ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestMissingFieldsB ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestMissingFieldsB ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestMissingFieldsB ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestMissingFieldsB ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestMissingFieldsB ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestMissingFieldsB ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestMissingFieldsB ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestMissingFieldsB ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static Builder CreateBuilder() { return new Builder(); }
    public override Builder ToBuilder() { return CreateBuilder(this); }
    public override Builder CreateBuilderForType() { return new Builder(); }
    public static Builder CreateBuilder(TestMissingFieldsB prototype) {
      return (Builder) new Builder().MergeFrom(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
    public sealed partial class Builder : pb::GeneratedBuilder<TestMissingFieldsB, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {}
      
      TestMissingFieldsB result = new TestMissingFieldsB();
      
      protected override TestMissingFieldsB MessageBeingBuilt {
        get { return result; }
      }
      
      public override Builder Clear() {
        result = new TestMissingFieldsB();
        return this;
      }
      
      public override Builder Clone() {
        return new Builder().MergeFrom(result);
      }
      
      public override pbd::MessageDescriptor DescriptorForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Descriptor; }
      }
      
      public override TestMissingFieldsB DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.DefaultInstance; }
      }
      
      public override TestMissingFieldsB BuildPartial() {
        if (result == null) {
          throw new global::System.InvalidOperationException("build() has already been called on this Builder");
        }
        TestMissingFieldsB returnMe = result;
        result = null;
        return returnMe;
      }
      
      
      public bool HasName {
        get { return result.hasName; }
      }
      public string Name {
        get { return result.Name; }
        set { SetName(value); }
      }
      public Builder SetName(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasName = true;
        result.name_ = value;
        return this;
      }
      public Builder ClearName() {
        result.hasName = false;
        result.name_ = "";
        return this;
      }
      
      public bool HasId {
        get { return result.hasId; }
      }
      public int Id {
        get { return result.Id; }
        set { SetId(value); }
      }
      public Builder SetId(int value) {
        result.hasId = true;
        result.id_ = value;
        return this;
      }
      public Builder ClearId() {
        result.hasId = false;
        result.id_ = 0;
        return this;
      }
      
      public bool HasWebsite {
        get { return result.hasWebsite; }
      }
      public string Website {
        get { return result.Website; }
        set { SetWebsite(value); }
      }
      public Builder SetWebsite(string value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasWebsite = true;
        result.website_ = value;
        return this;
      }
      public Builder ClearWebsite() {
        result.hasWebsite = false;
        result.website_ = "";
        return this;
      }
      
      public bool HasTestB {
       get { return result.hasTestB; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Types.SubB TestB {
        get { return result.TestB; }
        set { SetTestB(value); }
      }
      public Builder SetTestB(global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Types.SubB value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        result.hasTestB = true;
        result.testB_ = value;
        return this;
      }
      public Builder SetTestB(global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Types.SubB.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        result.hasTestB = true;
        result.testB_ = builderForValue.Build();
        return this;
      }
      public Builder MergeTestB(global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Types.SubB value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        if (result.hasTestB &&
            result.testB_ != global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Types.SubB.DefaultInstance) {
            result.testB_ = global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Types.SubB.CreateBuilder(result.testB_).MergeFrom(value).BuildPartial();
        } else {
          result.testB_ = value;
        }
        result.hasTestB = true;
        return this;
      }
      public Builder ClearTestB() {
        result.hasTestB = false;
        result.testB_ = global::Google.ProtocolBuffers.TestProtos.TestMissingFieldsB.Types.SubB.DefaultInstance;
        return this;
      }
    }
    static TestMissingFieldsB() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestExtrasFullProtoFile.Descriptor, null);
    }
  }
  
  #endregion
  
}
