Regenerate C# code with the new generator, adding unittest_proto3_optional.proto

The changes in the existing proto2 code are solely around presence bits. The new generator allocated presence bits more efficiently. (Previously bits were sometimes allocated but never used.)
diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto2.cs b/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto2.cs
index 350fb7c..1ba1275 100644
--- a/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto2.cs
+++ b/csharp/src/Google.Protobuf.Test.TestProtos/TestMessagesProto2.cs
@@ -1872,21 +1872,21 @@
     /// </summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int Fieldname1 {
-      get { if ((_hasBits0 & 2097152) != 0) { return fieldname1_; } else { return Fieldname1DefaultValue; } }
+      get { if ((_hasBits0 & 32768) != 0) { return fieldname1_; } else { return Fieldname1DefaultValue; } }
       set {
-        _hasBits0 |= 2097152;
+        _hasBits0 |= 32768;
         fieldname1_ = value;
       }
     }
     /// <summary>Gets whether the "fieldname1" field is set</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool HasFieldname1 {
-      get { return (_hasBits0 & 2097152) != 0; }
+      get { return (_hasBits0 & 32768) != 0; }
     }
     /// <summary>Clears the value of the "fieldname1" field</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearFieldname1() {
-      _hasBits0 &= ~2097152;
+      _hasBits0 &= ~32768;
     }
 
     /// <summary>Field number for the "field_name2" field.</summary>
@@ -1896,21 +1896,21 @@
     private int fieldName2_;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int FieldName2 {
-      get { if ((_hasBits0 & 4194304) != 0) { return fieldName2_; } else { return FieldName2DefaultValue; } }
+      get { if ((_hasBits0 & 65536) != 0) { return fieldName2_; } else { return FieldName2DefaultValue; } }
       set {
-        _hasBits0 |= 4194304;
+        _hasBits0 |= 65536;
         fieldName2_ = value;
       }
     }
     /// <summary>Gets whether the "field_name2" field is set</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool HasFieldName2 {
-      get { return (_hasBits0 & 4194304) != 0; }
+      get { return (_hasBits0 & 65536) != 0; }
     }
     /// <summary>Clears the value of the "field_name2" field</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearFieldName2() {
-      _hasBits0 &= ~4194304;
+      _hasBits0 &= ~65536;
     }
 
     /// <summary>Field number for the "_field_name3" field.</summary>
@@ -1920,21 +1920,21 @@
     private int FieldName3_;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int FieldName3 {
-      get { if ((_hasBits0 & 8388608) != 0) { return FieldName3_; } else { return FieldName3DefaultValue; } }
+      get { if ((_hasBits0 & 131072) != 0) { return FieldName3_; } else { return FieldName3DefaultValue; } }
       set {
-        _hasBits0 |= 8388608;
+        _hasBits0 |= 131072;
         FieldName3_ = value;
       }
     }
     /// <summary>Gets whether the "_field_name3" field is set</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool HasFieldName3 {
-      get { return (_hasBits0 & 8388608) != 0; }
+      get { return (_hasBits0 & 131072) != 0; }
     }
     /// <summary>Clears the value of the "_field_name3" field</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearFieldName3() {
-      _hasBits0 &= ~8388608;
+      _hasBits0 &= ~131072;
     }
 
     /// <summary>Field number for the "field__name4_" field.</summary>
@@ -1944,21 +1944,21 @@
     private int fieldName4_;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int FieldName4 {
-      get { if ((_hasBits0 & 16777216) != 0) { return fieldName4_; } else { return FieldName4DefaultValue; } }
+      get { if ((_hasBits0 & 262144) != 0) { return fieldName4_; } else { return FieldName4DefaultValue; } }
       set {
-        _hasBits0 |= 16777216;
+        _hasBits0 |= 262144;
         fieldName4_ = value;
       }
     }
     /// <summary>Gets whether the "field__name4_" field is set</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool HasFieldName4 {
-      get { return (_hasBits0 & 16777216) != 0; }
+      get { return (_hasBits0 & 262144) != 0; }
     }
     /// <summary>Clears the value of the "field__name4_" field</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearFieldName4() {
-      _hasBits0 &= ~16777216;
+      _hasBits0 &= ~262144;
     }
 
     /// <summary>Field number for the "field0name5" field.</summary>
@@ -1968,21 +1968,21 @@
     private int field0Name5_;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int Field0Name5 {
-      get { if ((_hasBits0 & 33554432) != 0) { return field0Name5_; } else { return Field0Name5DefaultValue; } }
+      get { if ((_hasBits0 & 524288) != 0) { return field0Name5_; } else { return Field0Name5DefaultValue; } }
       set {
-        _hasBits0 |= 33554432;
+        _hasBits0 |= 524288;
         field0Name5_ = value;
       }
     }
     /// <summary>Gets whether the "field0name5" field is set</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool HasField0Name5 {
-      get { return (_hasBits0 & 33554432) != 0; }
+      get { return (_hasBits0 & 524288) != 0; }
     }
     /// <summary>Clears the value of the "field0name5" field</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearField0Name5() {
-      _hasBits0 &= ~33554432;
+      _hasBits0 &= ~524288;
     }
 
     /// <summary>Field number for the "field_0_name6" field.</summary>
@@ -1992,21 +1992,21 @@
     private int field0Name6_;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int Field0Name6 {
-      get { if ((_hasBits0 & 67108864) != 0) { return field0Name6_; } else { return Field0Name6DefaultValue; } }
+      get { if ((_hasBits0 & 1048576) != 0) { return field0Name6_; } else { return Field0Name6DefaultValue; } }
       set {
-        _hasBits0 |= 67108864;
+        _hasBits0 |= 1048576;
         field0Name6_ = value;
       }
     }
     /// <summary>Gets whether the "field_0_name6" field is set</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool HasField0Name6 {
-      get { return (_hasBits0 & 67108864) != 0; }
+      get { return (_hasBits0 & 1048576) != 0; }
     }
     /// <summary>Clears the value of the "field_0_name6" field</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearField0Name6() {
-      _hasBits0 &= ~67108864;
+      _hasBits0 &= ~1048576;
     }
 
     /// <summary>Field number for the "fieldName7" field.</summary>
@@ -2016,21 +2016,21 @@
     private int fieldName7_;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int FieldName7 {
-      get { if ((_hasBits0 & 134217728) != 0) { return fieldName7_; } else { return FieldName7DefaultValue; } }
+      get { if ((_hasBits0 & 2097152) != 0) { return fieldName7_; } else { return FieldName7DefaultValue; } }
       set {
-        _hasBits0 |= 134217728;
+        _hasBits0 |= 2097152;
         fieldName7_ = value;
       }
     }
     /// <summary>Gets whether the "fieldName7" field is set</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool HasFieldName7 {
-      get { return (_hasBits0 & 134217728) != 0; }
+      get { return (_hasBits0 & 2097152) != 0; }
     }
     /// <summary>Clears the value of the "fieldName7" field</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearFieldName7() {
-      _hasBits0 &= ~134217728;
+      _hasBits0 &= ~2097152;
     }
 
     /// <summary>Field number for the "FieldName8" field.</summary>
@@ -2040,21 +2040,21 @@
     private int fieldName8_;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int FieldName8 {
-      get { if ((_hasBits0 & 268435456) != 0) { return fieldName8_; } else { return FieldName8DefaultValue; } }
+      get { if ((_hasBits0 & 4194304) != 0) { return fieldName8_; } else { return FieldName8DefaultValue; } }
       set {
-        _hasBits0 |= 268435456;
+        _hasBits0 |= 4194304;
         fieldName8_ = value;
       }
     }
     /// <summary>Gets whether the "FieldName8" field is set</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool HasFieldName8 {
-      get { return (_hasBits0 & 268435456) != 0; }
+      get { return (_hasBits0 & 4194304) != 0; }
     }
     /// <summary>Clears the value of the "FieldName8" field</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearFieldName8() {
-      _hasBits0 &= ~268435456;
+      _hasBits0 &= ~4194304;
     }
 
     /// <summary>Field number for the "field_Name9" field.</summary>
@@ -2064,21 +2064,21 @@
     private int fieldName9_;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int FieldName9 {
-      get { if ((_hasBits0 & 536870912) != 0) { return fieldName9_; } else { return FieldName9DefaultValue; } }
+      get { if ((_hasBits0 & 8388608) != 0) { return fieldName9_; } else { return FieldName9DefaultValue; } }
       set {
-        _hasBits0 |= 536870912;
+        _hasBits0 |= 8388608;
         fieldName9_ = value;
       }
     }
     /// <summary>Gets whether the "field_Name9" field is set</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool HasFieldName9 {
-      get { return (_hasBits0 & 536870912) != 0; }
+      get { return (_hasBits0 & 8388608) != 0; }
     }
     /// <summary>Clears the value of the "field_Name9" field</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearFieldName9() {
-      _hasBits0 &= ~536870912;
+      _hasBits0 &= ~8388608;
     }
 
     /// <summary>Field number for the "Field_Name10" field.</summary>
@@ -2088,21 +2088,21 @@
     private int fieldName10_;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int FieldName10 {
-      get { if ((_hasBits0 & 1073741824) != 0) { return fieldName10_; } else { return FieldName10DefaultValue; } }
+      get { if ((_hasBits0 & 16777216) != 0) { return fieldName10_; } else { return FieldName10DefaultValue; } }
       set {
-        _hasBits0 |= 1073741824;
+        _hasBits0 |= 16777216;
         fieldName10_ = value;
       }
     }
     /// <summary>Gets whether the "Field_Name10" field is set</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool HasFieldName10 {
-      get { return (_hasBits0 & 1073741824) != 0; }
+      get { return (_hasBits0 & 16777216) != 0; }
     }
     /// <summary>Clears the value of the "Field_Name10" field</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearFieldName10() {
-      _hasBits0 &= ~1073741824;
+      _hasBits0 &= ~16777216;
     }
 
     /// <summary>Field number for the "FIELD_NAME11" field.</summary>
@@ -2112,21 +2112,21 @@
     private int fIELDNAME11_;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int FIELDNAME11 {
-      get { if ((_hasBits0 & -2147483648) != 0) { return fIELDNAME11_; } else { return FIELDNAME11DefaultValue; } }
+      get { if ((_hasBits0 & 33554432) != 0) { return fIELDNAME11_; } else { return FIELDNAME11DefaultValue; } }
       set {
-        _hasBits0 |= -2147483648;
+        _hasBits0 |= 33554432;
         fIELDNAME11_ = value;
       }
     }
     /// <summary>Gets whether the "FIELD_NAME11" field is set</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool HasFIELDNAME11 {
-      get { return (_hasBits0 & -2147483648) != 0; }
+      get { return (_hasBits0 & 33554432) != 0; }
     }
     /// <summary>Clears the value of the "FIELD_NAME11" field</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearFIELDNAME11() {
-      _hasBits0 &= ~-2147483648;
+      _hasBits0 &= ~33554432;
     }
 
     /// <summary>Field number for the "FIELD_name12" field.</summary>
@@ -2136,21 +2136,21 @@
     private int fIELDName12_;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int FIELDName12 {
-      get { if ((_hasBits1 & 1) != 0) { return fIELDName12_; } else { return FIELDName12DefaultValue; } }
+      get { if ((_hasBits0 & 67108864) != 0) { return fIELDName12_; } else { return FIELDName12DefaultValue; } }
       set {
-        _hasBits1 |= 1;
+        _hasBits0 |= 67108864;
         fIELDName12_ = value;
       }
     }
     /// <summary>Gets whether the "FIELD_name12" field is set</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool HasFIELDName12 {
-      get { return (_hasBits1 & 1) != 0; }
+      get { return (_hasBits0 & 67108864) != 0; }
     }
     /// <summary>Clears the value of the "FIELD_name12" field</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearFIELDName12() {
-      _hasBits1 &= ~1;
+      _hasBits0 &= ~67108864;
     }
 
     /// <summary>Field number for the "__field_name13" field.</summary>
@@ -2160,21 +2160,21 @@
     private int FieldName13_;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int FieldName13 {
-      get { if ((_hasBits1 & 2) != 0) { return FieldName13_; } else { return FieldName13DefaultValue; } }
+      get { if ((_hasBits0 & 134217728) != 0) { return FieldName13_; } else { return FieldName13DefaultValue; } }
       set {
-        _hasBits1 |= 2;
+        _hasBits0 |= 134217728;
         FieldName13_ = value;
       }
     }
     /// <summary>Gets whether the "__field_name13" field is set</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool HasFieldName13 {
-      get { return (_hasBits1 & 2) != 0; }
+      get { return (_hasBits0 & 134217728) != 0; }
     }
     /// <summary>Clears the value of the "__field_name13" field</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearFieldName13() {
-      _hasBits1 &= ~2;
+      _hasBits0 &= ~134217728;
     }
 
     /// <summary>Field number for the "__Field_name14" field.</summary>
@@ -2184,21 +2184,21 @@
     private int FieldName14_;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int FieldName14 {
-      get { if ((_hasBits1 & 4) != 0) { return FieldName14_; } else { return FieldName14DefaultValue; } }
+      get { if ((_hasBits0 & 268435456) != 0) { return FieldName14_; } else { return FieldName14DefaultValue; } }
       set {
-        _hasBits1 |= 4;
+        _hasBits0 |= 268435456;
         FieldName14_ = value;
       }
     }
     /// <summary>Gets whether the "__Field_name14" field is set</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool HasFieldName14 {
-      get { return (_hasBits1 & 4) != 0; }
+      get { return (_hasBits0 & 268435456) != 0; }
     }
     /// <summary>Clears the value of the "__Field_name14" field</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearFieldName14() {
-      _hasBits1 &= ~4;
+      _hasBits0 &= ~268435456;
     }
 
     /// <summary>Field number for the "field__name15" field.</summary>
@@ -2208,21 +2208,21 @@
     private int fieldName15_;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int FieldName15 {
-      get { if ((_hasBits1 & 8) != 0) { return fieldName15_; } else { return FieldName15DefaultValue; } }
+      get { if ((_hasBits0 & 536870912) != 0) { return fieldName15_; } else { return FieldName15DefaultValue; } }
       set {
-        _hasBits1 |= 8;
+        _hasBits0 |= 536870912;
         fieldName15_ = value;
       }
     }
     /// <summary>Gets whether the "field__name15" field is set</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool HasFieldName15 {
-      get { return (_hasBits1 & 8) != 0; }
+      get { return (_hasBits0 & 536870912) != 0; }
     }
     /// <summary>Clears the value of the "field__name15" field</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearFieldName15() {
-      _hasBits1 &= ~8;
+      _hasBits0 &= ~536870912;
     }
 
     /// <summary>Field number for the "field__Name16" field.</summary>
@@ -2232,21 +2232,21 @@
     private int fieldName16_;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int FieldName16 {
-      get { if ((_hasBits1 & 16) != 0) { return fieldName16_; } else { return FieldName16DefaultValue; } }
+      get { if ((_hasBits0 & 1073741824) != 0) { return fieldName16_; } else { return FieldName16DefaultValue; } }
       set {
-        _hasBits1 |= 16;
+        _hasBits0 |= 1073741824;
         fieldName16_ = value;
       }
     }
     /// <summary>Gets whether the "field__Name16" field is set</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool HasFieldName16 {
-      get { return (_hasBits1 & 16) != 0; }
+      get { return (_hasBits0 & 1073741824) != 0; }
     }
     /// <summary>Clears the value of the "field__Name16" field</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearFieldName16() {
-      _hasBits1 &= ~16;
+      _hasBits0 &= ~1073741824;
     }
 
     /// <summary>Field number for the "field_name17__" field.</summary>
@@ -2256,21 +2256,21 @@
     private int fieldName17_;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int FieldName17 {
-      get { if ((_hasBits1 & 32) != 0) { return fieldName17_; } else { return FieldName17DefaultValue; } }
+      get { if ((_hasBits0 & -2147483648) != 0) { return fieldName17_; } else { return FieldName17DefaultValue; } }
       set {
-        _hasBits1 |= 32;
+        _hasBits0 |= -2147483648;
         fieldName17_ = value;
       }
     }
     /// <summary>Gets whether the "field_name17__" field is set</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool HasFieldName17 {
-      get { return (_hasBits1 & 32) != 0; }
+      get { return (_hasBits0 & -2147483648) != 0; }
     }
     /// <summary>Clears the value of the "field_name17__" field</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearFieldName17() {
-      _hasBits1 &= ~32;
+      _hasBits0 &= ~-2147483648;
     }
 
     /// <summary>Field number for the "Field_name18__" field.</summary>
@@ -2280,21 +2280,21 @@
     private int fieldName18_;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int FieldName18 {
-      get { if ((_hasBits1 & 64) != 0) { return fieldName18_; } else { return FieldName18DefaultValue; } }
+      get { if ((_hasBits1 & 1) != 0) { return fieldName18_; } else { return FieldName18DefaultValue; } }
       set {
-        _hasBits1 |= 64;
+        _hasBits1 |= 1;
         fieldName18_ = value;
       }
     }
     /// <summary>Gets whether the "Field_name18__" field is set</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool HasFieldName18 {
-      get { return (_hasBits1 & 64) != 0; }
+      get { return (_hasBits1 & 1) != 0; }
     }
     /// <summary>Clears the value of the "Field_name18__" field</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearFieldName18() {
-      _hasBits1 &= ~64;
+      _hasBits1 &= ~1;
     }
 
     private object oneofField_;
diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/Unittest.cs b/csharp/src/Google.Protobuf.Test.TestProtos/Unittest.cs
index a35b6e0..25fecb9 100644
--- a/csharp/src/Google.Protobuf.Test.TestProtos/Unittest.cs
+++ b/csharp/src/Google.Protobuf.Test.TestProtos/Unittest.cs
@@ -15521,7 +15521,6 @@
   public sealed partial class TestOneof : pb::IMessage<TestOneof> {
     private static readonly pb::MessageParser<TestOneof> _parser = new pb::MessageParser<TestOneof>(() => new TestOneof());
     private pb::UnknownFieldSet _unknownFields;
-    private int _hasBits0;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<TestOneof> Parser { get { return _parser; } }
 
@@ -15544,7 +15543,6 @@
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public TestOneof(TestOneof other) : this() {
-      _hasBits0 = other._hasBits0;
       switch (other.FooCase) {
         case FooOneofCase.FooInt:
           FooInt = other.FooInt;
@@ -16934,21 +16932,21 @@
     private int bazInt_;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public int BazInt {
-      get { if ((_hasBits0 & 16) != 0) { return bazInt_; } else { return BazIntDefaultValue; } }
+      get { if ((_hasBits0 & 1) != 0) { return bazInt_; } else { return BazIntDefaultValue; } }
       set {
-        _hasBits0 |= 16;
+        _hasBits0 |= 1;
         bazInt_ = value;
       }
     }
     /// <summary>Gets whether the "baz_int" field is set</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public bool HasBazInt {
-      get { return (_hasBits0 & 16) != 0; }
+      get { return (_hasBits0 & 1) != 0; }
     }
     /// <summary>Clears the value of the "baz_int" field</summary>
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public void ClearBazInt() {
-      _hasBits0 &= ~16;
+      _hasBits0 &= ~1;
     }
 
     /// <summary>Field number for the "baz_string" field.</summary>
@@ -17767,7 +17765,6 @@
   public sealed partial class TestRequiredOneof : pb::IMessage<TestRequiredOneof> {
     private static readonly pb::MessageParser<TestRequiredOneof> _parser = new pb::MessageParser<TestRequiredOneof>(() => new TestRequiredOneof());
     private pb::UnknownFieldSet _unknownFields;
-    private int _hasBits0;
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public static pb::MessageParser<TestRequiredOneof> Parser { get { return _parser; } }
 
@@ -17790,7 +17787,6 @@
 
     [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
     public TestRequiredOneof(TestRequiredOneof other) : this() {
-      _hasBits0 = other._hasBits0;
       switch (other.FooCase) {
         case FooOneofCase.FooInt:
           FooInt = other.FooInt;
diff --git a/csharp/src/Google.Protobuf.Test.TestProtos/UnittestProto3Optional.cs b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestProto3Optional.cs
new file mode 100644
index 0000000..cbad589
--- /dev/null
+++ b/csharp/src/Google.Protobuf.Test.TestProtos/UnittestProto3Optional.cs
@@ -0,0 +1,1072 @@
+// <auto-generated>
+//     Generated by the protocol buffer compiler.  DO NOT EDIT!
+//     source: google/protobuf/unittest_proto3_optional.proto
+// </auto-generated>
+#pragma warning disable 1591, 0612, 3021
+#region Designer generated code
+
+using pb = global::Google.Protobuf;
+using pbc = global::Google.Protobuf.Collections;
+using pbr = global::Google.Protobuf.Reflection;
+using scg = global::System.Collections.Generic;
+namespace ProtobufUnittest {
+
+  /// <summary>Holder for reflection information generated from google/protobuf/unittest_proto3_optional.proto</summary>
+  public static partial class UnittestProto3OptionalReflection {
+
+    #region Descriptor
+    /// <summary>File descriptor for google/protobuf/unittest_proto3_optional.proto</summary>
+    public static pbr::FileDescriptor Descriptor {
+      get { return descriptor; }
+    }
+    private static pbr::FileDescriptor descriptor;
+
+    static UnittestProto3OptionalReflection() {
+      byte[] descriptorData = global::System.Convert.FromBase64String(
+          string.Concat(
+            "Ci5nb29nbGUvcHJvdG9idWYvdW5pdHRlc3RfcHJvdG8zX29wdGlvbmFsLnBy",
+            "b3RvEhFwcm90b2J1Zl91bml0dGVzdCKBCgoSVGVzdFByb3RvM09wdGlvbmFs",
+            "EhsKDm9wdGlvbmFsX2ludDMyGAEgASgFSACIAQESGwoOb3B0aW9uYWxfaW50",
+            "NjQYAiABKANIAYgBARIcCg9vcHRpb25hbF91aW50MzIYAyABKA1IAogBARIc",
+            "Cg9vcHRpb25hbF91aW50NjQYBCABKARIA4gBARIcCg9vcHRpb25hbF9zaW50",
+            "MzIYBSABKBFIBIgBARIcCg9vcHRpb25hbF9zaW50NjQYBiABKBJIBYgBARId",
+            "ChBvcHRpb25hbF9maXhlZDMyGAcgASgHSAaIAQESHQoQb3B0aW9uYWxfZml4",
+            "ZWQ2NBgIIAEoBkgHiAEBEh4KEW9wdGlvbmFsX3NmaXhlZDMyGAkgASgPSAiI",
+            "AQESHgoRb3B0aW9uYWxfc2ZpeGVkNjQYCiABKBBICYgBARIbCg5vcHRpb25h",
+            "bF9mbG9hdBgLIAEoAkgKiAEBEhwKD29wdGlvbmFsX2RvdWJsZRgMIAEoAUgL",
+            "iAEBEhoKDW9wdGlvbmFsX2Jvb2wYDSABKAhIDIgBARIcCg9vcHRpb25hbF9z",
+            "dHJpbmcYDiABKAlIDYgBARIbCg5vcHRpb25hbF9ieXRlcxgPIAEoDEgOiAEB",
+            "Eh4KDW9wdGlvbmFsX2NvcmQYECABKAlCAggBSA+IAQESWQoXb3B0aW9uYWxf",
+            "bmVzdGVkX21lc3NhZ2UYEiABKAsyMy5wcm90b2J1Zl91bml0dGVzdC5UZXN0",
+            "UHJvdG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZUgQiAEBElkKE2xhenlfbmVz",
+            "dGVkX21lc3NhZ2UYEyABKAsyMy5wcm90b2J1Zl91bml0dGVzdC5UZXN0UHJv",
+            "dG8zT3B0aW9uYWwuTmVzdGVkTWVzc2FnZUICKAFIEYgBARJTChRvcHRpb25h",
+            "bF9uZXN0ZWRfZW51bRgVIAEoDjIwLnByb3RvYnVmX3VuaXR0ZXN0LlRlc3RQ",
+            "cm90bzNPcHRpb25hbC5OZXN0ZWRFbnVtSBKIAQEaJwoNTmVzdGVkTWVzc2Fn",
+            "ZRIPCgJiYhgBIAEoBUgAiAEBQgUKA19iYiJKCgpOZXN0ZWRFbnVtEg8KC1VO",
+            "U1BFQ0lGSUVEEAASBwoDRk9PEAESBwoDQkFSEAISBwoDQkFaEAMSEAoDTkVH",
+            "EP///////////wFCEQoPX29wdGlvbmFsX2ludDMyQhEKD19vcHRpb25hbF9p",
+            "bnQ2NEISChBfb3B0aW9uYWxfdWludDMyQhIKEF9vcHRpb25hbF91aW50NjRC",
+            "EgoQX29wdGlvbmFsX3NpbnQzMkISChBfb3B0aW9uYWxfc2ludDY0QhMKEV9v",
+            "cHRpb25hbF9maXhlZDMyQhMKEV9vcHRpb25hbF9maXhlZDY0QhQKEl9vcHRp",
+            "b25hbF9zZml4ZWQzMkIUChJfb3B0aW9uYWxfc2ZpeGVkNjRCEQoPX29wdGlv",
+            "bmFsX2Zsb2F0QhIKEF9vcHRpb25hbF9kb3VibGVCEAoOX29wdGlvbmFsX2Jv",
+            "b2xCEgoQX29wdGlvbmFsX3N0cmluZ0IRCg9fb3B0aW9uYWxfYnl0ZXNCEAoO",
+            "X29wdGlvbmFsX2NvcmRCGgoYX29wdGlvbmFsX25lc3RlZF9tZXNzYWdlQhYK",
+            "FF9sYXp5X25lc3RlZF9tZXNzYWdlQhcKFV9vcHRpb25hbF9uZXN0ZWRfZW51",
+            "bUIlCiFjb20uZ29vZ2xlLnByb3RvYnVmLnRlc3RpbmcucHJvdG9QAWIGcHJv",
+            "dG8z"));
+      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
+          new pbr::FileDescriptor[] { },
+          new pbr::GeneratedClrTypeInfo(null, null, new pbr::GeneratedClrTypeInfo[] {
+            new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3Optional), global::ProtobufUnittest.TestProto3Optional.Parser, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalCord", "OptionalNestedMessage", "LazyNestedMessage", "OptionalNestedEnum" }, new[]{ "OptionalInt32", "OptionalInt64", "OptionalUint32", "OptionalUint64", "OptionalSint32", "OptionalSint64", "OptionalFixed32", "OptionalFixed64", "OptionalSfixed32", "OptionalSfixed64", "OptionalFloat", "OptionalDouble", "OptionalBool", "OptionalString", "OptionalBytes", "OptionalCord", "OptionalNestedMessage", "LazyNestedMessage", "OptionalNestedEnum" }, new[]{ typeof(global::ProtobufUnittest.TestProto3Optional.Types.NestedEnum) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage), global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage.Parser, new[]{ "Bb" }, new[]{ "Bb" }, null, null, null)})
+          }));
+    }
+    #endregion
+
+  }
+  #region Messages
+  public sealed partial class TestProto3Optional : pb::IMessage<TestProto3Optional> {
+    private static readonly pb::MessageParser<TestProto3Optional> _parser = new pb::MessageParser<TestProto3Optional>(() => new TestProto3Optional());
+    private pb::UnknownFieldSet _unknownFields;
+    private int _hasBits0;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pb::MessageParser<TestProto3Optional> Parser { get { return _parser; } }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static pbr::MessageDescriptor Descriptor {
+      get { return global::ProtobufUnittest.UnittestProto3OptionalReflection.Descriptor.MessageTypes[0]; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    pbr::MessageDescriptor pb::IMessage.Descriptor {
+      get { return Descriptor; }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public TestProto3Optional() {
+      OnConstruction();
+    }
+
+    partial void OnConstruction();
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public TestProto3Optional(TestProto3Optional other) : this() {
+      _hasBits0 = other._hasBits0;
+      optionalInt32_ = other.optionalInt32_;
+      optionalInt64_ = other.optionalInt64_;
+      optionalUint32_ = other.optionalUint32_;
+      optionalUint64_ = other.optionalUint64_;
+      optionalSint32_ = other.optionalSint32_;
+      optionalSint64_ = other.optionalSint64_;
+      optionalFixed32_ = other.optionalFixed32_;
+      optionalFixed64_ = other.optionalFixed64_;
+      optionalSfixed32_ = other.optionalSfixed32_;
+      optionalSfixed64_ = other.optionalSfixed64_;
+      optionalFloat_ = other.optionalFloat_;
+      optionalDouble_ = other.optionalDouble_;
+      optionalBool_ = other.optionalBool_;
+      optionalString_ = other.optionalString_;
+      optionalBytes_ = other.optionalBytes_;
+      optionalCord_ = other.optionalCord_;
+      optionalNestedMessage_ = other.optionalNestedMessage_ != null ? other.optionalNestedMessage_.Clone() : null;
+      lazyNestedMessage_ = other.lazyNestedMessage_ != null ? other.lazyNestedMessage_.Clone() : null;
+      optionalNestedEnum_ = other.optionalNestedEnum_;
+      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public TestProto3Optional Clone() {
+      return new TestProto3Optional(this);
+    }
+
+    /// <summary>Field number for the "optional_int32" field.</summary>
+    public const int OptionalInt32FieldNumber = 1;
+    private int optionalInt32_;
+    /// <summary>
+    /// Singular
+    /// </summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int OptionalInt32 {
+      get { if ((_hasBits0 & 1) != 0) { return optionalInt32_; } else { return 0; } }
+      set {
+        _hasBits0 |= 1;
+        optionalInt32_ = value;
+      }
+    }
+    /// <summary>Gets whether the "optional_int32" field is set</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool HasOptionalInt32 {
+      get { return (_hasBits0 & 1) != 0; }
+    }
+    /// <summary>Clears the value of the "optional_int32" field</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void ClearOptionalInt32() {
+      _hasBits0 &= ~1;
+    }
+
+    /// <summary>Field number for the "optional_int64" field.</summary>
+    public const int OptionalInt64FieldNumber = 2;
+    private long optionalInt64_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public long OptionalInt64 {
+      get { if ((_hasBits0 & 2) != 0) { return optionalInt64_; } else { return 0L; } }
+      set {
+        _hasBits0 |= 2;
+        optionalInt64_ = value;
+      }
+    }
+    /// <summary>Gets whether the "optional_int64" field is set</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool HasOptionalInt64 {
+      get { return (_hasBits0 & 2) != 0; }
+    }
+    /// <summary>Clears the value of the "optional_int64" field</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void ClearOptionalInt64() {
+      _hasBits0 &= ~2;
+    }
+
+    /// <summary>Field number for the "optional_uint32" field.</summary>
+    public const int OptionalUint32FieldNumber = 3;
+    private uint optionalUint32_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public uint OptionalUint32 {
+      get { if ((_hasBits0 & 4) != 0) { return optionalUint32_; } else { return 0; } }
+      set {
+        _hasBits0 |= 4;
+        optionalUint32_ = value;
+      }
+    }
+    /// <summary>Gets whether the "optional_uint32" field is set</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool HasOptionalUint32 {
+      get { return (_hasBits0 & 4) != 0; }
+    }
+    /// <summary>Clears the value of the "optional_uint32" field</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void ClearOptionalUint32() {
+      _hasBits0 &= ~4;
+    }
+
+    /// <summary>Field number for the "optional_uint64" field.</summary>
+    public const int OptionalUint64FieldNumber = 4;
+    private ulong optionalUint64_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ulong OptionalUint64 {
+      get { if ((_hasBits0 & 8) != 0) { return optionalUint64_; } else { return 0UL; } }
+      set {
+        _hasBits0 |= 8;
+        optionalUint64_ = value;
+      }
+    }
+    /// <summary>Gets whether the "optional_uint64" field is set</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool HasOptionalUint64 {
+      get { return (_hasBits0 & 8) != 0; }
+    }
+    /// <summary>Clears the value of the "optional_uint64" field</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void ClearOptionalUint64() {
+      _hasBits0 &= ~8;
+    }
+
+    /// <summary>Field number for the "optional_sint32" field.</summary>
+    public const int OptionalSint32FieldNumber = 5;
+    private int optionalSint32_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int OptionalSint32 {
+      get { if ((_hasBits0 & 16) != 0) { return optionalSint32_; } else { return 0; } }
+      set {
+        _hasBits0 |= 16;
+        optionalSint32_ = value;
+      }
+    }
+    /// <summary>Gets whether the "optional_sint32" field is set</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool HasOptionalSint32 {
+      get { return (_hasBits0 & 16) != 0; }
+    }
+    /// <summary>Clears the value of the "optional_sint32" field</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void ClearOptionalSint32() {
+      _hasBits0 &= ~16;
+    }
+
+    /// <summary>Field number for the "optional_sint64" field.</summary>
+    public const int OptionalSint64FieldNumber = 6;
+    private long optionalSint64_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public long OptionalSint64 {
+      get { if ((_hasBits0 & 32) != 0) { return optionalSint64_; } else { return 0L; } }
+      set {
+        _hasBits0 |= 32;
+        optionalSint64_ = value;
+      }
+    }
+    /// <summary>Gets whether the "optional_sint64" field is set</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool HasOptionalSint64 {
+      get { return (_hasBits0 & 32) != 0; }
+    }
+    /// <summary>Clears the value of the "optional_sint64" field</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void ClearOptionalSint64() {
+      _hasBits0 &= ~32;
+    }
+
+    /// <summary>Field number for the "optional_fixed32" field.</summary>
+    public const int OptionalFixed32FieldNumber = 7;
+    private uint optionalFixed32_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public uint OptionalFixed32 {
+      get { if ((_hasBits0 & 64) != 0) { return optionalFixed32_; } else { return 0; } }
+      set {
+        _hasBits0 |= 64;
+        optionalFixed32_ = value;
+      }
+    }
+    /// <summary>Gets whether the "optional_fixed32" field is set</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool HasOptionalFixed32 {
+      get { return (_hasBits0 & 64) != 0; }
+    }
+    /// <summary>Clears the value of the "optional_fixed32" field</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void ClearOptionalFixed32() {
+      _hasBits0 &= ~64;
+    }
+
+    /// <summary>Field number for the "optional_fixed64" field.</summary>
+    public const int OptionalFixed64FieldNumber = 8;
+    private ulong optionalFixed64_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public ulong OptionalFixed64 {
+      get { if ((_hasBits0 & 128) != 0) { return optionalFixed64_; } else { return 0UL; } }
+      set {
+        _hasBits0 |= 128;
+        optionalFixed64_ = value;
+      }
+    }
+    /// <summary>Gets whether the "optional_fixed64" field is set</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool HasOptionalFixed64 {
+      get { return (_hasBits0 & 128) != 0; }
+    }
+    /// <summary>Clears the value of the "optional_fixed64" field</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void ClearOptionalFixed64() {
+      _hasBits0 &= ~128;
+    }
+
+    /// <summary>Field number for the "optional_sfixed32" field.</summary>
+    public const int OptionalSfixed32FieldNumber = 9;
+    private int optionalSfixed32_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int OptionalSfixed32 {
+      get { if ((_hasBits0 & 256) != 0) { return optionalSfixed32_; } else { return 0; } }
+      set {
+        _hasBits0 |= 256;
+        optionalSfixed32_ = value;
+      }
+    }
+    /// <summary>Gets whether the "optional_sfixed32" field is set</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool HasOptionalSfixed32 {
+      get { return (_hasBits0 & 256) != 0; }
+    }
+    /// <summary>Clears the value of the "optional_sfixed32" field</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void ClearOptionalSfixed32() {
+      _hasBits0 &= ~256;
+    }
+
+    /// <summary>Field number for the "optional_sfixed64" field.</summary>
+    public const int OptionalSfixed64FieldNumber = 10;
+    private long optionalSfixed64_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public long OptionalSfixed64 {
+      get { if ((_hasBits0 & 512) != 0) { return optionalSfixed64_; } else { return 0L; } }
+      set {
+        _hasBits0 |= 512;
+        optionalSfixed64_ = value;
+      }
+    }
+    /// <summary>Gets whether the "optional_sfixed64" field is set</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool HasOptionalSfixed64 {
+      get { return (_hasBits0 & 512) != 0; }
+    }
+    /// <summary>Clears the value of the "optional_sfixed64" field</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void ClearOptionalSfixed64() {
+      _hasBits0 &= ~512;
+    }
+
+    /// <summary>Field number for the "optional_float" field.</summary>
+    public const int OptionalFloatFieldNumber = 11;
+    private float optionalFloat_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public float OptionalFloat {
+      get { if ((_hasBits0 & 1024) != 0) { return optionalFloat_; } else { return 0F; } }
+      set {
+        _hasBits0 |= 1024;
+        optionalFloat_ = value;
+      }
+    }
+    /// <summary>Gets whether the "optional_float" field is set</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool HasOptionalFloat {
+      get { return (_hasBits0 & 1024) != 0; }
+    }
+    /// <summary>Clears the value of the "optional_float" field</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void ClearOptionalFloat() {
+      _hasBits0 &= ~1024;
+    }
+
+    /// <summary>Field number for the "optional_double" field.</summary>
+    public const int OptionalDoubleFieldNumber = 12;
+    private double optionalDouble_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public double OptionalDouble {
+      get { if ((_hasBits0 & 2048) != 0) { return optionalDouble_; } else { return 0D; } }
+      set {
+        _hasBits0 |= 2048;
+        optionalDouble_ = value;
+      }
+    }
+    /// <summary>Gets whether the "optional_double" field is set</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool HasOptionalDouble {
+      get { return (_hasBits0 & 2048) != 0; }
+    }
+    /// <summary>Clears the value of the "optional_double" field</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void ClearOptionalDouble() {
+      _hasBits0 &= ~2048;
+    }
+
+    /// <summary>Field number for the "optional_bool" field.</summary>
+    public const int OptionalBoolFieldNumber = 13;
+    private bool optionalBool_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool OptionalBool {
+      get { if ((_hasBits0 & 4096) != 0) { return optionalBool_; } else { return false; } }
+      set {
+        _hasBits0 |= 4096;
+        optionalBool_ = value;
+      }
+    }
+    /// <summary>Gets whether the "optional_bool" field is set</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool HasOptionalBool {
+      get { return (_hasBits0 & 4096) != 0; }
+    }
+    /// <summary>Clears the value of the "optional_bool" field</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void ClearOptionalBool() {
+      _hasBits0 &= ~4096;
+    }
+
+    /// <summary>Field number for the "optional_string" field.</summary>
+    public const int OptionalStringFieldNumber = 14;
+    private string optionalString_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string OptionalString {
+      get { return optionalString_ ?? ""; }
+      set {
+        optionalString_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+    /// <summary>Gets whether the "optional_string" field is set</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool HasOptionalString {
+      get { return optionalString_ != null; }
+    }
+    /// <summary>Clears the value of the "optional_string" field</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void ClearOptionalString() {
+      optionalString_ = null;
+    }
+
+    /// <summary>Field number for the "optional_bytes" field.</summary>
+    public const int OptionalBytesFieldNumber = 15;
+    private pb::ByteString optionalBytes_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public pb::ByteString OptionalBytes {
+      get { return optionalBytes_ ?? pb::ByteString.Empty; }
+      set {
+        optionalBytes_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+    /// <summary>Gets whether the "optional_bytes" field is set</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool HasOptionalBytes {
+      get { return optionalBytes_ != null; }
+    }
+    /// <summary>Clears the value of the "optional_bytes" field</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void ClearOptionalBytes() {
+      optionalBytes_ = null;
+    }
+
+    /// <summary>Field number for the "optional_cord" field.</summary>
+    public const int OptionalCordFieldNumber = 16;
+    private string optionalCord_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public string OptionalCord {
+      get { return optionalCord_ ?? ""; }
+      set {
+        optionalCord_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
+      }
+    }
+    /// <summary>Gets whether the "optional_cord" field is set</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool HasOptionalCord {
+      get { return optionalCord_ != null; }
+    }
+    /// <summary>Clears the value of the "optional_cord" field</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void ClearOptionalCord() {
+      optionalCord_ = null;
+    }
+
+    /// <summary>Field number for the "optional_nested_message" field.</summary>
+    public const int OptionalNestedMessageFieldNumber = 18;
+    private global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage optionalNestedMessage_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage OptionalNestedMessage {
+      get { return optionalNestedMessage_; }
+      set {
+        optionalNestedMessage_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "lazy_nested_message" field.</summary>
+    public const int LazyNestedMessageFieldNumber = 19;
+    private global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage lazyNestedMessage_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage LazyNestedMessage {
+      get { return lazyNestedMessage_; }
+      set {
+        lazyNestedMessage_ = value;
+      }
+    }
+
+    /// <summary>Field number for the "optional_nested_enum" field.</summary>
+    public const int OptionalNestedEnumFieldNumber = 21;
+    private global::ProtobufUnittest.TestProto3Optional.Types.NestedEnum optionalNestedEnum_;
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public global::ProtobufUnittest.TestProto3Optional.Types.NestedEnum OptionalNestedEnum {
+      get { if ((_hasBits0 & 8192) != 0) { return optionalNestedEnum_; } else { return global::ProtobufUnittest.TestProto3Optional.Types.NestedEnum.Unspecified; } }
+      set {
+        _hasBits0 |= 8192;
+        optionalNestedEnum_ = value;
+      }
+    }
+    /// <summary>Gets whether the "optional_nested_enum" field is set</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool HasOptionalNestedEnum {
+      get { return (_hasBits0 & 8192) != 0; }
+    }
+    /// <summary>Clears the value of the "optional_nested_enum" field</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void ClearOptionalNestedEnum() {
+      _hasBits0 &= ~8192;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override bool Equals(object other) {
+      return Equals(other as TestProto3Optional);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public bool Equals(TestProto3Optional other) {
+      if (ReferenceEquals(other, null)) {
+        return false;
+      }
+      if (ReferenceEquals(other, this)) {
+        return true;
+      }
+      if (OptionalInt32 != other.OptionalInt32) return false;
+      if (OptionalInt64 != other.OptionalInt64) return false;
+      if (OptionalUint32 != other.OptionalUint32) return false;
+      if (OptionalUint64 != other.OptionalUint64) return false;
+      if (OptionalSint32 != other.OptionalSint32) return false;
+      if (OptionalSint64 != other.OptionalSint64) return false;
+      if (OptionalFixed32 != other.OptionalFixed32) return false;
+      if (OptionalFixed64 != other.OptionalFixed64) return false;
+      if (OptionalSfixed32 != other.OptionalSfixed32) return false;
+      if (OptionalSfixed64 != other.OptionalSfixed64) return false;
+      if (!pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.Equals(OptionalFloat, other.OptionalFloat)) return false;
+      if (!pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.Equals(OptionalDouble, other.OptionalDouble)) return false;
+      if (OptionalBool != other.OptionalBool) return false;
+      if (OptionalString != other.OptionalString) return false;
+      if (OptionalBytes != other.OptionalBytes) return false;
+      if (OptionalCord != other.OptionalCord) return false;
+      if (!object.Equals(OptionalNestedMessage, other.OptionalNestedMessage)) return false;
+      if (!object.Equals(LazyNestedMessage, other.LazyNestedMessage)) return false;
+      if (OptionalNestedEnum != other.OptionalNestedEnum) return false;
+      return Equals(_unknownFields, other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override int GetHashCode() {
+      int hash = 1;
+      if (HasOptionalInt32) hash ^= OptionalInt32.GetHashCode();
+      if (HasOptionalInt64) hash ^= OptionalInt64.GetHashCode();
+      if (HasOptionalUint32) hash ^= OptionalUint32.GetHashCode();
+      if (HasOptionalUint64) hash ^= OptionalUint64.GetHashCode();
+      if (HasOptionalSint32) hash ^= OptionalSint32.GetHashCode();
+      if (HasOptionalSint64) hash ^= OptionalSint64.GetHashCode();
+      if (HasOptionalFixed32) hash ^= OptionalFixed32.GetHashCode();
+      if (HasOptionalFixed64) hash ^= OptionalFixed64.GetHashCode();
+      if (HasOptionalSfixed32) hash ^= OptionalSfixed32.GetHashCode();
+      if (HasOptionalSfixed64) hash ^= OptionalSfixed64.GetHashCode();
+      if (HasOptionalFloat) hash ^= pbc::ProtobufEqualityComparers.BitwiseSingleEqualityComparer.GetHashCode(OptionalFloat);
+      if (HasOptionalDouble) hash ^= pbc::ProtobufEqualityComparers.BitwiseDoubleEqualityComparer.GetHashCode(OptionalDouble);
+      if (HasOptionalBool) hash ^= OptionalBool.GetHashCode();
+      if (HasOptionalString) hash ^= OptionalString.GetHashCode();
+      if (HasOptionalBytes) hash ^= OptionalBytes.GetHashCode();
+      if (HasOptionalCord) hash ^= OptionalCord.GetHashCode();
+      if (optionalNestedMessage_ != null) hash ^= OptionalNestedMessage.GetHashCode();
+      if (lazyNestedMessage_ != null) hash ^= LazyNestedMessage.GetHashCode();
+      if (HasOptionalNestedEnum) hash ^= OptionalNestedEnum.GetHashCode();
+      if (_unknownFields != null) {
+        hash ^= _unknownFields.GetHashCode();
+      }
+      return hash;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public override string ToString() {
+      return pb::JsonFormatter.ToDiagnosticString(this);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void WriteTo(pb::CodedOutputStream output) {
+      if (HasOptionalInt32) {
+        output.WriteRawTag(8);
+        output.WriteInt32(OptionalInt32);
+      }
+      if (HasOptionalInt64) {
+        output.WriteRawTag(16);
+        output.WriteInt64(OptionalInt64);
+      }
+      if (HasOptionalUint32) {
+        output.WriteRawTag(24);
+        output.WriteUInt32(OptionalUint32);
+      }
+      if (HasOptionalUint64) {
+        output.WriteRawTag(32);
+        output.WriteUInt64(OptionalUint64);
+      }
+      if (HasOptionalSint32) {
+        output.WriteRawTag(40);
+        output.WriteSInt32(OptionalSint32);
+      }
+      if (HasOptionalSint64) {
+        output.WriteRawTag(48);
+        output.WriteSInt64(OptionalSint64);
+      }
+      if (HasOptionalFixed32) {
+        output.WriteRawTag(61);
+        output.WriteFixed32(OptionalFixed32);
+      }
+      if (HasOptionalFixed64) {
+        output.WriteRawTag(65);
+        output.WriteFixed64(OptionalFixed64);
+      }
+      if (HasOptionalSfixed32) {
+        output.WriteRawTag(77);
+        output.WriteSFixed32(OptionalSfixed32);
+      }
+      if (HasOptionalSfixed64) {
+        output.WriteRawTag(81);
+        output.WriteSFixed64(OptionalSfixed64);
+      }
+      if (HasOptionalFloat) {
+        output.WriteRawTag(93);
+        output.WriteFloat(OptionalFloat);
+      }
+      if (HasOptionalDouble) {
+        output.WriteRawTag(97);
+        output.WriteDouble(OptionalDouble);
+      }
+      if (HasOptionalBool) {
+        output.WriteRawTag(104);
+        output.WriteBool(OptionalBool);
+      }
+      if (HasOptionalString) {
+        output.WriteRawTag(114);
+        output.WriteString(OptionalString);
+      }
+      if (HasOptionalBytes) {
+        output.WriteRawTag(122);
+        output.WriteBytes(OptionalBytes);
+      }
+      if (HasOptionalCord) {
+        output.WriteRawTag(130, 1);
+        output.WriteString(OptionalCord);
+      }
+      if (optionalNestedMessage_ != null) {
+        output.WriteRawTag(146, 1);
+        output.WriteMessage(OptionalNestedMessage);
+      }
+      if (lazyNestedMessage_ != null) {
+        output.WriteRawTag(154, 1);
+        output.WriteMessage(LazyNestedMessage);
+      }
+      if (HasOptionalNestedEnum) {
+        output.WriteRawTag(168, 1);
+        output.WriteEnum((int) OptionalNestedEnum);
+      }
+      if (_unknownFields != null) {
+        _unknownFields.WriteTo(output);
+      }
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public int CalculateSize() {
+      int size = 0;
+      if (HasOptionalInt32) {
+        size += 1 + pb::CodedOutputStream.ComputeInt32Size(OptionalInt32);
+      }
+      if (HasOptionalInt64) {
+        size += 1 + pb::CodedOutputStream.ComputeInt64Size(OptionalInt64);
+      }
+      if (HasOptionalUint32) {
+        size += 1 + pb::CodedOutputStream.ComputeUInt32Size(OptionalUint32);
+      }
+      if (HasOptionalUint64) {
+        size += 1 + pb::CodedOutputStream.ComputeUInt64Size(OptionalUint64);
+      }
+      if (HasOptionalSint32) {
+        size += 1 + pb::CodedOutputStream.ComputeSInt32Size(OptionalSint32);
+      }
+      if (HasOptionalSint64) {
+        size += 1 + pb::CodedOutputStream.ComputeSInt64Size(OptionalSint64);
+      }
+      if (HasOptionalFixed32) {
+        size += 1 + 4;
+      }
+      if (HasOptionalFixed64) {
+        size += 1 + 8;
+      }
+      if (HasOptionalSfixed32) {
+        size += 1 + 4;
+      }
+      if (HasOptionalSfixed64) {
+        size += 1 + 8;
+      }
+      if (HasOptionalFloat) {
+        size += 1 + 4;
+      }
+      if (HasOptionalDouble) {
+        size += 1 + 8;
+      }
+      if (HasOptionalBool) {
+        size += 1 + 1;
+      }
+      if (HasOptionalString) {
+        size += 1 + pb::CodedOutputStream.ComputeStringSize(OptionalString);
+      }
+      if (HasOptionalBytes) {
+        size += 1 + pb::CodedOutputStream.ComputeBytesSize(OptionalBytes);
+      }
+      if (HasOptionalCord) {
+        size += 2 + pb::CodedOutputStream.ComputeStringSize(OptionalCord);
+      }
+      if (optionalNestedMessage_ != null) {
+        size += 2 + pb::CodedOutputStream.ComputeMessageSize(OptionalNestedMessage);
+      }
+      if (lazyNestedMessage_ != null) {
+        size += 2 + pb::CodedOutputStream.ComputeMessageSize(LazyNestedMessage);
+      }
+      if (HasOptionalNestedEnum) {
+        size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) OptionalNestedEnum);
+      }
+      if (_unknownFields != null) {
+        size += _unknownFields.CalculateSize();
+      }
+      return size;
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(TestProto3Optional other) {
+      if (other == null) {
+        return;
+      }
+      if (other.HasOptionalInt32) {
+        OptionalInt32 = other.OptionalInt32;
+      }
+      if (other.HasOptionalInt64) {
+        OptionalInt64 = other.OptionalInt64;
+      }
+      if (other.HasOptionalUint32) {
+        OptionalUint32 = other.OptionalUint32;
+      }
+      if (other.HasOptionalUint64) {
+        OptionalUint64 = other.OptionalUint64;
+      }
+      if (other.HasOptionalSint32) {
+        OptionalSint32 = other.OptionalSint32;
+      }
+      if (other.HasOptionalSint64) {
+        OptionalSint64 = other.OptionalSint64;
+      }
+      if (other.HasOptionalFixed32) {
+        OptionalFixed32 = other.OptionalFixed32;
+      }
+      if (other.HasOptionalFixed64) {
+        OptionalFixed64 = other.OptionalFixed64;
+      }
+      if (other.HasOptionalSfixed32) {
+        OptionalSfixed32 = other.OptionalSfixed32;
+      }
+      if (other.HasOptionalSfixed64) {
+        OptionalSfixed64 = other.OptionalSfixed64;
+      }
+      if (other.HasOptionalFloat) {
+        OptionalFloat = other.OptionalFloat;
+      }
+      if (other.HasOptionalDouble) {
+        OptionalDouble = other.OptionalDouble;
+      }
+      if (other.HasOptionalBool) {
+        OptionalBool = other.OptionalBool;
+      }
+      if (other.HasOptionalString) {
+        OptionalString = other.OptionalString;
+      }
+      if (other.HasOptionalBytes) {
+        OptionalBytes = other.OptionalBytes;
+      }
+      if (other.HasOptionalCord) {
+        OptionalCord = other.OptionalCord;
+      }
+      if (other.optionalNestedMessage_ != null) {
+        if (optionalNestedMessage_ == null) {
+          OptionalNestedMessage = new global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage();
+        }
+        OptionalNestedMessage.MergeFrom(other.OptionalNestedMessage);
+      }
+      if (other.lazyNestedMessage_ != null) {
+        if (lazyNestedMessage_ == null) {
+          LazyNestedMessage = new global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage();
+        }
+        LazyNestedMessage.MergeFrom(other.LazyNestedMessage);
+      }
+      if (other.HasOptionalNestedEnum) {
+        OptionalNestedEnum = other.OptionalNestedEnum;
+      }
+      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
+    }
+
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public void MergeFrom(pb::CodedInputStream input) {
+      uint tag;
+      while ((tag = input.ReadTag()) != 0) {
+        switch(tag) {
+          default:
+            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+            break;
+          case 8: {
+            OptionalInt32 = input.ReadInt32();
+            break;
+          }
+          case 16: {
+            OptionalInt64 = input.ReadInt64();
+            break;
+          }
+          case 24: {
+            OptionalUint32 = input.ReadUInt32();
+            break;
+          }
+          case 32: {
+            OptionalUint64 = input.ReadUInt64();
+            break;
+          }
+          case 40: {
+            OptionalSint32 = input.ReadSInt32();
+            break;
+          }
+          case 48: {
+            OptionalSint64 = input.ReadSInt64();
+            break;
+          }
+          case 61: {
+            OptionalFixed32 = input.ReadFixed32();
+            break;
+          }
+          case 65: {
+            OptionalFixed64 = input.ReadFixed64();
+            break;
+          }
+          case 77: {
+            OptionalSfixed32 = input.ReadSFixed32();
+            break;
+          }
+          case 81: {
+            OptionalSfixed64 = input.ReadSFixed64();
+            break;
+          }
+          case 93: {
+            OptionalFloat = input.ReadFloat();
+            break;
+          }
+          case 97: {
+            OptionalDouble = input.ReadDouble();
+            break;
+          }
+          case 104: {
+            OptionalBool = input.ReadBool();
+            break;
+          }
+          case 114: {
+            OptionalString = input.ReadString();
+            break;
+          }
+          case 122: {
+            OptionalBytes = input.ReadBytes();
+            break;
+          }
+          case 130: {
+            OptionalCord = input.ReadString();
+            break;
+          }
+          case 146: {
+            if (optionalNestedMessage_ == null) {
+              OptionalNestedMessage = new global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage();
+            }
+            input.ReadMessage(OptionalNestedMessage);
+            break;
+          }
+          case 154: {
+            if (lazyNestedMessage_ == null) {
+              LazyNestedMessage = new global::ProtobufUnittest.TestProto3Optional.Types.NestedMessage();
+            }
+            input.ReadMessage(LazyNestedMessage);
+            break;
+          }
+          case 168: {
+            OptionalNestedEnum = (global::ProtobufUnittest.TestProto3Optional.Types.NestedEnum) input.ReadEnum();
+            break;
+          }
+        }
+      }
+    }
+
+    #region Nested types
+    /// <summary>Container for nested types declared in the TestProto3Optional message type.</summary>
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+    public static partial class Types {
+      public enum NestedEnum {
+        [pbr::OriginalName("UNSPECIFIED")] Unspecified = 0,
+        [pbr::OriginalName("FOO")] Foo = 1,
+        [pbr::OriginalName("BAR")] Bar = 2,
+        [pbr::OriginalName("BAZ")] Baz = 3,
+        /// <summary>
+        /// Intentionally negative.
+        /// </summary>
+        [pbr::OriginalName("NEG")] Neg = -1,
+      }
+
+      public sealed partial class NestedMessage : pb::IMessage<NestedMessage> {
+        private static readonly pb::MessageParser<NestedMessage> _parser = new pb::MessageParser<NestedMessage>(() => new NestedMessage());
+        private pb::UnknownFieldSet _unknownFields;
+        private int _hasBits0;
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public static pb::MessageParser<NestedMessage> Parser { get { return _parser; } }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public static pbr::MessageDescriptor Descriptor {
+          get { return global::ProtobufUnittest.TestProto3Optional.Descriptor.NestedTypes[0]; }
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        pbr::MessageDescriptor pb::IMessage.Descriptor {
+          get { return Descriptor; }
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public NestedMessage() {
+          OnConstruction();
+        }
+
+        partial void OnConstruction();
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public NestedMessage(NestedMessage other) : this() {
+          _hasBits0 = other._hasBits0;
+          bb_ = other.bb_;
+          _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public NestedMessage Clone() {
+          return new NestedMessage(this);
+        }
+
+        /// <summary>Field number for the "bb" field.</summary>
+        public const int BbFieldNumber = 1;
+        private int bb_;
+        /// <summary>
+        /// The field name "b" fails to compile in proto1 because it conflicts with
+        /// a local variable named "b" in one of the generated methods.  Doh.
+        /// This file needs to compile in proto1 to test backwards-compatibility.
+        /// </summary>
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public int Bb {
+          get { if ((_hasBits0 & 1) != 0) { return bb_; } else { return 0; } }
+          set {
+            _hasBits0 |= 1;
+            bb_ = value;
+          }
+        }
+        /// <summary>Gets whether the "bb" field is set</summary>
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public bool HasBb {
+          get { return (_hasBits0 & 1) != 0; }
+        }
+        /// <summary>Clears the value of the "bb" field</summary>
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public void ClearBb() {
+          _hasBits0 &= ~1;
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public override bool Equals(object other) {
+          return Equals(other as NestedMessage);
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public bool Equals(NestedMessage other) {
+          if (ReferenceEquals(other, null)) {
+            return false;
+          }
+          if (ReferenceEquals(other, this)) {
+            return true;
+          }
+          if (Bb != other.Bb) return false;
+          return Equals(_unknownFields, other._unknownFields);
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public override int GetHashCode() {
+          int hash = 1;
+          if (HasBb) hash ^= Bb.GetHashCode();
+          if (_unknownFields != null) {
+            hash ^= _unknownFields.GetHashCode();
+          }
+          return hash;
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public override string ToString() {
+          return pb::JsonFormatter.ToDiagnosticString(this);
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public void WriteTo(pb::CodedOutputStream output) {
+          if (HasBb) {
+            output.WriteRawTag(8);
+            output.WriteInt32(Bb);
+          }
+          if (_unknownFields != null) {
+            _unknownFields.WriteTo(output);
+          }
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public int CalculateSize() {
+          int size = 0;
+          if (HasBb) {
+            size += 1 + pb::CodedOutputStream.ComputeInt32Size(Bb);
+          }
+          if (_unknownFields != null) {
+            size += _unknownFields.CalculateSize();
+          }
+          return size;
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public void MergeFrom(NestedMessage other) {
+          if (other == null) {
+            return;
+          }
+          if (other.HasBb) {
+            Bb = other.Bb;
+          }
+          _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
+        }
+
+        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
+        public void MergeFrom(pb::CodedInputStream input) {
+          uint tag;
+          while ((tag = input.ReadTag()) != 0) {
+            switch(tag) {
+              default:
+                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
+                break;
+              case 8: {
+                Bb = input.ReadInt32();
+                break;
+              }
+            }
+          }
+        }
+
+      }
+
+    }
+    #endregion
+
+  }
+
+  #endregion
+
+}
+
+#endregion Designer generated code
diff --git a/csharp/src/Google.Protobuf.Test/testprotos.pb b/csharp/src/Google.Protobuf.Test/testprotos.pb
index 424d969..1758578 100644
--- a/csharp/src/Google.Protobuf.Test/testprotos.pb
+++ b/csharp/src/Google.Protobuf.Test/testprotos.pb
Binary files differ