// Generated by ProtoGen, Version=2.4.1.555, Culture=neutral, PublicKeyToken=55f7125234beb589.  DO NOT EDIT!
#pragma warning disable 1591, 0612, 3021
#region Designer generated code

using pb = global::Google.ProtocolBuffers;
using pbc = global::Google.ProtocolBuffers.Collections;
using pbd = global::Google.ProtocolBuffers.Descriptors;
using scg = global::System.Collections.Generic;
namespace Google.ProtocolBuffers.TestProtos {
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public static partial class UnitTestOptimizeForProtoFile {
  
    #region Extension registration
    public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {
      registry.Add(global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.TestExtension);
      registry.Add(global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.TestExtension2);
    }
    #endregion
    #region Static variables
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestOptimizedForSize__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize, global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.Builder> internal__static_protobuf_unittest_TestOptimizedForSize__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestRequiredOptimizedForSize__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize, global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize.Builder> internal__static_protobuf_unittest_TestRequiredOptimizedForSize__FieldAccessorTable;
    internal static pbd::MessageDescriptor internal__static_protobuf_unittest_TestOptionalOptimizedForSize__Descriptor;
    internal static pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestOptionalOptimizedForSize, global::Google.ProtocolBuffers.TestProtos.TestOptionalOptimizedForSize.Builder> internal__static_protobuf_unittest_TestOptionalOptimizedForSize__FieldAccessorTable;
    #endregion
    #region Descriptor
    public static pbd::FileDescriptor Descriptor {
      get { return descriptor; }
    }
    private static pbd::FileDescriptor descriptor;
    
    static UnitTestOptimizeForProtoFile() {
      byte[] descriptorData = global::System.Convert.FromBase64String(
          string.Concat(
            "Citnb29nbGUvcHJvdG9idWYvdW5pdHRlc3Rfb3B0aW1pemVfZm9yLnByb3Rv", 
            "EhFwcm90b2J1Zl91bml0dGVzdBokZ29vZ2xlL3Byb3RvYnVmL2NzaGFycF9v", 
            "cHRpb25zLnByb3RvGh5nb29nbGUvcHJvdG9idWYvdW5pdHRlc3QucHJvdG8i", 
            "kgIKFFRlc3RPcHRpbWl6ZWRGb3JTaXplEgkKAWkYASABKAUSLgoDbXNnGBMg", 
            "ASgLMiEucHJvdG9idWZfdW5pdHRlc3QuRm9yZWlnbk1lc3NhZ2UqCQjoBxCA", 
            "gICAAjJACg50ZXN0X2V4dGVuc2lvbhInLnByb3RvYnVmX3VuaXR0ZXN0LlRl", 
            "c3RPcHRpbWl6ZWRGb3JTaXplGNIJIAEoBTJyCg90ZXN0X2V4dGVuc2lvbjIS", 
            "Jy5wcm90b2J1Zl91bml0dGVzdC5UZXN0T3B0aW1pemVkRm9yU2l6ZRjTCSAB", 
            "KAsyLy5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRG", 
            "b3JTaXplIikKHFRlc3RSZXF1aXJlZE9wdGltaXplZEZvclNpemUSCQoBeBgB", 
            "IAIoBSJaChxUZXN0T3B0aW9uYWxPcHRpbWl6ZWRGb3JTaXplEjoKAW8YASAB", 
            "KAsyLy5wcm90b2J1Zl91bml0dGVzdC5UZXN0UmVxdWlyZWRPcHRpbWl6ZWRG", 
            "b3JTaXplQkZIAsI+QQohR29vZ2xlLlByb3RvY29sQnVmZmVycy5UZXN0UHJv", 
          "dG9zEhxVbml0VGVzdE9wdGltaXplRm9yUHJvdG9GaWxl"));
      pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {
        descriptor = root;
        internal__static_protobuf_unittest_TestOptimizedForSize__Descriptor = Descriptor.MessageTypes[0];
        internal__static_protobuf_unittest_TestOptimizedForSize__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize, global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.Builder>(internal__static_protobuf_unittest_TestOptimizedForSize__Descriptor,
                new string[] { "I", "Msg", });
        global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.TestExtension = pb::GeneratedSingleExtension<int>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.Descriptor.Extensions[0]);
        global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.TestExtension2 = pb::GeneratedSingleExtension<global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize>.CreateInstance(global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.Descriptor.Extensions[1]);
        internal__static_protobuf_unittest_TestRequiredOptimizedForSize__Descriptor = Descriptor.MessageTypes[1];
        internal__static_protobuf_unittest_TestRequiredOptimizedForSize__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize, global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize.Builder>(internal__static_protobuf_unittest_TestRequiredOptimizedForSize__Descriptor,
                new string[] { "X", });
        internal__static_protobuf_unittest_TestOptionalOptimizedForSize__Descriptor = Descriptor.MessageTypes[2];
        internal__static_protobuf_unittest_TestOptionalOptimizedForSize__FieldAccessorTable = 
            new pb::FieldAccess.FieldAccessorTable<global::Google.ProtocolBuffers.TestProtos.TestOptionalOptimizedForSize, global::Google.ProtocolBuffers.TestProtos.TestOptionalOptimizedForSize.Builder>(internal__static_protobuf_unittest_TestOptionalOptimizedForSize__Descriptor,
                new string[] { "O", });
        pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();
        RegisterAllExtensions(registry);
        global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.RegisterAllExtensions(registry);
        global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.RegisterAllExtensions(registry);
        return registry;
      };
      pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,
          new pbd::FileDescriptor[] {
          global::Google.ProtocolBuffers.DescriptorProtos.CSharpOptions.Descriptor, 
          global::Google.ProtocolBuffers.TestProtos.UnitTestProtoFile.Descriptor, 
          }, assigner);
    }
    #endregion
    
  }
  #region Messages
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestOptimizedForSize : pb::ExtendableMessage<TestOptimizedForSize, TestOptimizedForSize.Builder> {
    private TestOptimizedForSize() { }
    private static readonly TestOptimizedForSize defaultInstance = new TestOptimizedForSize().MakeReadOnly();
    public static TestOptimizedForSize DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestOptimizedForSize DefaultInstanceForType {
      get { return DefaultInstance; }
    }
    
    protected override TestOptimizedForSize ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestOptimizeForProtoFile.internal__static_protobuf_unittest_TestOptimizedForSize__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestOptimizedForSize, TestOptimizedForSize.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestOptimizeForProtoFile.internal__static_protobuf_unittest_TestOptimizedForSize__FieldAccessorTable; }
    }
    
    public const int TestExtensionFieldNumber = 1234;
    public static pb::GeneratedExtensionBase<int> TestExtension;
    public const int TestExtension2FieldNumber = 1235;
    public static pb::GeneratedExtensionBase<global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize> TestExtension2;
    public const int IFieldNumber = 1;
    private bool hasI;
    private int i_;
    public bool HasI {
      get { return hasI; }
    }
    public int I {
      get { return i_; }
    }
    
    public const int MsgFieldNumber = 19;
    private bool hasMsg;
    private global::Google.ProtocolBuffers.TestProtos.ForeignMessage msg_;
    public bool HasMsg {
      get { return hasMsg; }
    }
    public global::Google.ProtocolBuffers.TestProtos.ForeignMessage Msg {
      get { return msg_ ?? global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance; }
    }
    
    public static TestOptimizedForSize ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestOptimizedForSize ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestOptimizedForSize ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestOptimizedForSize ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestOptimizedForSize ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestOptimizedForSize ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestOptimizedForSize ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestOptimizedForSize ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestOptimizedForSize ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestOptimizedForSize ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestOptimizedForSize 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(TestOptimizedForSize prototype) {
      return new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::ExtendableBuilder<TestOptimizedForSize, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestOptimizedForSize cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestOptimizedForSize result;
      
      private TestOptimizedForSize PrepareBuilder() {
        if (resultIsReadOnly) {
          TestOptimizedForSize original = result;
          result = new TestOptimizedForSize();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestOptimizedForSize 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.TestOptimizedForSize.Descriptor; }
      }
      
      public override TestOptimizedForSize DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.DefaultInstance; }
      }
      
      public override TestOptimizedForSize BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      
      public bool HasI {
        get { return result.hasI; }
      }
      public int I {
        get { return result.I; }
        set { SetI(value); }
      }
      public Builder SetI(int value) {
        PrepareBuilder();
        result.hasI = true;
        result.i_ = value;
        return this;
      }
      public Builder ClearI() {
        PrepareBuilder();
        result.hasI = false;
        result.i_ = 0;
        return this;
      }
      
      public bool HasMsg {
       get { return result.hasMsg; }
      }
      public global::Google.ProtocolBuffers.TestProtos.ForeignMessage Msg {
        get { return result.Msg; }
        set { SetMsg(value); }
      }
      public Builder SetMsg(global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasMsg = true;
        result.msg_ = value;
        return this;
      }
      public Builder SetMsg(global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasMsg = true;
        result.msg_ = builderForValue.Build();
        return this;
      }
      public Builder MergeMsg(global::Google.ProtocolBuffers.TestProtos.ForeignMessage value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        if (result.hasMsg &&
            result.msg_ != global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance) {
            result.msg_ = global::Google.ProtocolBuffers.TestProtos.ForeignMessage.CreateBuilder(result.msg_).MergeFrom(value).BuildPartial();
        } else {
          result.msg_ = value;
        }
        result.hasMsg = true;
        return this;
      }
      public Builder ClearMsg() {
        PrepareBuilder();
        result.hasMsg = false;
        result.msg_ = null;
        return this;
      }
    }
    static TestOptimizedForSize() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestOptimizeForProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestRequiredOptimizedForSize : pb::GeneratedMessage<TestRequiredOptimizedForSize, TestRequiredOptimizedForSize.Builder> {
    private TestRequiredOptimizedForSize() { }
    private static readonly TestRequiredOptimizedForSize defaultInstance = new TestRequiredOptimizedForSize().MakeReadOnly();
    public static TestRequiredOptimizedForSize DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestRequiredOptimizedForSize DefaultInstanceForType {
      get { return DefaultInstance; }
    }
    
    protected override TestRequiredOptimizedForSize ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestOptimizeForProtoFile.internal__static_protobuf_unittest_TestRequiredOptimizedForSize__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestRequiredOptimizedForSize, TestRequiredOptimizedForSize.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestOptimizeForProtoFile.internal__static_protobuf_unittest_TestRequiredOptimizedForSize__FieldAccessorTable; }
    }
    
    public const int XFieldNumber = 1;
    private bool hasX;
    private int x_;
    public bool HasX {
      get { return hasX; }
    }
    public int X {
      get { return x_; }
    }
    
    public static TestRequiredOptimizedForSize ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestRequiredOptimizedForSize ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestRequiredOptimizedForSize ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestRequiredOptimizedForSize ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestRequiredOptimizedForSize ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestRequiredOptimizedForSize ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestRequiredOptimizedForSize ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestRequiredOptimizedForSize ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestRequiredOptimizedForSize ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestRequiredOptimizedForSize ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestRequiredOptimizedForSize 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(TestRequiredOptimizedForSize prototype) {
      return new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestRequiredOptimizedForSize, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestRequiredOptimizedForSize cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestRequiredOptimizedForSize result;
      
      private TestRequiredOptimizedForSize PrepareBuilder() {
        if (resultIsReadOnly) {
          TestRequiredOptimizedForSize original = result;
          result = new TestRequiredOptimizedForSize();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestRequiredOptimizedForSize 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.TestRequiredOptimizedForSize.Descriptor; }
      }
      
      public override TestRequiredOptimizedForSize DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize.DefaultInstance; }
      }
      
      public override TestRequiredOptimizedForSize BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      
      public bool HasX {
        get { return result.hasX; }
      }
      public int X {
        get { return result.X; }
        set { SetX(value); }
      }
      public Builder SetX(int value) {
        PrepareBuilder();
        result.hasX = true;
        result.x_ = value;
        return this;
      }
      public Builder ClearX() {
        PrepareBuilder();
        result.hasX = false;
        result.x_ = 0;
        return this;
      }
    }
    static TestRequiredOptimizedForSize() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestOptimizeForProtoFile.Descriptor, null);
    }
  }
  
  [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
  public sealed partial class TestOptionalOptimizedForSize : pb::GeneratedMessage<TestOptionalOptimizedForSize, TestOptionalOptimizedForSize.Builder> {
    private TestOptionalOptimizedForSize() { }
    private static readonly TestOptionalOptimizedForSize defaultInstance = new TestOptionalOptimizedForSize().MakeReadOnly();
    public static TestOptionalOptimizedForSize DefaultInstance {
      get { return defaultInstance; }
    }
    
    public override TestOptionalOptimizedForSize DefaultInstanceForType {
      get { return DefaultInstance; }
    }
    
    protected override TestOptionalOptimizedForSize ThisMessage {
      get { return this; }
    }
    
    public static pbd::MessageDescriptor Descriptor {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestOptimizeForProtoFile.internal__static_protobuf_unittest_TestOptionalOptimizedForSize__Descriptor; }
    }
    
    protected override pb::FieldAccess.FieldAccessorTable<TestOptionalOptimizedForSize, TestOptionalOptimizedForSize.Builder> InternalFieldAccessors {
      get { return global::Google.ProtocolBuffers.TestProtos.UnitTestOptimizeForProtoFile.internal__static_protobuf_unittest_TestOptionalOptimizedForSize__FieldAccessorTable; }
    }
    
    public const int OFieldNumber = 1;
    private bool hasO;
    private global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize o_;
    public bool HasO {
      get { return hasO; }
    }
    public global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize O {
      get { return o_ ?? global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize.DefaultInstance; }
    }
    
    public static TestOptionalOptimizedForSize ParseFrom(pb::ByteString data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestOptionalOptimizedForSize ParseFrom(pb::ByteString data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestOptionalOptimizedForSize ParseFrom(byte[] data) {
      return ((Builder) CreateBuilder().MergeFrom(data)).BuildParsed();
    }
    public static TestOptionalOptimizedForSize ParseFrom(byte[] data, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(data, extensionRegistry)).BuildParsed();
    }
    public static TestOptionalOptimizedForSize ParseFrom(global::System.IO.Stream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestOptionalOptimizedForSize ParseFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    public static TestOptionalOptimizedForSize ParseDelimitedFrom(global::System.IO.Stream input) {
      return CreateBuilder().MergeDelimitedFrom(input).BuildParsed();
    }
    public static TestOptionalOptimizedForSize ParseDelimitedFrom(global::System.IO.Stream input, pb::ExtensionRegistry extensionRegistry) {
      return CreateBuilder().MergeDelimitedFrom(input, extensionRegistry).BuildParsed();
    }
    public static TestOptionalOptimizedForSize ParseFrom(pb::ICodedInputStream input) {
      return ((Builder) CreateBuilder().MergeFrom(input)).BuildParsed();
    }
    public static TestOptionalOptimizedForSize ParseFrom(pb::ICodedInputStream input, pb::ExtensionRegistry extensionRegistry) {
      return ((Builder) CreateBuilder().MergeFrom(input, extensionRegistry)).BuildParsed();
    }
    private TestOptionalOptimizedForSize 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(TestOptionalOptimizedForSize prototype) {
      return new Builder(prototype);
    }
    
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
    public sealed partial class Builder : pb::GeneratedBuilder<TestOptionalOptimizedForSize, Builder> {
      protected override Builder ThisBuilder {
        get { return this; }
      }
      public Builder() {
        result = DefaultInstance;
        resultIsReadOnly = true;
      }
      internal Builder(TestOptionalOptimizedForSize cloneFrom) {
        result = cloneFrom;
        resultIsReadOnly = true;
      }
      
      private bool resultIsReadOnly;
      private TestOptionalOptimizedForSize result;
      
      private TestOptionalOptimizedForSize PrepareBuilder() {
        if (resultIsReadOnly) {
          TestOptionalOptimizedForSize original = result;
          result = new TestOptionalOptimizedForSize();
          resultIsReadOnly = false;
          MergeFrom(original);
        }
        return result;
      }
      
      public override bool IsInitialized {
        get { return result.IsInitialized; }
      }
      
      protected override TestOptionalOptimizedForSize 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.TestOptionalOptimizedForSize.Descriptor; }
      }
      
      public override TestOptionalOptimizedForSize DefaultInstanceForType {
        get { return global::Google.ProtocolBuffers.TestProtos.TestOptionalOptimizedForSize.DefaultInstance; }
      }
      
      public override TestOptionalOptimizedForSize BuildPartial() {
        if (resultIsReadOnly) {
          return result;
        }
        resultIsReadOnly = true;
        return result.MakeReadOnly();
      }
      
      
      public bool HasO {
       get { return result.hasO; }
      }
      public global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize O {
        get { return result.O; }
        set { SetO(value); }
      }
      public Builder SetO(global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        result.hasO = true;
        result.o_ = value;
        return this;
      }
      public Builder SetO(global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize.Builder builderForValue) {
        pb::ThrowHelper.ThrowIfNull(builderForValue, "builderForValue");
        PrepareBuilder();
        result.hasO = true;
        result.o_ = builderForValue.Build();
        return this;
      }
      public Builder MergeO(global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize value) {
        pb::ThrowHelper.ThrowIfNull(value, "value");
        PrepareBuilder();
        if (result.hasO &&
            result.o_ != global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize.DefaultInstance) {
            result.o_ = global::Google.ProtocolBuffers.TestProtos.TestRequiredOptimizedForSize.CreateBuilder(result.o_).MergeFrom(value).BuildPartial();
        } else {
          result.o_ = value;
        }
        result.hasO = true;
        return this;
      }
      public Builder ClearO() {
        PrepareBuilder();
        result.hasO = false;
        result.o_ = null;
        return this;
      }
    }
    static TestOptionalOptimizedForSize() {
      object.ReferenceEquals(global::Google.ProtocolBuffers.TestProtos.UnitTestOptimizeForProtoFile.Descriptor, null);
    }
  }
  
  #endregion
  
}

#endregion Designer generated code
