Refactoring of CodedInputStream.Read??? to use boolean return with out param.
diff --git a/src/AddressBook/AddressBookProtos.cs b/src/AddressBook/AddressBookProtos.cs
index cace043..2ed0a11 100644
--- a/src/AddressBook/AddressBookProtos.cs
+++ b/src/AddressBook/AddressBookProtos.cs
@@ -304,22 +304,22 @@
                   if (unknownFields == null) {

                     unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                   }

-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 10: {

-                  Number = input.ReadString();

+                  result.hasNumber |= input.ReadString(ref result.number_);

                   break;

                 }

                 case 16: {

-                  int rawValue = input.ReadEnum();

-                  if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneType), rawValue)) {

+                  object unknown;

+                  if(input.ReadEnum(ref result.type_, out unknown)) {

+                    result.hasType = true;

+                  } else if(unknown is int) {

                     if (unknownFields == null) {

                       unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                     }

-                    unknownFields.MergeVarintField(2, (ulong) rawValue);

-                  } else {

-                    Type = (global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneType) rawValue;

+                    unknownFields.MergeVarintField(2, (ulong)(int)unknown);

                   }

                   break;

                 }

@@ -602,25 +602,23 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              Name = input.ReadString();

+              result.hasName |= input.ReadString(ref result.name_);

               break;

             }

             case 16: {

-              Id = input.ReadInt32();

+              result.hasId |= input.ReadInt32(ref result.id_);

               break;

             }

             case 26: {

-              Email = input.ReadString();

+              result.hasEmail |= input.ReadString(ref result.email_);

               break;

             }

             case 34: {

-              global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber.Builder subBuilder = global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddPhone(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.phone_, global::Google.ProtocolBuffers.Examples.AddressBook.Person.Types.PhoneNumber.DefaultInstance, extensionRegistry);

               break;

             }

           }

@@ -922,13 +920,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              global::Google.ProtocolBuffers.Examples.AddressBook.Person.Builder subBuilder = global::Google.ProtocolBuffers.Examples.AddressBook.Person.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddPerson(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.person_, global::Google.ProtocolBuffers.Examples.AddressBook.Person.DefaultInstance, extensionRegistry);

               break;

             }

           }

diff --git a/src/ProtoGen/EnumFieldGenerator.cs b/src/ProtoGen/EnumFieldGenerator.cs
index 651d7db..3e9e071 100644
--- a/src/ProtoGen/EnumFieldGenerator.cs
+++ b/src/ProtoGen/EnumFieldGenerator.cs
@@ -95,19 +95,32 @@
 

         public void GenerateParsingCode(TextGenerator writer)

         {

-            // TODO(jonskeet): Make a more efficient way of doing this

-            writer.WriteLine("int rawValue = input.ReadEnum();");

-            writer.WriteLine("if (!global::System.Enum.IsDefined(typeof({0}), rawValue)) {{", TypeName);

+            writer.WriteLine("object unknown;");

+            writer.WriteLine("if(input.ReadEnum(ref result.{0}_, out unknown)) {{", Name);

+            writer.WriteLine("  result.has{0} = true;", PropertyName);

+            writer.WriteLine("} else if(unknown is int) {");

             if (!UseLiteRuntime)

             {

                 writer.WriteLine("  if (unknownFields == null) {"); // First unknown field - create builder now

                 writer.WriteLine("    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");

                 writer.WriteLine("  }");

-                writer.WriteLine("  unknownFields.MergeVarintField({0}, (ulong) rawValue);", Number);

+                writer.WriteLine("  unknownFields.MergeVarintField({0}, (ulong)(int)unknown);", Number);

             }

-            writer.WriteLine("} else {");

-            writer.WriteLine("  {0} = ({1}) rawValue;", PropertyName, TypeName);

             writer.WriteLine("}");

+

+            // TO DO(jonskeet): Make a more efficient way of doing this

+            //writer.WriteLine("int rawValue = input.ReadEnum();");

+            //writer.WriteLine("if (!global::System.Enum.IsDefined(typeof({0}), rawValue)) {{", TypeName);

+            //if (!UseLiteRuntime)

+            //{

+            //    writer.WriteLine("  if (unknownFields == null) {"); // First unknown field - create builder now

+            //    writer.WriteLine("    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");

+            //    writer.WriteLine("  }");

+            //    writer.WriteLine("  unknownFields.MergeVarintField({0}, (ulong) rawValue);", Number);

+            //}

+            //writer.WriteLine("} else {");

+            //writer.WriteLine("  {0} = ({1}) rawValue;", PropertyName, TypeName);

+            //writer.WriteLine("}");

         }

 

         public void GenerateSerializationCode(TextGenerator writer)

diff --git a/src/ProtoGen/MessageGenerator.cs b/src/ProtoGen/MessageGenerator.cs
index 94008fb..228dcf8 100644
--- a/src/ProtoGen/MessageGenerator.cs
+++ b/src/ProtoGen/MessageGenerator.cs
@@ -647,7 +647,7 @@
                 writer.WriteLine("    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");

                 writer.WriteLine("  }");

             }

-            writer.WriteLine("  ParseUnknownField(input, {0}extensionRegistry, tag);",

+            writer.WriteLine("  ParseUnknownField(input, {0}extensionRegistry, tag, field_name);",

                              UseLiteRuntime ? "" : "unknownFields, ");

             writer.WriteLine("  break;");

             writer.WriteLine("}");

diff --git a/src/ProtoGen/PrimitiveFieldGenerator.cs b/src/ProtoGen/PrimitiveFieldGenerator.cs
index ad0ab8d..2e767b9 100644
--- a/src/ProtoGen/PrimitiveFieldGenerator.cs
+++ b/src/ProtoGen/PrimitiveFieldGenerator.cs
@@ -97,7 +97,7 @@
 

         public void GenerateParsingCode(TextGenerator writer)

         {

-            writer.WriteLine("{0} = input.Read{1}();", PropertyName, CapitalizedTypeName);

+            writer.WriteLine("result.has{0} |= input.Read{1}(ref result.{2}_);", PropertyName, CapitalizedTypeName, Name);

         }

 

         public void GenerateSerializationCode(TextGenerator writer)

diff --git a/src/ProtoGen/RepeatedEnumFieldGenerator.cs b/src/ProtoGen/RepeatedEnumFieldGenerator.cs
index e3fdd65..27aabf5 100644
--- a/src/ProtoGen/RepeatedEnumFieldGenerator.cs
+++ b/src/ProtoGen/RepeatedEnumFieldGenerator.cs
@@ -112,36 +112,50 @@
 

         public void GenerateParsingCode(TextGenerator writer)

         {

-            // If packed, set up the while loop

-            if (Descriptor.IsPacked)

-            {

-                writer.WriteLine("int length = input.ReadInt32();");

-                writer.WriteLine("int oldLimit = input.PushLimit(length);");

-                writer.WriteLine("while (!input.ReachedLimit) {");

-                writer.Indent();

-            }

-

-            // Read and store the enum

-            // TODO(jonskeet): Make a more efficient way of doing this

-            writer.WriteLine("int rawValue = input.ReadEnum();");

-            writer.WriteLine("if (!global::System.Enum.IsDefined(typeof({0}), rawValue)) {{", TypeName);

+            writer.WriteLine("scg::ICollection<object> unknownItems;");

+            writer.WriteLine("input.ReadEnumArray<{0}>(tag, field_name, result.{1}_, out unknownItems);", TypeName, Name);

             if (!UseLiteRuntime)

             {

-                writer.WriteLine("  if (unknownFields == null) {"); // First unknown field - create builder now

+                writer.WriteLine("if (unknownItems != null) {");

+                writer.WriteLine("  if (unknownFields == null) {");

                 writer.WriteLine("    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");

                 writer.WriteLine("  }");

-                writer.WriteLine("  unknownFields.MergeVarintField({0}, (ulong) rawValue);", Number);

-            }

-            writer.WriteLine("} else {");

-            writer.WriteLine("  Add{0}(({1}) rawValue);", PropertyName, TypeName);

-            writer.WriteLine("}");

-

-            if (Descriptor.IsPacked)

-            {

-                writer.Outdent();

+                writer.WriteLine("  foreach (object rawValue in unknownItems)");

+                writer.WriteLine("    if (rawValue is int)");

+                writer.WriteLine("      unknownFields.MergeVarintField({0}, (ulong)(int)rawValue);", Number);

                 writer.WriteLine("}");

-                writer.WriteLine("input.PopLimit(oldLimit);");

             }

+

+            //// If packed, set up the while loop

+            //if (Descriptor.IsPacked)

+            //{

+            //    writer.WriteLine("int length = input.ReadInt32();");

+            //    writer.WriteLine("int oldLimit = input.PushLimit(length);");

+            //    writer.WriteLine("while (!input.ReachedLimit) {");

+            //    writer.Indent();

+            //}

+

+            //// Read and store the enum

+            //// TO DO(jonskeet): Make a more efficient way of doing this

+            //writer.WriteLine("int rawValue = input.ReadEnum();");

+            //writer.WriteLine("if (!global::System.Enum.IsDefined(typeof({0}), rawValue)) {{", TypeName);

+            //if (!UseLiteRuntime)

+            //{

+            //    writer.WriteLine("  if (unknownFields == null) {"); // First unknown field - create builder now

+            //    writer.WriteLine("    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);");

+            //    writer.WriteLine("  }");

+            //    writer.WriteLine("  unknownFields.MergeVarintField({0}, (ulong) rawValue);", Number);

+            //}

+            //writer.WriteLine("} else {");

+            //writer.WriteLine("  Add{0}(({1}) rawValue);", PropertyName, TypeName);

+            //writer.WriteLine("}");

+

+            //if (Descriptor.IsPacked)

+            //{

+            //    writer.Outdent();

+            //    writer.WriteLine("}");

+            //    writer.WriteLine("input.PopLimit(oldLimit);");

+            //}

         }

 

         public void GenerateSerializationCode(TextGenerator writer)

diff --git a/src/ProtoGen/RepeatedMessageFieldGenerator.cs b/src/ProtoGen/RepeatedMessageFieldGenerator.cs
index 84e92e0..23f06a1 100644
--- a/src/ProtoGen/RepeatedMessageFieldGenerator.cs
+++ b/src/ProtoGen/RepeatedMessageFieldGenerator.cs
@@ -34,6 +34,7 @@
 

 #endregion

 

+using System;

 using Google.ProtocolBuffers.Descriptors;

 

 namespace Google.ProtocolBuffers.ProtoGen

@@ -121,16 +122,18 @@
 

         public void GenerateParsingCode(TextGenerator writer)

         {

-            writer.WriteLine("{0}.Builder subBuilder = {0}.CreateBuilder();", TypeName);

-            if (Descriptor.FieldType == FieldType.Group)

-            {

-                writer.WriteLine("input.ReadGroup({0}, subBuilder, extensionRegistry);", Number);

-            }

-            else

-            {

-                writer.WriteLine("input.ReadMessage(subBuilder, extensionRegistry);");

-            }

-            writer.WriteLine("Add{0}(subBuilder.BuildPartial());", PropertyName);

+            writer.WriteLine("input.Read{0}Array(tag, field_name, result.{1}_, {2}.DefaultInstance, extensionRegistry);", MessageOrGroup, Name, TypeName);

+      

+            //writer.WriteLine("{0}.Builder subBuilder = {0}.CreateBuilder();", TypeName);

+            //if (Descriptor.FieldType == FieldType.Group)

+            //{

+            //    writer.WriteLine("input.ReadGroup({0}, subBuilder, extensionRegistry);", Number);

+            //}

+            //else

+            //{

+            //    writer.WriteLine("input.ReadMessage(subBuilder, extensionRegistry);");

+            //}

+            //writer.WriteLine("Add{0}(subBuilder.BuildPartial());", PropertyName);

         }

 

         public void GenerateSerializationCode(TextGenerator writer)

diff --git a/src/ProtoGen/RepeatedPrimitiveFieldGenerator.cs b/src/ProtoGen/RepeatedPrimitiveFieldGenerator.cs
index 64b95e1..d653628 100644
--- a/src/ProtoGen/RepeatedPrimitiveFieldGenerator.cs
+++ b/src/ProtoGen/RepeatedPrimitiveFieldGenerator.cs
@@ -121,19 +121,20 @@
 

         public void GenerateParsingCode(TextGenerator writer)

         {

-            if (Descriptor.IsPacked)

-            {

-                writer.WriteLine("int length = input.ReadInt32();");

-                writer.WriteLine("int limit = input.PushLimit(length);");

-                writer.WriteLine("while (!input.ReachedLimit) {");

-                writer.WriteLine("  Add{0}(input.Read{1}());", PropertyName, CapitalizedTypeName);

-                writer.WriteLine("}");

-                writer.WriteLine("input.PopLimit(limit);");

-            }

-            else

-            {

-                writer.WriteLine("Add{0}(input.Read{1}());", PropertyName, CapitalizedTypeName);

-            }

+            writer.WriteLine("input.ReadPrimitiveArray(pbd::FieldType.{1}, tag, field_name, result.{0}_);", Name, Descriptor.FieldType);

+            //if (Descriptor.IsPacked)

+            //{

+            //    writer.WriteLine("int length = input.ReadInt32();");

+            //    writer.WriteLine("int limit = input.PushLimit(length);");

+            //    writer.WriteLine("while (!input.ReachedLimit) {");

+            //    writer.WriteLine("  Add{0}(input.Read{1}());", PropertyName, CapitalizedTypeName);

+            //    writer.WriteLine("}");

+            //    writer.WriteLine("input.PopLimit(limit);");

+            //}

+            //else

+            //{

+            //    writer.WriteLine("Add{0}(input.Read{1}());", PropertyName, CapitalizedTypeName);

+            //}

         }

 

         public void GenerateSerializationCode(TextGenerator writer)

diff --git a/src/ProtocolBuffers.Test/CodedInputStreamTest.cs b/src/ProtocolBuffers.Test/CodedInputStreamTest.cs
index a49b1ed..c3ca0a1 100644
--- a/src/ProtocolBuffers.Test/CodedInputStreamTest.cs
+++ b/src/ProtocolBuffers.Test/CodedInputStreamTest.cs
@@ -362,7 +362,8 @@
 

             try

             {

-                input.ReadBytes();

+                ByteString bytes = null;

+                input.ReadBytes(ref bytes);

                 Assert.Fail("Should have thrown an exception!");

             }

             catch (InvalidProtocolBufferException)

@@ -506,7 +507,8 @@
 

             Assert.IsTrue(input.ReadTag(out testtag, out ignored));

             Assert.AreEqual(tag, testtag);

-            string text = input.ReadString();

+            string text = null;

+            input.ReadString(ref text);

             Assert.AreEqual('\ufffd', text[0]);

         }

 

diff --git a/src/ProtocolBuffers.Test/TestProtos/UnitTestCSharpOptionsProtoFile.cs b/src/ProtocolBuffers.Test/TestProtos/UnitTestCSharpOptionsProtoFile.cs
index 79567d2..55f52f7 100644
--- a/src/ProtocolBuffers.Test/TestProtos/UnitTestCSharpOptionsProtoFile.cs
+++ b/src/ProtocolBuffers.Test/TestProtos/UnitTestCSharpOptionsProtoFile.cs
@@ -276,19 +276,19 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              Normal = input.ReadString();

+              result.hasNormal |= input.ReadString(ref result.normal_);

               break;

             }

             case 18: {

-              OptionsMessage_ = input.ReadString();

+              result.hasOptionsMessage_ |= input.ReadString(ref result.optionsMessage_);

               break;

             }

             case 26: {

-              CustomName = input.ReadString();

+              result.hasCustomName |= input.ReadString(ref result.customized_);

               break;

             }

           }

diff --git a/src/ProtocolBuffers.Test/TestProtos/UnitTestCustomOptionsProtoFile.cs b/src/ProtocolBuffers.Test/TestProtos/UnitTestCustomOptionsProtoFile.cs
index 73a1781..96c8a76 100644
--- a/src/ProtocolBuffers.Test/TestProtos/UnitTestCustomOptionsProtoFile.cs
+++ b/src/ProtocolBuffers.Test/TestProtos/UnitTestCustomOptionsProtoFile.cs
@@ -593,11 +593,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              Field1 = input.ReadString();

+              result.hasField1 |= input.ReadString(ref result.field1_);

               break;

             }

           }

@@ -799,7 +799,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -982,7 +982,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -1180,7 +1180,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -1363,7 +1363,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -1546,7 +1546,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -1729,7 +1729,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -1912,7 +1912,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -2095,7 +2095,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -2278,7 +2278,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -2523,19 +2523,19 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              Foo = input.ReadInt32();

+              result.hasFoo |= input.ReadInt32(ref result.foo_);

               break;

             }

             case 16: {

-              Foo2 = input.ReadInt32();

+              result.hasFoo2 |= input.ReadInt32(ref result.foo2_);

               break;

             }

             case 24: {

-              Foo3 = input.ReadInt32();

+              result.hasFoo3 |= input.ReadInt32(ref result.foo3_);

               break;

             }

           }

@@ -2823,11 +2823,11 @@
                   if (unknownFields == null) {

                     unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                   }

-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 8: {

-                  Waldo = input.ReadInt32();

+                  result.hasWaldo |= input.ReadInt32(ref result.waldo_);

                   break;

                 }

               }

@@ -3071,7 +3071,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

@@ -3084,7 +3084,7 @@
               break;

             }

             case 16: {

-              Baz = input.ReadInt32();

+              result.hasBaz |= input.ReadInt32(ref result.baz_);

               break;

             }

             case 26: {

@@ -3415,11 +3415,11 @@
                   if (unknownFields == null) {

                     unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                   }

-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 24: {

-                  Plugh = input.ReadInt32();

+                  result.hasPlugh |= input.ReadInt32(ref result.plugh_);

                   break;

                 }

               }

@@ -3636,11 +3636,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              Qux = input.ReadInt32();

+              result.hasQux |= input.ReadInt32(ref result.qux_);

               break;

             }

             case 19: {

@@ -3905,11 +3905,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 60751608: {

-              Xyzzy = input.ReadInt32();

+              result.hasXyzzy |= input.ReadInt32(ref result.xyzzy_);

               break;

             }

           }

@@ -4110,7 +4110,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

diff --git a/src/ProtocolBuffers.Test/TestProtos/UnitTestEmbedOptimizeForProtoFile.cs b/src/ProtocolBuffers.Test/TestProtos/UnitTestEmbedOptimizeForProtoFile.cs
index 5f1d1a8..9993960 100644
--- a/src/ProtocolBuffers.Test/TestProtos/UnitTestEmbedOptimizeForProtoFile.cs
+++ b/src/ProtocolBuffers.Test/TestProtos/UnitTestEmbedOptimizeForProtoFile.cs
@@ -270,7 +270,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

@@ -283,9 +283,7 @@
               break;

             }

             case 18: {

-              global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddRepeatedMessage(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.repeatedMessage_, global::Google.ProtocolBuffers.TestProtos.TestOptimizedForSize.DefaultInstance, extensionRegistry);

               break;

             }

           }

diff --git a/src/ProtocolBuffers.Test/TestProtos/UnitTestGoogleSpeedProtoFile.cs b/src/ProtocolBuffers.Test/TestProtos/UnitTestGoogleSpeedProtoFile.cs
index 7e0f7d1..757ecff 100644
--- a/src/ProtocolBuffers.Test/TestProtos/UnitTestGoogleSpeedProtoFile.cs
+++ b/src/ProtocolBuffers.Test/TestProtos/UnitTestGoogleSpeedProtoFile.cs
@@ -1086,51 +1086,51 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              Field1 = input.ReadString();

+              result.hasField1 |= input.ReadString(ref result.field1_);

               break;

             }

             case 16: {

-              Field2 = input.ReadInt32();

+              result.hasField2 |= input.ReadInt32(ref result.field2_);

               break;

             }

             case 24: {

-              Field3 = input.ReadInt32();

+              result.hasField3 |= input.ReadInt32(ref result.field3_);

               break;

             }

             case 34: {

-              Field4 = input.ReadString();

+              result.hasField4 |= input.ReadString(ref result.field4_);

               break;

             }

             case 41: {

-              AddField5(input.ReadFixed64());

+              input.ReadPrimitiveArray(pbd::FieldType.Fixed64, tag, field_name, result.field5_);

               break;

             }

             case 48: {

-              Field6 = input.ReadInt32();

+              result.hasField6 |= input.ReadInt32(ref result.field6_);

               break;

             }

             case 58: {

-              Field7 = input.ReadString();

+              result.hasField7 |= input.ReadString(ref result.field7_);

               break;

             }

             case 74: {

-              Field9 = input.ReadString();

+              result.hasField9 |= input.ReadString(ref result.field9_);

               break;

             }

             case 96: {

-              Field12 = input.ReadBool();

+              result.hasField12 |= input.ReadBool(ref result.field12_);

               break;

             }

             case 104: {

-              Field13 = input.ReadBool();

+              result.hasField13 |= input.ReadBool(ref result.field13_);

               break;

             }

             case 112: {

-              Field14 = input.ReadBool();

+              result.hasField14 |= input.ReadBool(ref result.field14_);

               break;

             }

             case 122: {

@@ -1143,119 +1143,119 @@
               break;

             }

             case 128: {

-              Field16 = input.ReadInt32();

+              result.hasField16 |= input.ReadInt32(ref result.field16_);

               break;

             }

             case 136: {

-              Field17 = input.ReadBool();

+              result.hasField17 |= input.ReadBool(ref result.field17_);

               break;

             }

             case 146: {

-              Field18 = input.ReadString();

+              result.hasField18 |= input.ReadString(ref result.field18_);

               break;

             }

             case 176: {

-              Field22 = input.ReadInt64();

+              result.hasField22 |= input.ReadInt64(ref result.field22_);

               break;

             }

             case 184: {

-              Field23 = input.ReadInt32();

+              result.hasField23 |= input.ReadInt32(ref result.field23_);

               break;

             }

             case 192: {

-              Field24 = input.ReadBool();

+              result.hasField24 |= input.ReadBool(ref result.field24_);

               break;

             }

             case 200: {

-              Field25 = input.ReadInt32();

+              result.hasField25 |= input.ReadInt32(ref result.field25_);

               break;

             }

             case 232: {

-              Field29 = input.ReadInt32();

+              result.hasField29 |= input.ReadInt32(ref result.field29_);

               break;

             }

             case 240: {

-              Field30 = input.ReadBool();

+              result.hasField30 |= input.ReadBool(ref result.field30_);

               break;

             }

             case 472: {

-              Field59 = input.ReadBool();

+              result.hasField59 |= input.ReadBool(ref result.field59_);

               break;

             }

             case 480: {

-              Field60 = input.ReadInt32();

+              result.hasField60 |= input.ReadInt32(ref result.field60_);

               break;

             }

             case 536: {

-              Field67 = input.ReadInt32();

+              result.hasField67 |= input.ReadInt32(ref result.field67_);

               break;

             }

             case 544: {

-              Field68 = input.ReadInt32();

+              result.hasField68 |= input.ReadInt32(ref result.field68_);

               break;

             }

             case 624: {

-              Field78 = input.ReadBool();

+              result.hasField78 |= input.ReadBool(ref result.field78_);

               break;

             }

             case 640: {

-              Field80 = input.ReadBool();

+              result.hasField80 |= input.ReadBool(ref result.field80_);

               break;

             }

             case 648: {

-              Field81 = input.ReadBool();

+              result.hasField81 |= input.ReadBool(ref result.field81_);

               break;

             }

             case 800: {

-              Field100 = input.ReadInt32();

+              result.hasField100 |= input.ReadInt32(ref result.field100_);

               break;

             }

             case 808: {

-              Field101 = input.ReadInt32();

+              result.hasField101 |= input.ReadInt32(ref result.field101_);

               break;

             }

             case 818: {

-              Field102 = input.ReadString();

+              result.hasField102 |= input.ReadString(ref result.field102_);

               break;

             }

             case 826: {

-              Field103 = input.ReadString();

+              result.hasField103 |= input.ReadString(ref result.field103_);

               break;

             }

             case 832: {

-              Field104 = input.ReadInt32();

+              result.hasField104 |= input.ReadInt32(ref result.field104_);

               break;

             }

             case 1024: {

-              Field128 = input.ReadInt32();

+              result.hasField128 |= input.ReadInt32(ref result.field128_);

               break;

             }

             case 1034: {

-              Field129 = input.ReadString();

+              result.hasField129 |= input.ReadString(ref result.field129_);

               break;

             }

             case 1040: {

-              Field130 = input.ReadInt32();

+              result.hasField130 |= input.ReadInt32(ref result.field130_);

               break;

             }

             case 1048: {

-              Field131 = input.ReadInt32();

+              result.hasField131 |= input.ReadInt32(ref result.field131_);

               break;

             }

             case 1200: {

-              Field150 = input.ReadInt32();

+              result.hasField150 |= input.ReadInt32(ref result.field150_);

               break;

             }

             case 2168: {

-              Field271 = input.ReadInt32();

+              result.hasField271 |= input.ReadInt32(ref result.field271_);

               break;

             }

             case 2176: {

-              Field272 = input.ReadInt32();

+              result.hasField272 |= input.ReadInt32(ref result.field272_);

               break;

             }

             case 2240: {

-              Field280 = input.ReadInt32();

+              result.hasField280 |= input.ReadInt32(ref result.field280_);

               break;

             }

           }

@@ -2599,87 +2599,87 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              Field1 = input.ReadInt32();

+              result.hasField1 |= input.ReadInt32(ref result.field1_);

               break;

             }

             case 16: {

-              Field2 = input.ReadInt32();

+              result.hasField2 |= input.ReadInt32(ref result.field2_);

               break;

             }

             case 24: {

-              Field3 = input.ReadInt32();

+              result.hasField3 |= input.ReadInt32(ref result.field3_);

               break;

             }

             case 96: {

-              Field12 = input.ReadBool();

+              result.hasField12 |= input.ReadBool(ref result.field12_);

               break;

             }

             case 104: {

-              Field13 = input.ReadInt64();

+              result.hasField13 |= input.ReadInt64(ref result.field13_);

               break;

             }

             case 112: {

-              Field14 = input.ReadInt64();

+              result.hasField14 |= input.ReadInt64(ref result.field14_);

               break;

             }

             case 122: {

-              Field15 = input.ReadString();

+              result.hasField15 |= input.ReadString(ref result.field15_);

               break;

             }

             case 128: {

-              Field16 = input.ReadInt32();

+              result.hasField16 |= input.ReadInt32(ref result.field16_);

               break;

             }

             case 152: {

-              Field19 = input.ReadInt32();

+              result.hasField19 |= input.ReadInt32(ref result.field19_);

               break;

             }

             case 160: {

-              Field20 = input.ReadBool();

+              result.hasField20 |= input.ReadBool(ref result.field20_);

               break;

             }

             case 169: {

-              Field21 = input.ReadFixed64();

+              result.hasField21 |= input.ReadFixed64(ref result.field21_);

               break;

             }

             case 176: {

-              Field22 = input.ReadInt32();

+              result.hasField22 |= input.ReadInt32(ref result.field22_);

               break;

             }

             case 184: {

-              Field23 = input.ReadBool();

+              result.hasField23 |= input.ReadBool(ref result.field23_);

               break;

             }

             case 224: {

-              Field28 = input.ReadBool();

+              result.hasField28 |= input.ReadBool(ref result.field28_);

               break;

             }

             case 1629: {

-              Field203 = input.ReadFixed32();

+              result.hasField203 |= input.ReadFixed32(ref result.field203_);

               break;

             }

             case 1632: {

-              Field204 = input.ReadInt32();

+              result.hasField204 |= input.ReadInt32(ref result.field204_);

               break;

             }

             case 1642: {

-              Field205 = input.ReadString();

+              result.hasField205 |= input.ReadString(ref result.field205_);

               break;

             }

             case 1648: {

-              Field206 = input.ReadBool();

+              result.hasField206 |= input.ReadBool(ref result.field206_);

               break;

             }

             case 1656: {

-              Field207 = input.ReadUInt64();

+              result.hasField207 |= input.ReadUInt64(ref result.field207_);

               break;

             }

             case 2400: {

-              Field300 = input.ReadUInt64();

+              result.hasField300 |= input.ReadUInt64(ref result.field300_);

               break;

             }

           }

@@ -3593,63 +3593,63 @@
                   if (unknownFields == null) {

                     unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                   }

-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 40: {

-                  Field5 = input.ReadInt32();

+                  result.hasField5 |= input.ReadInt32(ref result.field5_);

                   break;

                 }

                 case 93: {

-                  Field11 = input.ReadFloat();

+                  result.hasField11 |= input.ReadFloat(ref result.field11_);

                   break;

                 }

                 case 98: {

-                  Field12 = input.ReadString();

+                  result.hasField12 |= input.ReadString(ref result.field12_);

                   break;

                 }

                 case 106: {

-                  Field13 = input.ReadString();

+                  result.hasField13 |= input.ReadString(ref result.field13_);

                   break;

                 }

                 case 114: {

-                  AddField14(input.ReadString());

+                  input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.field14_);

                   break;

                 }

                 case 120: {

-                  Field15 = input.ReadUInt64();

+                  result.hasField15 |= input.ReadUInt64(ref result.field15_);

                   break;

                 }

                 case 130: {

-                  Field16 = input.ReadString();

+                  result.hasField16 |= input.ReadString(ref result.field16_);

                   break;

                 }

                 case 160: {

-                  Field20 = input.ReadInt32();

+                  result.hasField20 |= input.ReadInt32(ref result.field20_);

                   break;

                 }

                 case 178: {

-                  AddField22(input.ReadString());

+                  input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.field22_);

                   break;

                 }

                 case 194: {

-                  Field24 = input.ReadString();

+                  result.hasField24 |= input.ReadString(ref result.field24_);

                   break;

                 }

                 case 213: {

-                  Field26 = input.ReadFloat();

+                  result.hasField26 |= input.ReadFloat(ref result.field26_);

                   break;

                 }

                 case 218: {

-                  Field27 = input.ReadString();

+                  result.hasField27 |= input.ReadString(ref result.field27_);

                   break;

                 }

                 case 224: {

-                  Field28 = input.ReadInt32();

+                  result.hasField28 |= input.ReadInt32(ref result.field28_);

                   break;

                 }

                 case 234: {

-                  Field29 = input.ReadString();

+                  result.hasField29 |= input.ReadString(ref result.field29_);

                   break;

                 }

                 case 250: {

@@ -3662,7 +3662,7 @@
                   break;

                 }

                 case 584: {

-                  AddField73(input.ReadInt32());

+                  input.ReadPrimitiveArray(pbd::FieldType.Int32, tag, field_name, result.field73_);

                   break;

                 }

               }

@@ -4762,129 +4762,127 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              Field1 = input.ReadString();

+              result.hasField1 |= input.ReadString(ref result.field1_);

               break;

             }

             case 18: {

-              Field2 = input.ReadBytes();

+              result.hasField2 |= input.ReadBytes(ref result.field2_);

               break;

             }

             case 24: {

-              Field3 = input.ReadInt64();

+              result.hasField3 |= input.ReadInt64(ref result.field3_);

               break;

             }

             case 32: {

-              Field4 = input.ReadInt64();

+              result.hasField4 |= input.ReadInt64(ref result.field4_);

               break;

             }

             case 50: {

-              Field6 = input.ReadString();

+              result.hasField6 |= input.ReadString(ref result.field6_);

               break;

             }

             case 83: {

-              global::Google.ProtocolBuffers.TestProtos.SpeedMessage2.Types.Group1.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.SpeedMessage2.Types.Group1.CreateBuilder();

-              input.ReadGroup(10, subBuilder, extensionRegistry);

-              AddGroup1(subBuilder.BuildPartial());

+              input.ReadGroupArray(tag, field_name, result.group1_, global::Google.ProtocolBuffers.TestProtos.SpeedMessage2.Types.Group1.DefaultInstance, extensionRegistry);

               break;

             }

             case 168: {

-              Field21 = input.ReadInt32();

+              result.hasField21 |= input.ReadInt32(ref result.field21_);

               break;

             }

             case 205: {

-              Field25 = input.ReadFloat();

+              result.hasField25 |= input.ReadFloat(ref result.field25_);

               break;

             }

             case 240: {

-              Field30 = input.ReadInt64();

+              result.hasField30 |= input.ReadInt64(ref result.field30_);

               break;

             }

             case 504: {

-              Field63 = input.ReadInt32();

+              result.hasField63 |= input.ReadInt32(ref result.field63_);

               break;

             }

             case 568: {

-              Field71 = input.ReadInt32();

+              result.hasField71 |= input.ReadInt32(ref result.field71_);

               break;

             }

             case 600: {

-              Field75 = input.ReadBool();

+              result.hasField75 |= input.ReadBool(ref result.field75_);

               break;

             }

             case 872: {

-              Field109 = input.ReadInt32();

+              result.hasField109 |= input.ReadInt32(ref result.field109_);

               break;

             }

             case 1018: {

-              AddField127(input.ReadString());

+              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.field127_);

               break;

             }

             case 1026: {

-              AddField128(input.ReadString());

+              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.field128_);

               break;

             }

             case 1032: {

-              Field129 = input.ReadInt32();

+              result.hasField129 |= input.ReadInt32(ref result.field129_);

               break;

             }

             case 1040: {

-              AddField130(input.ReadInt64());

+              input.ReadPrimitiveArray(pbd::FieldType.Int64, tag, field_name, result.field130_);

               break;

             }

             case 1048: {

-              Field131 = input.ReadInt64();

+              result.hasField131 |= input.ReadInt64(ref result.field131_);

               break;

             }

             case 1640: {

-              Field205 = input.ReadBool();

+              result.hasField205 |= input.ReadBool(ref result.field205_);

               break;

             }

             case 1648: {

-              Field206 = input.ReadBool();

+              result.hasField206 |= input.ReadBool(ref result.field206_);

               break;

             }

             case 1680: {

-              Field210 = input.ReadInt32();

+              result.hasField210 |= input.ReadInt32(ref result.field210_);

               break;

             }

             case 1688: {

-              Field211 = input.ReadInt32();

+              result.hasField211 |= input.ReadInt32(ref result.field211_);

               break;

             }

             case 1696: {

-              Field212 = input.ReadInt32();

+              result.hasField212 |= input.ReadInt32(ref result.field212_);

               break;

             }

             case 1704: {

-              Field213 = input.ReadInt32();

+              result.hasField213 |= input.ReadInt32(ref result.field213_);

               break;

             }

             case 1728: {

-              Field216 = input.ReadInt32();

+              result.hasField216 |= input.ReadInt32(ref result.field216_);

               break;

             }

             case 1736: {

-              Field217 = input.ReadInt32();

+              result.hasField217 |= input.ReadInt32(ref result.field217_);

               break;

             }

             case 1744: {

-              Field218 = input.ReadInt32();

+              result.hasField218 |= input.ReadInt32(ref result.field218_);

               break;

             }

             case 1760: {

-              Field220 = input.ReadInt32();

+              result.hasField220 |= input.ReadInt32(ref result.field220_);

               break;

             }

             case 1768: {

-              Field221 = input.ReadInt32();

+              result.hasField221 |= input.ReadInt32(ref result.field221_);

               break;

             }

             case 1781: {

-              Field222 = input.ReadFloat();

+              result.hasField222 |= input.ReadFloat(ref result.field222_);

               break;

             }

           }

@@ -5867,51 +5865,51 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 13: {

-              Field1 = input.ReadFloat();

+              result.hasField1 |= input.ReadFloat(ref result.field1_);

               break;

             }

             case 21: {

-              Field2 = input.ReadFloat();

+              result.hasField2 |= input.ReadFloat(ref result.field2_);

               break;

             }

             case 29: {

-              Field3 = input.ReadFloat();

+              result.hasField3 |= input.ReadFloat(ref result.field3_);

               break;

             }

             case 32: {

-              Field4 = input.ReadBool();

+              result.hasField4 |= input.ReadBool(ref result.field4_);

               break;

             }

             case 40: {

-              Field5 = input.ReadBool();

+              result.hasField5 |= input.ReadBool(ref result.field5_);

               break;

             }

             case 48: {

-              Field6 = input.ReadBool();

+              result.hasField6 |= input.ReadBool(ref result.field6_);

               break;

             }

             case 56: {

-              Field7 = input.ReadBool();

+              result.hasField7 |= input.ReadBool(ref result.field7_);

               break;

             }

             case 69: {

-              Field8 = input.ReadFloat();

+              result.hasField8 |= input.ReadFloat(ref result.field8_);

               break;

             }

             case 72: {

-              Field9 = input.ReadBool();

+              result.hasField9 |= input.ReadBool(ref result.field9_);

               break;

             }

             case 85: {

-              Field10 = input.ReadFloat();

+              result.hasField10 |= input.ReadFloat(ref result.field10_);

               break;

             }

             case 88: {

-              Field11 = input.ReadInt64();

+              result.hasField11 |= input.ReadInt64(ref result.field11_);

               break;

             }

           }

diff --git a/src/ProtocolBuffers.Test/TestProtos/UnitTestImportLiteProtoFile.cs b/src/ProtocolBuffers.Test/TestProtos/UnitTestImportLiteProtoFile.cs
index 26eb96a..0e890f3 100644
--- a/src/ProtocolBuffers.Test/TestProtos/UnitTestImportLiteProtoFile.cs
+++ b/src/ProtocolBuffers.Test/TestProtos/UnitTestImportLiteProtoFile.cs
@@ -218,11 +218,11 @@
               if (pb::WireFormat.IsEndGroupTag(tag)) {

                 return this;

               }

-              ParseUnknownField(input, extensionRegistry, tag);

+              ParseUnknownField(input, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              D = input.ReadInt32();

+              result.hasD |= input.ReadInt32(ref result.d_);

               break;

             }

           }

diff --git a/src/ProtocolBuffers.Test/TestProtos/UnitTestImportProtoFile.cs b/src/ProtocolBuffers.Test/TestProtos/UnitTestImportProtoFile.cs
index d97466d..cbd6cea 100644
--- a/src/ProtocolBuffers.Test/TestProtos/UnitTestImportProtoFile.cs
+++ b/src/ProtocolBuffers.Test/TestProtos/UnitTestImportProtoFile.cs
@@ -249,11 +249,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              D = input.ReadInt32();

+              result.hasD |= input.ReadInt32(ref result.d_);

               break;

             }

           }

diff --git a/src/ProtocolBuffers.Test/TestProtos/UnitTestMessageSetProtoFile.cs b/src/ProtocolBuffers.Test/TestProtos/UnitTestMessageSetProtoFile.cs
index 5e5cea7..b41a15d 100644
--- a/src/ProtocolBuffers.Test/TestProtos/UnitTestMessageSetProtoFile.cs
+++ b/src/ProtocolBuffers.Test/TestProtos/UnitTestMessageSetProtoFile.cs
@@ -267,7 +267,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -469,7 +469,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

@@ -718,11 +718,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 120: {

-              I = input.ReadInt32();

+              result.hasI |= input.ReadInt32(ref result.i_);

               break;

             }

           }

@@ -944,11 +944,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 202: {

-              Str = input.ReadString();

+              result.hasStr |= input.ReadString(ref result.str_);

               break;

             }

           }

@@ -1220,15 +1220,15 @@
                   if (unknownFields == null) {

                     unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                   }

-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 16: {

-                  TypeId = input.ReadInt32();

+                  result.hasTypeId |= input.ReadInt32(ref result.typeId_);

                   break;

                 }

                 case 26: {

-                  Message = input.ReadBytes();

+                  result.hasMessage |= input.ReadBytes(ref result.message_);

                   break;

                 }

               }

@@ -1448,13 +1448,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 11: {

-              global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item.CreateBuilder();

-              input.ReadGroup(1, subBuilder, extensionRegistry);

-              AddItem(subBuilder.BuildPartial());

+              input.ReadGroupArray(tag, field_name, result.item_, global::Google.ProtocolBuffers.TestProtos.RawMessageSet.Types.Item.DefaultInstance, extensionRegistry);

               break;

             }

           }

diff --git a/src/ProtocolBuffers.Test/TestProtos/UnitTestNoGenericServicesProtoFile.cs b/src/ProtocolBuffers.Test/TestProtos/UnitTestNoGenericServicesProtoFile.cs
index 9897e23..f72688b 100644
--- a/src/ProtocolBuffers.Test/TestProtos/UnitTestNoGenericServicesProtoFile.cs
+++ b/src/ProtocolBuffers.Test/TestProtos/UnitTestNoGenericServicesProtoFile.cs
@@ -264,11 +264,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              A = input.ReadInt32();

+              result.hasA |= input.ReadInt32(ref result.a_);

               break;

             }

           }

diff --git a/src/ProtocolBuffers.Test/TestProtos/UnitTestProtoFile.cs b/src/ProtocolBuffers.Test/TestProtos/UnitTestProtoFile.cs
index ce2fbc8..d564a02 100644
--- a/src/ProtocolBuffers.Test/TestProtos/UnitTestProtoFile.cs
+++ b/src/ProtocolBuffers.Test/TestProtos/UnitTestProtoFile.cs
@@ -1246,11 +1246,11 @@
                   if (unknownFields == null) {

                     unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                   }

-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 8: {

-                  Bb = input.ReadInt32();

+                  result.hasBb |= input.ReadInt32(ref result.bb_);

                   break;

                 }

               }

@@ -1470,11 +1470,11 @@
                   if (unknownFields == null) {

                     unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                   }

-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 136: {

-                  A = input.ReadInt32();

+                  result.hasA |= input.ReadInt32(ref result.a_);

                   break;

                 }

               }

@@ -1694,11 +1694,11 @@
                   if (unknownFields == null) {

                     unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                   }

-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 376: {

-                  A = input.ReadInt32();

+                  result.hasA |= input.ReadInt32(ref result.a_);

                   break;

                 }

               }

@@ -3349,67 +3349,67 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              OptionalInt32 = input.ReadInt32();

+              result.hasOptionalInt32 |= input.ReadInt32(ref result.optionalInt32_);

               break;

             }

             case 16: {

-              OptionalInt64 = input.ReadInt64();

+              result.hasOptionalInt64 |= input.ReadInt64(ref result.optionalInt64_);

               break;

             }

             case 24: {

-              OptionalUint32 = input.ReadUInt32();

+              result.hasOptionalUint32 |= input.ReadUInt32(ref result.optionalUint32_);

               break;

             }

             case 32: {

-              OptionalUint64 = input.ReadUInt64();

+              result.hasOptionalUint64 |= input.ReadUInt64(ref result.optionalUint64_);

               break;

             }

             case 40: {

-              OptionalSint32 = input.ReadSInt32();

+              result.hasOptionalSint32 |= input.ReadSInt32(ref result.optionalSint32_);

               break;

             }

             case 48: {

-              OptionalSint64 = input.ReadSInt64();

+              result.hasOptionalSint64 |= input.ReadSInt64(ref result.optionalSint64_);

               break;

             }

             case 61: {

-              OptionalFixed32 = input.ReadFixed32();

+              result.hasOptionalFixed32 |= input.ReadFixed32(ref result.optionalFixed32_);

               break;

             }

             case 65: {

-              OptionalFixed64 = input.ReadFixed64();

+              result.hasOptionalFixed64 |= input.ReadFixed64(ref result.optionalFixed64_);

               break;

             }

             case 77: {

-              OptionalSfixed32 = input.ReadSFixed32();

+              result.hasOptionalSfixed32 |= input.ReadSFixed32(ref result.optionalSfixed32_);

               break;

             }

             case 81: {

-              OptionalSfixed64 = input.ReadSFixed64();

+              result.hasOptionalSfixed64 |= input.ReadSFixed64(ref result.optionalSfixed64_);

               break;

             }

             case 93: {

-              OptionalFloat = input.ReadFloat();

+              result.hasOptionalFloat |= input.ReadFloat(ref result.optionalFloat_);

               break;

             }

             case 97: {

-              OptionalDouble = input.ReadDouble();

+              result.hasOptionalDouble |= input.ReadDouble(ref result.optionalDouble_);

               break;

             }

             case 104: {

-              OptionalBool = input.ReadBool();

+              result.hasOptionalBool |= input.ReadBool(ref result.optionalBool_);

               break;

             }

             case 114: {

-              OptionalString = input.ReadString();

+              result.hasOptionalString |= input.ReadString(ref result.optionalString_);

               break;

             }

             case 122: {

-              OptionalBytes = input.ReadBytes();

+              result.hasOptionalBytes |= input.ReadBytes(ref result.optionalBytes_);

               break;

             }

             case 131: {

@@ -3449,279 +3449,274 @@
               break;

             }

             case 168: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum), rawValue)) {

+              object unknown;

+              if(input.ReadEnum(ref result.optionalNestedEnum_, out unknown)) {

+                result.hasOptionalNestedEnum = true;

+              } else if(unknown is int) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(21, (ulong) rawValue);

-              } else {

-                OptionalNestedEnum = (global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum) rawValue;

+                unknownFields.MergeVarintField(21, (ulong)(int)unknown);

               }

               break;

             }

             case 176: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnum), rawValue)) {

+              object unknown;

+              if(input.ReadEnum(ref result.optionalForeignEnum_, out unknown)) {

+                result.hasOptionalForeignEnum = true;

+              } else if(unknown is int) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(22, (ulong) rawValue);

-              } else {

-                OptionalForeignEnum = (global::Google.ProtocolBuffers.TestProtos.ForeignEnum) rawValue;

+                unknownFields.MergeVarintField(22, (ulong)(int)unknown);

               }

               break;

             }

             case 184: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ImportEnum), rawValue)) {

+              object unknown;

+              if(input.ReadEnum(ref result.optionalImportEnum_, out unknown)) {

+                result.hasOptionalImportEnum = true;

+              } else if(unknown is int) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(23, (ulong) rawValue);

-              } else {

-                OptionalImportEnum = (global::Google.ProtocolBuffers.TestProtos.ImportEnum) rawValue;

+                unknownFields.MergeVarintField(23, (ulong)(int)unknown);

               }

               break;

             }

             case 194: {

-              OptionalStringPiece = input.ReadString();

+              result.hasOptionalStringPiece |= input.ReadString(ref result.optionalStringPiece_);

               break;

             }

             case 202: {

-              OptionalCord = input.ReadString();

+              result.hasOptionalCord |= input.ReadString(ref result.optionalCord_);

               break;

             }

             case 248: {

-              AddRepeatedInt32(input.ReadInt32());

+              input.ReadPrimitiveArray(pbd::FieldType.Int32, tag, field_name, result.repeatedInt32_);

               break;

             }

             case 256: {

-              AddRepeatedInt64(input.ReadInt64());

+              input.ReadPrimitiveArray(pbd::FieldType.Int64, tag, field_name, result.repeatedInt64_);

               break;

             }

             case 264: {

-              AddRepeatedUint32(input.ReadUInt32());

+              input.ReadPrimitiveArray(pbd::FieldType.UInt32, tag, field_name, result.repeatedUint32_);

               break;

             }

             case 272: {

-              AddRepeatedUint64(input.ReadUInt64());

+              input.ReadPrimitiveArray(pbd::FieldType.UInt64, tag, field_name, result.repeatedUint64_);

               break;

             }

             case 280: {

-              AddRepeatedSint32(input.ReadSInt32());

+              input.ReadPrimitiveArray(pbd::FieldType.SInt32, tag, field_name, result.repeatedSint32_);

               break;

             }

             case 288: {

-              AddRepeatedSint64(input.ReadSInt64());

+              input.ReadPrimitiveArray(pbd::FieldType.SInt64, tag, field_name, result.repeatedSint64_);

               break;

             }

             case 301: {

-              AddRepeatedFixed32(input.ReadFixed32());

+              input.ReadPrimitiveArray(pbd::FieldType.Fixed32, tag, field_name, result.repeatedFixed32_);

               break;

             }

             case 305: {

-              AddRepeatedFixed64(input.ReadFixed64());

+              input.ReadPrimitiveArray(pbd::FieldType.Fixed64, tag, field_name, result.repeatedFixed64_);

               break;

             }

             case 317: {

-              AddRepeatedSfixed32(input.ReadSFixed32());

+              input.ReadPrimitiveArray(pbd::FieldType.SFixed32, tag, field_name, result.repeatedSfixed32_);

               break;

             }

             case 321: {

-              AddRepeatedSfixed64(input.ReadSFixed64());

+              input.ReadPrimitiveArray(pbd::FieldType.SFixed64, tag, field_name, result.repeatedSfixed64_);

               break;

             }

             case 333: {

-              AddRepeatedFloat(input.ReadFloat());

+              input.ReadPrimitiveArray(pbd::FieldType.Float, tag, field_name, result.repeatedFloat_);

               break;

             }

             case 337: {

-              AddRepeatedDouble(input.ReadDouble());

+              input.ReadPrimitiveArray(pbd::FieldType.Double, tag, field_name, result.repeatedDouble_);

               break;

             }

             case 344: {

-              AddRepeatedBool(input.ReadBool());

+              input.ReadPrimitiveArray(pbd::FieldType.Bool, tag, field_name, result.repeatedBool_);

               break;

             }

             case 354: {

-              AddRepeatedString(input.ReadString());

+              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedString_);

               break;

             }

             case 362: {

-              AddRepeatedBytes(input.ReadBytes());

+              input.ReadPrimitiveArray(pbd::FieldType.Bytes, tag, field_name, result.repeatedBytes_);

               break;

             }

             case 371: {

-              global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup.CreateBuilder();

-              input.ReadGroup(46, subBuilder, extensionRegistry);

-              AddRepeatedGroup(subBuilder.BuildPartial());

+              input.ReadGroupArray(tag, field_name, result.repeatedGroup_, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup.DefaultInstance, extensionRegistry);

               break;

             }

             case 386: {

-              global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddRepeatedNestedMessage(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.repeatedNestedMessage_, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.DefaultInstance, extensionRegistry);

               break;

             }

             case 394: {

-              global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.ForeignMessage.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddRepeatedForeignMessage(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.repeatedForeignMessage_, global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance, extensionRegistry);

               break;

             }

             case 402: {

-              global::Google.ProtocolBuffers.TestProtos.ImportMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.ImportMessage.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddRepeatedImportMessage(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.repeatedImportMessage_, global::Google.ProtocolBuffers.TestProtos.ImportMessage.DefaultInstance, extensionRegistry);

               break;

             }

             case 408: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum), rawValue)) {

+              scg::ICollection<object> unknownItems;

+              input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum>(tag, field_name, result.repeatedNestedEnum_, out unknownItems);

+              if (unknownItems != null) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(51, (ulong) rawValue);

-              } else {

-                AddRepeatedNestedEnum((global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum) rawValue);

+                foreach (object rawValue in unknownItems)

+                  if (rawValue is int)

+                    unknownFields.MergeVarintField(51, (ulong)(int)rawValue);

               }

               break;

             }

             case 416: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnum), rawValue)) {

+              scg::ICollection<object> unknownItems;

+              input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>(tag, field_name, result.repeatedForeignEnum_, out unknownItems);

+              if (unknownItems != null) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(52, (ulong) rawValue);

-              } else {

-                AddRepeatedForeignEnum((global::Google.ProtocolBuffers.TestProtos.ForeignEnum) rawValue);

+                foreach (object rawValue in unknownItems)

+                  if (rawValue is int)

+                    unknownFields.MergeVarintField(52, (ulong)(int)rawValue);

               }

               break;

             }

             case 424: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ImportEnum), rawValue)) {

+              scg::ICollection<object> unknownItems;

+              input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.ImportEnum>(tag, field_name, result.repeatedImportEnum_, out unknownItems);

+              if (unknownItems != null) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(53, (ulong) rawValue);

-              } else {

-                AddRepeatedImportEnum((global::Google.ProtocolBuffers.TestProtos.ImportEnum) rawValue);

+                foreach (object rawValue in unknownItems)

+                  if (rawValue is int)

+                    unknownFields.MergeVarintField(53, (ulong)(int)rawValue);

               }

               break;

             }

             case 434: {

-              AddRepeatedStringPiece(input.ReadString());

+              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedStringPiece_);

               break;

             }

             case 442: {

-              AddRepeatedCord(input.ReadString());

+              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedCord_);

               break;

             }

             case 488: {

-              DefaultInt32 = input.ReadInt32();

+              result.hasDefaultInt32 |= input.ReadInt32(ref result.defaultInt32_);

               break;

             }

             case 496: {

-              DefaultInt64 = input.ReadInt64();

+              result.hasDefaultInt64 |= input.ReadInt64(ref result.defaultInt64_);

               break;

             }

             case 504: {

-              DefaultUint32 = input.ReadUInt32();

+              result.hasDefaultUint32 |= input.ReadUInt32(ref result.defaultUint32_);

               break;

             }

             case 512: {

-              DefaultUint64 = input.ReadUInt64();

+              result.hasDefaultUint64 |= input.ReadUInt64(ref result.defaultUint64_);

               break;

             }

             case 520: {

-              DefaultSint32 = input.ReadSInt32();

+              result.hasDefaultSint32 |= input.ReadSInt32(ref result.defaultSint32_);

               break;

             }

             case 528: {

-              DefaultSint64 = input.ReadSInt64();

+              result.hasDefaultSint64 |= input.ReadSInt64(ref result.defaultSint64_);

               break;

             }

             case 541: {

-              DefaultFixed32 = input.ReadFixed32();

+              result.hasDefaultFixed32 |= input.ReadFixed32(ref result.defaultFixed32_);

               break;

             }

             case 545: {

-              DefaultFixed64 = input.ReadFixed64();

+              result.hasDefaultFixed64 |= input.ReadFixed64(ref result.defaultFixed64_);

               break;

             }

             case 557: {

-              DefaultSfixed32 = input.ReadSFixed32();

+              result.hasDefaultSfixed32 |= input.ReadSFixed32(ref result.defaultSfixed32_);

               break;

             }

             case 561: {

-              DefaultSfixed64 = input.ReadSFixed64();

+              result.hasDefaultSfixed64 |= input.ReadSFixed64(ref result.defaultSfixed64_);

               break;

             }

             case 573: {

-              DefaultFloat = input.ReadFloat();

+              result.hasDefaultFloat |= input.ReadFloat(ref result.defaultFloat_);

               break;

             }

             case 577: {

-              DefaultDouble = input.ReadDouble();

+              result.hasDefaultDouble |= input.ReadDouble(ref result.defaultDouble_);

               break;

             }

             case 584: {

-              DefaultBool = input.ReadBool();

+              result.hasDefaultBool |= input.ReadBool(ref result.defaultBool_);

               break;

             }

             case 594: {

-              DefaultString = input.ReadString();

+              result.hasDefaultString |= input.ReadString(ref result.defaultString_);

               break;

             }

             case 602: {

-              DefaultBytes = input.ReadBytes();

+              result.hasDefaultBytes |= input.ReadBytes(ref result.defaultBytes_);

               break;

             }

             case 648: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum), rawValue)) {

+              object unknown;

+              if(input.ReadEnum(ref result.defaultNestedEnum_, out unknown)) {

+                result.hasDefaultNestedEnum = true;

+              } else if(unknown is int) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(81, (ulong) rawValue);

-              } else {

-                DefaultNestedEnum = (global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum) rawValue;

+                unknownFields.MergeVarintField(81, (ulong)(int)unknown);

               }

               break;

             }

             case 656: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnum), rawValue)) {

+              object unknown;

+              if(input.ReadEnum(ref result.defaultForeignEnum_, out unknown)) {

+                result.hasDefaultForeignEnum = true;

+              } else if(unknown is int) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(82, (ulong) rawValue);

-              } else {

-                DefaultForeignEnum = (global::Google.ProtocolBuffers.TestProtos.ForeignEnum) rawValue;

+                unknownFields.MergeVarintField(82, (ulong)(int)unknown);

               }

               break;

             }

             case 664: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ImportEnum), rawValue)) {

+              object unknown;

+              if(input.ReadEnum(ref result.defaultImportEnum_, out unknown)) {

+                result.hasDefaultImportEnum = true;

+              } else if(unknown is int) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(83, (ulong) rawValue);

-              } else {

-                DefaultImportEnum = (global::Google.ProtocolBuffers.TestProtos.ImportEnum) rawValue;

+                unknownFields.MergeVarintField(83, (ulong)(int)unknown);

               }

               break;

             }

             case 674: {

-              DefaultStringPiece = input.ReadString();

+              result.hasDefaultStringPiece |= input.ReadString(ref result.defaultStringPiece_);

               break;

             }

             case 682: {

-              DefaultCord = input.ReadString();

+              result.hasDefaultCord |= input.ReadString(ref result.defaultCord_);

               break;

             }

           }

@@ -5511,11 +5506,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              DeprecatedInt32 = input.ReadInt32();

+              result.hasDeprecatedInt32 |= input.ReadInt32(ref result.deprecatedInt32_);

               break;

             }

           }

@@ -5735,11 +5730,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              C = input.ReadInt32();

+              result.hasC |= input.ReadInt32(ref result.c_);

               break;

             }

           }

@@ -5945,7 +5940,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -6147,11 +6142,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 136: {

-              A = input.ReadInt32();

+              result.hasA |= input.ReadInt32(ref result.a_);

               break;

             }

           }

@@ -6371,11 +6366,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 376: {

-              A = input.ReadInt32();

+              result.hasA |= input.ReadInt32(ref result.a_);

               break;

             }

           }

@@ -6578,7 +6573,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -7395,139 +7390,139 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              A = input.ReadInt32();

+              result.hasA |= input.ReadInt32(ref result.a_);

               break;

             }

             case 16: {

-              Dummy2 = input.ReadInt32();

+              result.hasDummy2 |= input.ReadInt32(ref result.dummy2_);

               break;

             }

             case 24: {

-              B = input.ReadInt32();

+              result.hasB |= input.ReadInt32(ref result.b_);

               break;

             }

             case 32: {

-              Dummy4 = input.ReadInt32();

+              result.hasDummy4 |= input.ReadInt32(ref result.dummy4_);

               break;

             }

             case 40: {

-              Dummy5 = input.ReadInt32();

+              result.hasDummy5 |= input.ReadInt32(ref result.dummy5_);

               break;

             }

             case 48: {

-              Dummy6 = input.ReadInt32();

+              result.hasDummy6 |= input.ReadInt32(ref result.dummy6_);

               break;

             }

             case 56: {

-              Dummy7 = input.ReadInt32();

+              result.hasDummy7 |= input.ReadInt32(ref result.dummy7_);

               break;

             }

             case 64: {

-              Dummy8 = input.ReadInt32();

+              result.hasDummy8 |= input.ReadInt32(ref result.dummy8_);

               break;

             }

             case 72: {

-              Dummy9 = input.ReadInt32();

+              result.hasDummy9 |= input.ReadInt32(ref result.dummy9_);

               break;

             }

             case 80: {

-              Dummy10 = input.ReadInt32();

+              result.hasDummy10 |= input.ReadInt32(ref result.dummy10_);

               break;

             }

             case 88: {

-              Dummy11 = input.ReadInt32();

+              result.hasDummy11 |= input.ReadInt32(ref result.dummy11_);

               break;

             }

             case 96: {

-              Dummy12 = input.ReadInt32();

+              result.hasDummy12 |= input.ReadInt32(ref result.dummy12_);

               break;

             }

             case 104: {

-              Dummy13 = input.ReadInt32();

+              result.hasDummy13 |= input.ReadInt32(ref result.dummy13_);

               break;

             }

             case 112: {

-              Dummy14 = input.ReadInt32();

+              result.hasDummy14 |= input.ReadInt32(ref result.dummy14_);

               break;

             }

             case 120: {

-              Dummy15 = input.ReadInt32();

+              result.hasDummy15 |= input.ReadInt32(ref result.dummy15_);

               break;

             }

             case 128: {

-              Dummy16 = input.ReadInt32();

+              result.hasDummy16 |= input.ReadInt32(ref result.dummy16_);

               break;

             }

             case 136: {

-              Dummy17 = input.ReadInt32();

+              result.hasDummy17 |= input.ReadInt32(ref result.dummy17_);

               break;

             }

             case 144: {

-              Dummy18 = input.ReadInt32();

+              result.hasDummy18 |= input.ReadInt32(ref result.dummy18_);

               break;

             }

             case 152: {

-              Dummy19 = input.ReadInt32();

+              result.hasDummy19 |= input.ReadInt32(ref result.dummy19_);

               break;

             }

             case 160: {

-              Dummy20 = input.ReadInt32();

+              result.hasDummy20 |= input.ReadInt32(ref result.dummy20_);

               break;

             }

             case 168: {

-              Dummy21 = input.ReadInt32();

+              result.hasDummy21 |= input.ReadInt32(ref result.dummy21_);

               break;

             }

             case 176: {

-              Dummy22 = input.ReadInt32();

+              result.hasDummy22 |= input.ReadInt32(ref result.dummy22_);

               break;

             }

             case 184: {

-              Dummy23 = input.ReadInt32();

+              result.hasDummy23 |= input.ReadInt32(ref result.dummy23_);

               break;

             }

             case 192: {

-              Dummy24 = input.ReadInt32();

+              result.hasDummy24 |= input.ReadInt32(ref result.dummy24_);

               break;

             }

             case 200: {

-              Dummy25 = input.ReadInt32();

+              result.hasDummy25 |= input.ReadInt32(ref result.dummy25_);

               break;

             }

             case 208: {

-              Dummy26 = input.ReadInt32();

+              result.hasDummy26 |= input.ReadInt32(ref result.dummy26_);

               break;

             }

             case 216: {

-              Dummy27 = input.ReadInt32();

+              result.hasDummy27 |= input.ReadInt32(ref result.dummy27_);

               break;

             }

             case 224: {

-              Dummy28 = input.ReadInt32();

+              result.hasDummy28 |= input.ReadInt32(ref result.dummy28_);

               break;

             }

             case 232: {

-              Dummy29 = input.ReadInt32();

+              result.hasDummy29 |= input.ReadInt32(ref result.dummy29_);

               break;

             }

             case 240: {

-              Dummy30 = input.ReadInt32();

+              result.hasDummy30 |= input.ReadInt32(ref result.dummy30_);

               break;

             }

             case 248: {

-              Dummy31 = input.ReadInt32();

+              result.hasDummy31 |= input.ReadInt32(ref result.dummy31_);

               break;

             }

             case 256: {

-              Dummy32 = input.ReadInt32();

+              result.hasDummy32 |= input.ReadInt32(ref result.dummy32_);

               break;

             }

             case 264: {

-              C = input.ReadInt32();

+              result.hasC |= input.ReadInt32(ref result.c_);

               break;

             }

           }

@@ -8370,7 +8365,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

@@ -8383,13 +8378,11 @@
               break;

             }

             case 18: {

-              global::Google.ProtocolBuffers.TestProtos.TestRequired.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestRequired.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddRepeatedMessage(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.repeatedMessage_, global::Google.ProtocolBuffers.TestProtos.TestRequired.DefaultInstance, extensionRegistry);

               break;

             }

             case 24: {

-              Dummy = input.ReadInt32();

+              result.hasDummy |= input.ReadInt32(ref result.dummy_);

               break;

             }

           }

@@ -8683,7 +8676,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

@@ -8911,7 +8904,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -9099,7 +9092,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -9289,7 +9282,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -9510,15 +9503,15 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              A = input.ReadInt32();

+              result.hasA |= input.ReadInt32(ref result.a_);

               break;

             }

             case 2147483640: {

-              Bb = input.ReadInt32();

+              result.hasBb |= input.ReadInt32(ref result.bb_);

               break;

             }

           }

@@ -9775,7 +9768,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

@@ -9788,7 +9781,7 @@
               break;

             }

             case 16: {

-              I = input.ReadInt32();

+              result.hasI |= input.ReadInt32(ref result.i_);

               break;

             }

           }

@@ -10044,7 +10037,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

@@ -10310,7 +10303,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

@@ -10323,7 +10316,7 @@
               break;

             }

             case 16: {

-              OptionalInt32 = input.ReadInt32();

+              result.hasOptionalInt32 |= input.ReadInt32(ref result.optionalInt32_);

               break;

             }

           }

@@ -10609,11 +10602,11 @@
                   if (unknownFields == null) {

                     unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                   }

-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 8: {

-                  A = input.ReadInt32();

+                  result.hasA |= input.ReadInt32(ref result.a_);

                   break;

                 }

               }

@@ -10833,11 +10826,11 @@
                   if (unknownFields == null) {

                     unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                   }

-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 8: {

-                  A = input.ReadInt32();

+                  result.hasA |= input.ReadInt32(ref result.a_);

                   break;

                 }

               }

@@ -11073,11 +11066,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              A = input.ReadInt32();

+              result.hasA |= input.ReadInt32(ref result.a_);

               break;

             }

             case 19: {

@@ -11447,17 +11440,15 @@
                   if (unknownFields == null) {

                     unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                   }

-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 8: {

-                  AddNestedmessageRepeatedInt32(input.ReadInt32());

+                  input.ReadPrimitiveArray(pbd::FieldType.Int32, tag, field_name, result.nestedmessageRepeatedInt32_);

                   break;

                 }

                 case 18: {

-                  global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.ForeignMessage.CreateBuilder();

-                  input.ReadMessage(subBuilder, extensionRegistry);

-                  AddNestedmessageRepeatedForeignmessage(subBuilder.BuildPartial());

+                  input.ReadMessageArray(tag, field_name, result.nestedmessageRepeatedForeignmessage_, global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance, extensionRegistry);

                   break;

                 }

               }

@@ -11701,7 +11692,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

@@ -12202,26 +12193,26 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              PrimitiveField = input.ReadInt32();

+              result.hasPrimitiveField |= input.ReadInt32(ref result.primitiveField_);

               break;

             }

             case 18: {

-              StringField = input.ReadString();

+              result.hasStringField |= input.ReadString(ref result.stringField_);

               break;

             }

             case 24: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnum), rawValue)) {

+              object unknown;

+              if(input.ReadEnum(ref result.enumField_, out unknown)) {

+                result.hasEnumField = true;

+              } else if(unknown is int) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(3, (ulong) rawValue);

-              } else {

-                EnumField = (global::Google.ProtocolBuffers.TestProtos.ForeignEnum) rawValue;

+                unknownFields.MergeVarintField(3, (ulong)(int)unknown);

               }

               break;

             }

@@ -12235,45 +12226,44 @@
               break;

             }

             case 42: {

-              StringPieceField = input.ReadString();

+              result.hasStringPieceField |= input.ReadString(ref result.stringPieceField_);

               break;

             }

             case 50: {

-              CordField = input.ReadString();

+              result.hasCordField |= input.ReadString(ref result.cordField_);

               break;

             }

             case 56: {

-              AddRepeatedPrimitiveField(input.ReadInt32());

+              input.ReadPrimitiveArray(pbd::FieldType.Int32, tag, field_name, result.repeatedPrimitiveField_);

               break;

             }

             case 66: {

-              AddRepeatedStringField(input.ReadString());

+              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedStringField_);

               break;

             }

             case 72: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnum), rawValue)) {

+              scg::ICollection<object> unknownItems;

+              input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>(tag, field_name, result.repeatedEnumField_, out unknownItems);

+              if (unknownItems != null) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(9, (ulong) rawValue);

-              } else {

-                AddRepeatedEnumField((global::Google.ProtocolBuffers.TestProtos.ForeignEnum) rawValue);

+                foreach (object rawValue in unknownItems)

+                  if (rawValue is int)

+                    unknownFields.MergeVarintField(9, (ulong)(int)rawValue);

               }

               break;

             }

             case 82: {

-              global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.ForeignMessage.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddRepeatedMessageField(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.repeatedMessageField_, global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance, extensionRegistry);

               break;

             }

             case 90: {

-              AddRepeatedStringPieceField(input.ReadString());

+              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedStringPieceField_);

               break;

             }

             case 98: {

-              AddRepeatedCordField(input.ReadString());

+              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedCordField_);

               break;

             }

           }

@@ -12822,19 +12812,19 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              MyInt = input.ReadInt64();

+              result.hasMyInt |= input.ReadInt64(ref result.myInt_);

               break;

             }

             case 90: {

-              MyString = input.ReadString();

+              result.hasMyString |= input.ReadString(ref result.myString_);

               break;

             }

             case 813: {

-              MyFloat = input.ReadFloat();

+              result.hasMyFloat |= input.ReadFloat(ref result.myFloat_);

               break;

             }

           }

@@ -13435,83 +13425,83 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              EscapedBytes = input.ReadBytes();

+              result.hasEscapedBytes |= input.ReadBytes(ref result.escapedBytes_);

               break;

             }

             case 16: {

-              LargeUint32 = input.ReadUInt32();

+              result.hasLargeUint32 |= input.ReadUInt32(ref result.largeUint32_);

               break;

             }

             case 24: {

-              LargeUint64 = input.ReadUInt64();

+              result.hasLargeUint64 |= input.ReadUInt64(ref result.largeUint64_);

               break;

             }

             case 32: {

-              SmallInt32 = input.ReadInt32();

+              result.hasSmallInt32 |= input.ReadInt32(ref result.smallInt32_);

               break;

             }

             case 40: {

-              SmallInt64 = input.ReadInt64();

+              result.hasSmallInt64 |= input.ReadInt64(ref result.smallInt64_);

               break;

             }

             case 50: {

-              Utf8String = input.ReadString();

+              result.hasUtf8String |= input.ReadString(ref result.utf8String_);

               break;

             }

             case 61: {

-              ZeroFloat = input.ReadFloat();

+              result.hasZeroFloat |= input.ReadFloat(ref result.zeroFloat_);

               break;

             }

             case 69: {

-              OneFloat = input.ReadFloat();

+              result.hasOneFloat |= input.ReadFloat(ref result.oneFloat_);

               break;

             }

             case 77: {

-              SmallFloat = input.ReadFloat();

+              result.hasSmallFloat |= input.ReadFloat(ref result.smallFloat_);

               break;

             }

             case 85: {

-              NegativeOneFloat = input.ReadFloat();

+              result.hasNegativeOneFloat |= input.ReadFloat(ref result.negativeOneFloat_);

               break;

             }

             case 93: {

-              NegativeFloat = input.ReadFloat();

+              result.hasNegativeFloat |= input.ReadFloat(ref result.negativeFloat_);

               break;

             }

             case 101: {

-              LargeFloat = input.ReadFloat();

+              result.hasLargeFloat |= input.ReadFloat(ref result.largeFloat_);

               break;

             }

             case 109: {

-              SmallNegativeFloat = input.ReadFloat();

+              result.hasSmallNegativeFloat |= input.ReadFloat(ref result.smallNegativeFloat_);

               break;

             }

             case 113: {

-              InfDouble = input.ReadDouble();

+              result.hasInfDouble |= input.ReadDouble(ref result.infDouble_);

               break;

             }

             case 121: {

-              NegInfDouble = input.ReadDouble();

+              result.hasNegInfDouble |= input.ReadDouble(ref result.negInfDouble_);

               break;

             }

             case 129: {

-              NanDouble = input.ReadDouble();

+              result.hasNanDouble |= input.ReadDouble(ref result.nanDouble_);

               break;

             }

             case 141: {

-              InfFloat = input.ReadFloat();

+              result.hasInfFloat |= input.ReadFloat(ref result.infFloat_);

               break;

             }

             case 149: {

-              NegInfFloat = input.ReadFloat();

+              result.hasNegInfFloat |= input.ReadFloat(ref result.negInfFloat_);

               break;

             }

             case 157: {

-              NanFloat = input.ReadFloat();

+              result.hasNanFloat |= input.ReadFloat(ref result.nanFloat_);

               break;

             }

           }

@@ -14061,11 +14051,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              Data = input.ReadString();

+              result.hasData |= input.ReadString(ref result.data_);

               break;

             }

           }

@@ -14286,11 +14276,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              Data = input.ReadBytes();

+              result.hasData |= input.ReadBytes(ref result.data_);

               break;

             }

           }

@@ -14921,141 +14911,72 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 722: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedInt32(input.ReadInt32());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.Int32, tag, field_name, result.packedInt32_);

               break;

             }

             case 730: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedInt64(input.ReadInt64());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.Int64, tag, field_name, result.packedInt64_);

               break;

             }

             case 738: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedUint32(input.ReadUInt32());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.UInt32, tag, field_name, result.packedUint32_);

               break;

             }

             case 746: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedUint64(input.ReadUInt64());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.UInt64, tag, field_name, result.packedUint64_);

               break;

             }

             case 754: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedSint32(input.ReadSInt32());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.SInt32, tag, field_name, result.packedSint32_);

               break;

             }

             case 762: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedSint64(input.ReadSInt64());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.SInt64, tag, field_name, result.packedSint64_);

               break;

             }

             case 770: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedFixed32(input.ReadFixed32());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.Fixed32, tag, field_name, result.packedFixed32_);

               break;

             }

             case 778: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedFixed64(input.ReadFixed64());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.Fixed64, tag, field_name, result.packedFixed64_);

               break;

             }

             case 786: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedSfixed32(input.ReadSFixed32());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.SFixed32, tag, field_name, result.packedSfixed32_);

               break;

             }

             case 794: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedSfixed64(input.ReadSFixed64());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.SFixed64, tag, field_name, result.packedSfixed64_);

               break;

             }

             case 802: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedFloat(input.ReadFloat());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.Float, tag, field_name, result.packedFloat_);

               break;

             }

             case 810: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedDouble(input.ReadDouble());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.Double, tag, field_name, result.packedDouble_);

               break;

             }

             case 818: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedBool(input.ReadBool());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.Bool, tag, field_name, result.packedBool_);

               break;

             }

             case 826: {

-              int length = input.ReadInt32();

-              int oldLimit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                int rawValue = input.ReadEnum();

-                if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnum), rawValue)) {

-                  if (unknownFields == null) {

-                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

-                  }

-                  unknownFields.MergeVarintField(103, (ulong) rawValue);

-                } else {

-                  AddPackedEnum((global::Google.ProtocolBuffers.TestProtos.ForeignEnum) rawValue);

+              scg::ICollection<object> unknownItems;

+              input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>(tag, field_name, result.packedEnum_, out unknownItems);

+              if (unknownItems != null) {

+                if (unknownFields == null) {

+                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

+                foreach (object rawValue in unknownItems)

+                  if (rawValue is int)

+                    unknownFields.MergeVarintField(103, (ulong)(int)rawValue);

               }

-              input.PopLimit(oldLimit);

               break;

             }

           }

@@ -15996,70 +15917,71 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 720: {

-              AddUnpackedInt32(input.ReadInt32());

+              input.ReadPrimitiveArray(pbd::FieldType.Int32, tag, field_name, result.unpackedInt32_);

               break;

             }

             case 728: {

-              AddUnpackedInt64(input.ReadInt64());

+              input.ReadPrimitiveArray(pbd::FieldType.Int64, tag, field_name, result.unpackedInt64_);

               break;

             }

             case 736: {

-              AddUnpackedUint32(input.ReadUInt32());

+              input.ReadPrimitiveArray(pbd::FieldType.UInt32, tag, field_name, result.unpackedUint32_);

               break;

             }

             case 744: {

-              AddUnpackedUint64(input.ReadUInt64());

+              input.ReadPrimitiveArray(pbd::FieldType.UInt64, tag, field_name, result.unpackedUint64_);

               break;

             }

             case 752: {

-              AddUnpackedSint32(input.ReadSInt32());

+              input.ReadPrimitiveArray(pbd::FieldType.SInt32, tag, field_name, result.unpackedSint32_);

               break;

             }

             case 760: {

-              AddUnpackedSint64(input.ReadSInt64());

+              input.ReadPrimitiveArray(pbd::FieldType.SInt64, tag, field_name, result.unpackedSint64_);

               break;

             }

             case 773: {

-              AddUnpackedFixed32(input.ReadFixed32());

+              input.ReadPrimitiveArray(pbd::FieldType.Fixed32, tag, field_name, result.unpackedFixed32_);

               break;

             }

             case 777: {

-              AddUnpackedFixed64(input.ReadFixed64());

+              input.ReadPrimitiveArray(pbd::FieldType.Fixed64, tag, field_name, result.unpackedFixed64_);

               break;

             }

             case 789: {

-              AddUnpackedSfixed32(input.ReadSFixed32());

+              input.ReadPrimitiveArray(pbd::FieldType.SFixed32, tag, field_name, result.unpackedSfixed32_);

               break;

             }

             case 793: {

-              AddUnpackedSfixed64(input.ReadSFixed64());

+              input.ReadPrimitiveArray(pbd::FieldType.SFixed64, tag, field_name, result.unpackedSfixed64_);

               break;

             }

             case 805: {

-              AddUnpackedFloat(input.ReadFloat());

+              input.ReadPrimitiveArray(pbd::FieldType.Float, tag, field_name, result.unpackedFloat_);

               break;

             }

             case 809: {

-              AddUnpackedDouble(input.ReadDouble());

+              input.ReadPrimitiveArray(pbd::FieldType.Double, tag, field_name, result.unpackedDouble_);

               break;

             }

             case 816: {

-              AddUnpackedBool(input.ReadBool());

+              input.ReadPrimitiveArray(pbd::FieldType.Bool, tag, field_name, result.unpackedBool_);

               break;

             }

             case 824: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnum), rawValue)) {

+              scg::ICollection<object> unknownItems;

+              input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>(tag, field_name, result.unpackedEnum_, out unknownItems);

+              if (unknownItems != null) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(103, (ulong) rawValue);

-              } else {

-                AddUnpackedEnum((global::Google.ProtocolBuffers.TestProtos.ForeignEnum) rawValue);

+                foreach (object rawValue in unknownItems)

+                  if (rawValue is int)

+                    unknownFields.MergeVarintField(103, (ulong)(int)rawValue);

               }

               break;

             }

@@ -16632,7 +16554,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -16872,11 +16794,11 @@
                   if (unknownFields == null) {

                     unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                   }

-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 16800: {

-                  DynamicField = input.ReadInt32();

+                  result.hasDynamicField |= input.ReadInt32(ref result.dynamicField_);

                   break;

                 }

               }

@@ -17209,34 +17131,34 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 16005: {

-              ScalarExtension = input.ReadFixed32();

+              result.hasScalarExtension |= input.ReadFixed32(ref result.scalarExtension_);

               break;

             }

             case 16008: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnum), rawValue)) {

+              object unknown;

+              if(input.ReadEnum(ref result.enumExtension_, out unknown)) {

+                result.hasEnumExtension = true;

+              } else if(unknown is int) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(2001, (ulong) rawValue);

-              } else {

-                EnumExtension = (global::Google.ProtocolBuffers.TestProtos.ForeignEnum) rawValue;

+                unknownFields.MergeVarintField(2001, (ulong)(int)unknown);

               }

               break;

             }

             case 16016: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicEnumType), rawValue)) {

+              object unknown;

+              if(input.ReadEnum(ref result.dynamicEnumExtension_, out unknown)) {

+                result.hasDynamicEnumExtension = true;

+              } else if(unknown is int) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(2002, (ulong) rawValue);

-              } else {

-                DynamicEnumExtension = (global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicEnumType) rawValue;

+                unknownFields.MergeVarintField(2002, (ulong)(int)unknown);

               }

               break;

             }

@@ -17259,16 +17181,11 @@
               break;

             }

             case 16042: {

-              AddRepeatedExtension(input.ReadString());

+              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedExtension_);

               break;

             }

             case 16050: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedExtension(input.ReadSInt32());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.SInt32, tag, field_name, result.packedExtension_);

               break;

             }

           }

@@ -17795,31 +17712,31 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 101: {

-              AddRepeatedFixed32(input.ReadFixed32());

+              input.ReadPrimitiveArray(pbd::FieldType.Fixed32, tag, field_name, result.repeatedFixed32_);

               break;

             }

             case 104: {

-              AddRepeatedInt32(input.ReadInt32());

+              input.ReadPrimitiveArray(pbd::FieldType.Int32, tag, field_name, result.repeatedInt32_);

               break;

             }

             case 16369: {

-              AddRepeatedFixed64(input.ReadFixed64());

+              input.ReadPrimitiveArray(pbd::FieldType.Fixed64, tag, field_name, result.repeatedFixed64_);

               break;

             }

             case 16376: {

-              AddRepeatedInt64(input.ReadInt64());

+              input.ReadPrimitiveArray(pbd::FieldType.Int64, tag, field_name, result.repeatedInt64_);

               break;

             }

             case 2097141: {

-              AddRepeatedFloat(input.ReadFloat());

+              input.ReadPrimitiveArray(pbd::FieldType.Float, tag, field_name, result.repeatedFloat_);

               break;

             }

             case 2097144: {

-              AddRepeatedUint64(input.ReadUInt64());

+              input.ReadPrimitiveArray(pbd::FieldType.UInt64, tag, field_name, result.repeatedUint64_);

               break;

             }

           }

@@ -18173,7 +18090,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -18356,7 +18273,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -18539,7 +18456,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -18722,7 +18639,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

diff --git a/src/ProtocolBuffers.Test/TestProtos/UnitTestRpcInterop.cs b/src/ProtocolBuffers.Test/TestProtos/UnitTestRpcInterop.cs
index b4f7a51..58ceef7 100644
--- a/src/ProtocolBuffers.Test/TestProtos/UnitTestRpcInterop.cs
+++ b/src/ProtocolBuffers.Test/TestProtos/UnitTestRpcInterop.cs
@@ -269,11 +269,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              AddCriteria(input.ReadString());

+              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.criteria_);

               break;

             }

           }

@@ -553,15 +553,15 @@
                   if (unknownFields == null) {

                     unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                   }

-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 10: {

-                  Url = input.ReadString();

+                  result.hasUrl |= input.ReadString(ref result.url_);

                   break;

                 }

                 case 18: {

-                  Name = input.ReadString();

+                  result.hasName |= input.ReadString(ref result.name_);

                   break;

                 }

               }

@@ -785,13 +785,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              global::Google.ProtocolBuffers.TestProtos.SearchResponse.Types.ResultItem.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.SearchResponse.Types.ResultItem.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddResults(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.results_, global::Google.ProtocolBuffers.TestProtos.SearchResponse.Types.ResultItem.DefaultInstance, extensionRegistry);

               break;

             }

           }

@@ -1060,11 +1058,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              AddCriteria(input.ReadString());

+              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.criteria_);

               break;

             }

             case 18: {

diff --git a/src/ProtocolBuffers.Test/TestProtos/UnitTestXmlSerializerTestProtoFile.cs b/src/ProtocolBuffers.Test/TestProtos/UnitTestXmlSerializerTestProtoFile.cs
index 1b523c3..2476cf1 100644
--- a/src/ProtocolBuffers.Test/TestProtos/UnitTestXmlSerializerTestProtoFile.cs
+++ b/src/ProtocolBuffers.Test/TestProtos/UnitTestXmlSerializerTestProtoFile.cs
@@ -337,23 +337,24 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 24: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.EnumOptions), rawValue)) {

+              scg::ICollection<object> unknownItems;

+              input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.EnumOptions>(tag, field_name, result.options_, out unknownItems);

+              if (unknownItems != null) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(3, (ulong) rawValue);

-              } else {

-                AddOptions((global::Google.ProtocolBuffers.TestProtos.EnumOptions) rawValue);

+                foreach (object rawValue in unknownItems)

+                  if (rawValue is int)

+                    unknownFields.MergeVarintField(3, (ulong)(int)rawValue);

               }

               break;

             }

             case 34: {

-              Binary = input.ReadBytes();

+              result.hasBinary |= input.ReadBytes(ref result.binary_);

               break;

             }

           }

@@ -581,7 +582,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -842,23 +843,24 @@
                   if (unknownFields == null) {

                     unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                   }

-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 24: {

-                  int rawValue = input.ReadEnum();

-                  if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.EnumOptions), rawValue)) {

+                  scg::ICollection<object> unknownItems;

+                  input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.EnumOptions>(tag, field_name, result.options_, out unknownItems);

+                  if (unknownItems != null) {

                     if (unknownFields == null) {

                       unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                     }

-                    unknownFields.MergeVarintField(3, (ulong) rawValue);

-                  } else {

-                    AddOptions((global::Google.ProtocolBuffers.TestProtos.EnumOptions) rawValue);

+                    foreach (object rawValue in unknownItems)

+                      if (rawValue is int)

+                        unknownFields.MergeVarintField(3, (ulong)(int)rawValue);

                   }

                   break;

                 }

                 case 34: {

-                  Binary = input.ReadBytes();

+                  result.hasBinary |= input.ReadBytes(ref result.binary_);

                   break;

                 }

               }

@@ -1221,7 +1223,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

@@ -1234,29 +1236,27 @@
               break;

             }

             case 16: {

-              AddNumbers(input.ReadInt32());

+              input.ReadPrimitiveArray(pbd::FieldType.Int32, tag, field_name, result.numbers_);

               break;

             }

             case 26: {

-              Text = input.ReadString();

+              result.hasText |= input.ReadString(ref result.text_);

               break;

             }

             case 40: {

-              Valid = input.ReadBool();

+              result.hasValid |= input.ReadBool(ref result.valid_);

               break;

             }

             case 48: {

-              Number = input.ReadInt64();

+              result.hasNumber |= input.ReadInt64(ref result.number_);

               break;

             }

             case 3211: {

-              global::Google.ProtocolBuffers.TestProtos.TestXmlMessage.Types.Children.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestXmlMessage.Types.Children.CreateBuilder();

-              input.ReadGroup(401, subBuilder, extensionRegistry);

-              AddChildren(subBuilder.BuildPartial());

+              input.ReadGroupArray(tag, field_name, result.children_, global::Google.ProtocolBuffers.TestProtos.TestXmlMessage.Types.Children.DefaultInstance, extensionRegistry);

               break;

             }

             case 5602: {

-              AddTextlines(input.ReadString());

+              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.textlines_);

               break;

             }

           }

@@ -1642,11 +1642,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              Number = input.ReadInt32();

+              result.hasNumber |= input.ReadInt32(ref result.number_);

               break;

             }

           }

diff --git a/src/ProtocolBuffers/CodedInputStream.cs b/src/ProtocolBuffers/CodedInputStream.cs
index 33986d3..92e547f 100644
--- a/src/ProtocolBuffers/CodedInputStream.cs
+++ b/src/ProtocolBuffers/CodedInputStream.cs
@@ -201,88 +201,100 @@
         /// <summary>

         /// Read a double field from the stream.

         /// </summary>

-        public double ReadDouble()

+        public bool ReadDouble(ref double value)

         {

 #if SILVERLIGHT2 || COMPACT_FRAMEWORK_35

-            byte[] bytes = ReadRawBytes(8);

-            return BitConverter.ToDouble(bytes, 0);

+            byte[] rawBytes = ReadRawBytes(8);

+            if (!BitConverter.IsLittleEndian) 

+                Array.Reverse(rawBytes);

+            value = BitConverter.ToDouble(rawBytes, 0);

+            return true;

 #else

-      return BitConverter.Int64BitsToDouble((long) ReadRawLittleEndian64());

+            value = BitConverter.Int64BitsToDouble((long) ReadRawLittleEndian64());

+            return true;

 #endif

         }

 

         /// <summary>

         /// Read a float field from the stream.

         /// </summary>

-        public float ReadFloat()

+        public bool ReadFloat(ref float value)

         {

-            // TODO(jonskeet): Test this on different endiannesses

-            uint raw = ReadRawLittleEndian32();

-            byte[] rawBytes = BitConverter.GetBytes(raw);

-            return BitConverter.ToSingle(rawBytes, 0);

+            byte[] rawBytes = ReadRawBytes(4);

+            if (!BitConverter.IsLittleEndian)

+                Array.Reverse(rawBytes);

+            value = BitConverter.ToSingle(rawBytes, 0);

+            return true;

         }

 

         /// <summary>

         /// Read a uint64 field from the stream.

         /// </summary>

         [CLSCompliant(false)]

-        public ulong ReadUInt64()

+        public bool ReadUInt64(ref ulong value)

         {

-            return ReadRawVarint64();

+            value = ReadRawVarint64();

+            return true;

         }

 

         /// <summary>

         /// Read an int64 field from the stream.

         /// </summary>

-        public long ReadInt64()

+        public bool ReadInt64(ref long value)

         {

-            return (long) ReadRawVarint64();

+            value = (long) ReadRawVarint64();

+            return true;

         }

 

         /// <summary>

         /// Read an int32 field from the stream.

         /// </summary>

-        public int ReadInt32()

+        public bool ReadInt32(ref int value)

         {

-            return (int) ReadRawVarint32();

+            value = (int)ReadRawVarint32();

+            return true;

         }

 

         /// <summary>

         /// Read a fixed64 field from the stream.

         /// </summary>

         [CLSCompliant(false)]

-        public ulong ReadFixed64()

+        public bool ReadFixed64(ref ulong value)

         {

-            return ReadRawLittleEndian64();

+            value = ReadRawLittleEndian64();

+            return true;

         }

 

         /// <summary>

         /// Read a fixed32 field from the stream.

         /// </summary>

         [CLSCompliant(false)]

-        public uint ReadFixed32()

+        public bool ReadFixed32(ref uint value)

         {

-            return ReadRawLittleEndian32();

+            value = ReadRawLittleEndian32();

+            return true;

         }

 

         /// <summary>

         /// Read a bool field from the stream.

         /// </summary>

-        public bool ReadBool()

+        public bool ReadBool(ref bool value)

         {

-            return ReadRawVarint32() != 0;

+            value = ReadRawVarint32() != 0;

+            return true;

         }

 

         /// <summary>

         /// Reads a string field from the stream.

         /// </summary>

-        public String ReadString()

+        public bool ReadString(ref string value)

         {

             int size = (int) ReadRawVarint32();

             // No need to read any data for an empty string.

             if (size == 0)

             {

-                return "";

+                value = "";

+                return true;

             }

             if (size <= bufferSize - bufferPos)

             {

@@ -290,10 +302,12 @@
                 //   just copy directly from it.

                 String result = Encoding.UTF8.GetString(buffer, bufferPos, size);

                 bufferPos += size;

-                return result;

+                value = result;

+                return true;

             }

             // Slow path: Build a byte array first then copy it.

-            return Encoding.UTF8.GetString(ReadRawBytes(size), 0, size);

+            value = Encoding.UTF8.GetString(ReadRawBytes(size), 0, size);

+            return true;

         }

 

         /// <summary>

@@ -350,7 +364,7 @@
         /// <summary>

         /// Reads a bytes field value from the stream.

         /// </summary>   

-        public ByteString ReadBytes()

+        public bool ReadBytes(ref ByteString value)

         {

             int size = (int) ReadRawVarint32();

             if (size < bufferSize - bufferPos && size > 0)

@@ -359,12 +373,14 @@
                 //   just copy directly from it.

                 ByteString result = ByteString.CopyFrom(buffer, bufferPos, size);

                 bufferPos += size;

-                return result;

+                value = result;

+                return true;

             }

             else

             {

                 // Slow path:  Build a byte array first then copy it.

-                return ByteString.AttachBytes(ReadRawBytes(size));

+                value = ByteString.AttachBytes(ReadRawBytes(size));

+                return true;

             }

         }

 

@@ -372,90 +388,358 @@
         /// Reads a uint32 field value from the stream.

         /// </summary>   

         [CLSCompliant(false)]

-        public uint ReadUInt32()

+        public bool ReadUInt32(ref uint value)

         {

-            return ReadRawVarint32();

+            value = ReadRawVarint32();

+            return true;

         }

 

         /// <summary>

         /// Reads an enum field value from the stream. The caller is responsible

         /// for converting the numeric value to an actual enum.

         /// </summary>   

-        public int ReadEnum()

+        public bool ReadEnum(ref IEnumLite value, out object unknown, IEnumLiteMap mapping)

         {

-            return (int) ReadRawVarint32();

+            int rawValue = (int)ReadRawVarint32();

+            

+            value = mapping.FindValueByNumber(rawValue);

+            if (value != null)

+            {

+                unknown = null;

+                return true;

+            }

+            unknown = rawValue;

+            return false;

+        }

+

+        /// <summary>

+        /// Reads an enum field value from the stream. If the enum is valid for type T,

+        /// then the ref value is set and it returns true.  Otherwise the unkown output

+        /// value is set and this method returns false.

+        /// </summary>   

+        [CLSCompliant(false)]

+        public bool ReadEnum<T>(ref T value, out object unknown)

+            where T : struct, IComparable, IFormattable, IConvertible

+        {

+            int number = (int)ReadRawVarint32();

+            if (Enum.IsDefined(typeof(T), number))

+            {

+                unknown = null;

+                value = (T)(object)number;

+                return true;

+            }

+            unknown = number;

+            return false;

         }

 

         /// <summary>

         /// Reads an sfixed32 field value from the stream.

         /// </summary>   

-        public int ReadSFixed32()

+        public bool ReadSFixed32(ref int value)

         {

-            return (int) ReadRawLittleEndian32();

+            value = (int)ReadRawLittleEndian32();

+            return true;

         }

 

         /// <summary>

         /// Reads an sfixed64 field value from the stream.

         /// </summary>   

-        public long ReadSFixed64()

+        public bool ReadSFixed64(ref long value)

         {

-            return (long) ReadRawLittleEndian64();

+            value = (long)ReadRawLittleEndian64();

+            return true;

         }

 

         /// <summary>

         /// Reads an sint32 field value from the stream.

         /// </summary>   

-        public int ReadSInt32()

+        public bool ReadSInt32(ref int value)

         {

-            return DecodeZigZag32(ReadRawVarint32());

+            value = DecodeZigZag32(ReadRawVarint32());

+            return true;

         }

 

         /// <summary>

         /// Reads an sint64 field value from the stream.

         /// </summary>   

-        public long ReadSInt64()

+        public bool ReadSInt64(ref long value)

         {

-            return DecodeZigZag64(ReadRawVarint64());

+            value = DecodeZigZag64(ReadRawVarint64());

+            return true;

+        }

+

+        [CLSCompliant(false)]

+        public void ReadPrimitiveArray<T>(FieldType fieldType, uint fieldTag, string fieldName, ICollection<T> list)

+        {

+            WireFormat.WireType normal = WireFormat.GetWireType(fieldType);

+            WireFormat.WireType wformat = WireFormat.GetTagWireType(fieldTag);

+            

+            // 2.3 allows packed form even if the field is not declared packed.

+            if(normal != wformat && wformat == WireFormat.WireType.LengthDelimited)

+            {

+                int length = (int)(ReadRawVarint32() & int.MaxValue);

+                int limit = PushLimit(length);

+                while (!ReachedLimit)

+                {

+                    Object value = null;

+                    if(ReadPrimitiveField(fieldType, ref value))

+                        list.Add((T)value);

+                }

+                PopLimit(limit);

+            }

+            else

+            {

+                Object value = null;

+                if (ReadPrimitiveField(fieldType, ref value))

+                    list.Add((T)value);

+            }

+        }

+

+        [CLSCompliant(false)]

+        public void ReadEnumArray(uint fieldTag, string fieldName, ICollection<IEnumLite> list, out ICollection<object> unknown, IEnumLiteMap mapping)

+        {

+            unknown = null;

+            object unkval;

+            IEnumLite value = null;

+            WireFormat.WireType wformat = WireFormat.GetTagWireType(fieldTag);

+

+            // 2.3 allows packed form even if the field is not declared packed.

+            if (wformat == WireFormat.WireType.LengthDelimited)

+            {

+                int length = (int)(ReadRawVarint32() & int.MaxValue);

+                int limit = PushLimit(length);

+                while (!ReachedLimit)

+                {

+                    if (ReadEnum(ref value, out unkval, mapping))

+                        list.Add(value);

+                    else

+                    {

+                        if (unknown == null)

+                            unknown = new List<object>();

+                        unknown.Add(unkval);

+                    }

+                }

+                PopLimit(limit);

+            }

+            else

+            {

+                if (ReadEnum(ref value, out unkval, mapping))

+                    list.Add(value);

+                else

+                    unknown = new object[] { unkval };

+            }

+        }

+

+        [CLSCompliant(false)]

+        public void ReadEnumArray<T>(uint fieldTag, string fieldName, ICollection<T> list, out ICollection<object> unknown)

+            where T : struct, IComparable, IFormattable, IConvertible

+        {

+            unknown = null;

+            object unkval;

+            T value = default(T);

+            WireFormat.WireType wformat = WireFormat.GetTagWireType(fieldTag);

+

+            // 2.3 allows packed form even if the field is not declared packed.

+            if (wformat == WireFormat.WireType.LengthDelimited)

+            {

+                int length = (int)(ReadRawVarint32() & int.MaxValue);

+                int limit = PushLimit(length);

+                while (!ReachedLimit)

+                {

+                    if (ReadEnum<T>(ref value, out unkval))

+                        list.Add(value);

+                    else

+                    {

+                        if (unknown == null)

+                            unknown = new List<object>();

+                        unknown.Add(unkval);

+                    }

+                }

+                PopLimit(limit);

+            }

+            else

+            {

+                if (ReadEnum(ref value, out unkval))

+                    list.Add(value);

+                else

+                    unknown = new object[] { unkval };

+            }

+        }

+

+        [CLSCompliant(false)]

+        public void ReadMessageArray<T>(uint fieldTag, string fieldName, ICollection<T> list, T messageType, ExtensionRegistry registry) where T : IMessageLite

+        {

+            IBuilderLite builder = messageType.WeakCreateBuilderForType();

+            ReadMessage(builder, registry);

+            list.Add((T)builder.WeakBuildPartial());

+        }

+

+        [CLSCompliant(false)]

+        public void ReadGroupArray<T>(uint fieldTag, string fieldName, ICollection<T> list, T messageType, ExtensionRegistry registry) where T : IMessageLite

+        {

+            IBuilderLite builder = messageType.WeakCreateBuilderForType();

+            ReadGroup(WireFormat.GetTagFieldNumber(fieldTag), builder, registry);

+            list.Add((T)builder.WeakBuildPartial());

         }

 

         /// <summary>

         /// Reads a field of any primitive type. Enums, groups and embedded

         /// messages are not handled by this method.

         /// </summary>

-        public object ReadPrimitiveField(FieldType fieldType)

+        public bool ReadPrimitiveField(FieldType fieldType, ref object value)

         {

             switch (fieldType)

             {

                 case FieldType.Double:

-                    return ReadDouble();

+                    {

+                        double tmp = 0;

+                        if (ReadDouble(ref tmp))

+                        {

+                            value = tmp;

+                            return true;

+                        }

+                        return false;

+                    }

                 case FieldType.Float:

-                    return ReadFloat();

+                    {

+                        float tmp = 0;

+                        if (ReadFloat(ref tmp))

+                        {

+                            value = tmp;

+                            return true;

+                        }

+                        return false;

+                    }

                 case FieldType.Int64:

-                    return ReadInt64();

+                    {

+                        long tmp = 0;

+                        if (ReadInt64(ref tmp))

+                        {

+                            value = tmp;

+                            return true;

+                        }

+                        return false;

+                    }

                 case FieldType.UInt64:

-                    return ReadUInt64();

+                    {

+                        ulong tmp = 0;

+                        if (ReadUInt64(ref tmp))

+                        {

+                            value = tmp;

+                            return true;

+                        }

+                        return false;

+                    }

                 case FieldType.Int32:

-                    return ReadInt32();

+                    {

+                        int tmp = 0;

+                        if (ReadInt32(ref tmp))

+                        {

+                            value = tmp;

+                            return true;

+                        }

+                        return false;

+                    }

                 case FieldType.Fixed64:

-                    return ReadFixed64();

+                    {

+                        ulong tmp = 0;

+                        if (ReadFixed64(ref tmp))

+                        {

+                            value = tmp;

+                            return true;

+                        }

+                        return false;

+                    }

                 case FieldType.Fixed32:

-                    return ReadFixed32();

+                    {

+                        uint tmp = 0;

+                        if (ReadFixed32(ref tmp))

+                        {

+                            value = tmp;

+                            return true;

+                        }

+                        return false;

+                    }

                 case FieldType.Bool:

-                    return ReadBool();

+                    {

+                        bool tmp = false;

+                        if (ReadBool(ref tmp))

+                        {

+                            value = tmp;

+                            return true;

+                        }

+                        return false;

+                    }

                 case FieldType.String:

-                    return ReadString();

+                    {

+                        string tmp = null;

+                        if (ReadString(ref tmp))

+                        {

+                            value = tmp;

+                            return true;

+                        }

+                        return false;

+                    }

                 case FieldType.Bytes:

-                    return ReadBytes();

+                    {

+                        ByteString tmp = null;

+                        if (ReadBytes(ref tmp))

+                        {

+                            value = tmp;

+                            return true;

+                        }

+                        return false;

+                    }

                 case FieldType.UInt32:

-                    return ReadUInt32();

+                    {

+                        uint tmp = 0;

+                        if (ReadUInt32(ref tmp))

+                        {

+                            value = tmp;

+                            return true;

+                        }

+                        return false;

+                    }

                 case FieldType.SFixed32:

-                    return ReadSFixed32();

+                    {

+                        int tmp = 0;

+                        if (ReadSFixed32(ref tmp))

+                        {

+                            value = tmp;

+                            return true;

+                        }

+                        return false;

+                    }

                 case FieldType.SFixed64:

-                    return ReadSFixed64();

+                    {

+                        long tmp = 0;

+                        if (ReadSFixed64(ref tmp))

+                        {

+                            value = tmp;

+                            return true;

+                        }

+                        return false;

+                    }

                 case FieldType.SInt32:

-                    return ReadSInt32();

+                    {

+                        int tmp = 0;

+                        if (ReadSInt32(ref tmp))

+                        {

+                            value = tmp;

+                            return true;

+                        }

+                        return false;

+                    }

                 case FieldType.SInt64:

-                    return ReadSInt64();

+                    {

+                        long tmp = 0;

+                        if (ReadSInt64(ref tmp))

+                        {

+                            value = tmp;

+                            return true;

+                        }

+                        return false;

+                    }

                 case FieldType.Group:

                     throw new ArgumentException("ReadPrimitiveField() cannot handle nested groups.");

                 case FieldType.Message:

@@ -1047,7 +1331,7 @@
             switch (WireFormat.GetTagWireType(tag))

             {

                 case WireFormat.WireType.Varint:

-                    ReadInt32();

+                    ReadRawVarint64();

                     return true;

                 case WireFormat.WireType.Fixed64:

                     ReadRawLittleEndian64();

diff --git a/src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs b/src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs
index 36040cb..5dbab8c 100644
--- a/src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs
+++ b/src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs
@@ -531,66 +531,66 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              Namespace = input.ReadString();

+              result.hasNamespace |= input.ReadString(ref result.namespace_);

               break;

             }

             case 18: {

-              UmbrellaClassname = input.ReadString();

+              result.hasUmbrellaClassname |= input.ReadString(ref result.umbrellaClassname_);

               break;

             }

             case 24: {

-              PublicClasses = input.ReadBool();

+              result.hasPublicClasses |= input.ReadBool(ref result.publicClasses_);

               break;

             }

             case 32: {

-              MultipleFiles = input.ReadBool();

+              result.hasMultipleFiles |= input.ReadBool(ref result.multipleFiles_);

               break;

             }

             case 40: {

-              NestClasses = input.ReadBool();

+              result.hasNestClasses |= input.ReadBool(ref result.nestClasses_);

               break;

             }

             case 48: {

-              CodeContracts = input.ReadBool();

+              result.hasCodeContracts |= input.ReadBool(ref result.codeContracts_);

               break;

             }

             case 56: {

-              ExpandNamespaceDirectories = input.ReadBool();

+              result.hasExpandNamespaceDirectories |= input.ReadBool(ref result.expandNamespaceDirectories_);

               break;

             }

             case 64: {

-              ClsCompliance = input.ReadBool();

+              result.hasClsCompliance |= input.ReadBool(ref result.clsCompliance_);

               break;

             }

             case 1770: {

-              FileExtension = input.ReadString();

+              result.hasFileExtension |= input.ReadString(ref result.fileExtension_);

               break;

             }

             case 1778: {

-              UmbrellaNamespace = input.ReadString();

+              result.hasUmbrellaNamespace |= input.ReadString(ref result.umbrellaNamespace_);

               break;

             }

             case 1786: {

-              OutputDirectory = input.ReadString();

+              result.hasOutputDirectory |= input.ReadString(ref result.outputDirectory_);

               break;

             }

             case 1792: {

-              IgnoreGoogleProtobuf = input.ReadBool();

+              result.hasIgnoreGoogleProtobuf |= input.ReadBool(ref result.ignoreGoogleProtobuf_);

               break;

             }

             case 1800: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceType), rawValue)) {

+              object unknown;

+              if(input.ReadEnum(ref result.serviceGeneratorType_, out unknown)) {

+                result.hasServiceGeneratorType = true;

+              } else if(unknown is int) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(225, (ulong) rawValue);

-              } else {

-                ServiceGeneratorType = (global::Google.ProtocolBuffers.DescriptorProtos.CSharpServiceType) rawValue;

+                unknownFields.MergeVarintField(225, (ulong)(int)unknown);

               }

               break;

             }

@@ -1032,11 +1032,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              PropertyName = input.ReadString();

+              result.hasPropertyName |= input.ReadString(ref result.propertyName_);

               break;

             }

           }

@@ -1257,11 +1257,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              InterfaceId = input.ReadString();

+              result.hasInterfaceId |= input.ReadString(ref result.interfaceId_);

               break;

             }

           }

@@ -1482,11 +1482,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              DispatchId = input.ReadInt32();

+              result.hasDispatchId |= input.ReadInt32(ref result.dispatchId_);

               break;

             }

           }

diff --git a/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs b/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs
index 0dca046..365a044 100644
--- a/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs
+++ b/src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs
@@ -417,13 +417,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddFile(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.file_, global::Google.ProtocolBuffers.DescriptorProtos.FileDescriptorProto.DefaultInstance, extensionRegistry);

               break;

             }

           }

@@ -831,43 +829,35 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              Name = input.ReadString();

+              result.hasName |= input.ReadString(ref result.name_);

               break;

             }

             case 18: {

-              Package = input.ReadString();

+              result.hasPackage |= input.ReadString(ref result.package_);

               break;

             }

             case 26: {

-              AddDependency(input.ReadString());

+              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.dependency_);

               break;

             }

             case 34: {

-              global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddMessageType(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.messageType_, global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.DefaultInstance, extensionRegistry);

               break;

             }

             case 42: {

-              global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddEnumType(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.enumType_, global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.DefaultInstance, extensionRegistry);

               break;

             }

             case 50: {

-              global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddService(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.service_, global::Google.ProtocolBuffers.DescriptorProtos.ServiceDescriptorProto.DefaultInstance, extensionRegistry);

               break;

             }

             case 58: {

-              global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddExtension(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.extension_, global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.DefaultInstance, extensionRegistry);

               break;

             }

             case 66: {

@@ -1381,15 +1371,15 @@
                   if (unknownFields == null) {

                     unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                   }

-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 8: {

-                  Start = input.ReadInt32();

+                  result.hasStart |= input.ReadInt32(ref result.start_);

                   break;

                 }

                 case 16: {

-                  End = input.ReadInt32();

+                  result.hasEnd |= input.ReadInt32(ref result.end_);

                   break;

                 }

               }

@@ -1749,41 +1739,31 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              Name = input.ReadString();

+              result.hasName |= input.ReadString(ref result.name_);

               break;

             }

             case 18: {

-              global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddField(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.field_, global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.DefaultInstance, extensionRegistry);

               break;

             }

             case 26: {

-              global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddNestedType(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.nestedType_, global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.DefaultInstance, extensionRegistry);

               break;

             }

             case 34: {

-              global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddEnumType(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.enumType_, global::Google.ProtocolBuffers.DescriptorProtos.EnumDescriptorProto.DefaultInstance, extensionRegistry);

               break;

             }

             case 42: {

-              global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddExtensionRange(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.extensionRange_, global::Google.ProtocolBuffers.DescriptorProtos.DescriptorProto.Types.ExtensionRange.DefaultInstance, extensionRegistry);

               break;

             }

             case 50: {

-              global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddExtension(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.extension_, global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.DefaultInstance, extensionRegistry);

               break;

             }

             case 58: {

@@ -2414,51 +2394,51 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              Name = input.ReadString();

+              result.hasName |= input.ReadString(ref result.name_);

               break;

             }

             case 18: {

-              Extendee = input.ReadString();

+              result.hasExtendee |= input.ReadString(ref result.extendee_);

               break;

             }

             case 24: {

-              Number = input.ReadInt32();

+              result.hasNumber |= input.ReadInt32(ref result.number_);

               break;

             }

             case 32: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Label), rawValue)) {

+              object unknown;

+              if(input.ReadEnum(ref result.label_, out unknown)) {

+                result.hasLabel = true;

+              } else if(unknown is int) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(4, (ulong) rawValue);

-              } else {

-                Label = (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Label) rawValue;

+                unknownFields.MergeVarintField(4, (ulong)(int)unknown);

               }

               break;

             }

             case 40: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Type), rawValue)) {

+              object unknown;

+              if(input.ReadEnum(ref result.type_, out unknown)) {

+                result.hasType = true;

+              } else if(unknown is int) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(5, (ulong) rawValue);

-              } else {

-                Type = (global::Google.ProtocolBuffers.DescriptorProtos.FieldDescriptorProto.Types.Type) rawValue;

+                unknownFields.MergeVarintField(5, (ulong)(int)unknown);

               }

               break;

             }

             case 50: {

-              TypeName = input.ReadString();

+              result.hasTypeName |= input.ReadString(ref result.typeName_);

               break;

             }

             case 58: {

-              DefaultValue = input.ReadString();

+              result.hasDefaultValue |= input.ReadString(ref result.defaultValue_);

               break;

             }

             case 66: {

@@ -2882,17 +2862,15 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              Name = input.ReadString();

+              result.hasName |= input.ReadString(ref result.name_);

               break;

             }

             case 18: {

-              global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddValue(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.value_, global::Google.ProtocolBuffers.DescriptorProtos.EnumValueDescriptorProto.DefaultInstance, extensionRegistry);

               break;

             }

             case 26: {

@@ -3237,15 +3215,15 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              Name = input.ReadString();

+              result.hasName |= input.ReadString(ref result.name_);

               break;

             }

             case 16: {

-              Number = input.ReadInt32();

+              result.hasNumber |= input.ReadInt32(ref result.number_);

               break;

             }

             case 26: {

@@ -3576,17 +3554,15 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              Name = input.ReadString();

+              result.hasName |= input.ReadString(ref result.name_);

               break;

             }

             case 18: {

-              global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddMethod(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.method_, global::Google.ProtocolBuffers.DescriptorProtos.MethodDescriptorProto.DefaultInstance, extensionRegistry);

               break;

             }

             case 26: {

@@ -3950,19 +3926,19 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              Name = input.ReadString();

+              result.hasName |= input.ReadString(ref result.name_);

               break;

             }

             case 18: {

-              InputType = input.ReadString();

+              result.hasInputType |= input.ReadString(ref result.inputType_);

               break;

             }

             case 26: {

-              OutputType = input.ReadString();

+              result.hasOutputType |= input.ReadString(ref result.outputType_);

               break;

             }

             case 34: {

@@ -4426,49 +4402,47 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              JavaPackage = input.ReadString();

+              result.hasJavaPackage |= input.ReadString(ref result.javaPackage_);

               break;

             }

             case 66: {

-              JavaOuterClassname = input.ReadString();

+              result.hasJavaOuterClassname |= input.ReadString(ref result.javaOuterClassname_);

               break;

             }

             case 72: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode), rawValue)) {

+              object unknown;

+              if(input.ReadEnum(ref result.optimizeFor_, out unknown)) {

+                result.hasOptimizeFor = true;

+              } else if(unknown is int) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(9, (ulong) rawValue);

-              } else {

-                OptimizeFor = (global::Google.ProtocolBuffers.DescriptorProtos.FileOptions.Types.OptimizeMode) rawValue;

+                unknownFields.MergeVarintField(9, (ulong)(int)unknown);

               }

               break;

             }

             case 80: {

-              JavaMultipleFiles = input.ReadBool();

+              result.hasJavaMultipleFiles |= input.ReadBool(ref result.javaMultipleFiles_);

               break;

             }

             case 128: {

-              CcGenericServices = input.ReadBool();

+              result.hasCcGenericServices |= input.ReadBool(ref result.ccGenericServices_);

               break;

             }

             case 136: {

-              JavaGenericServices = input.ReadBool();

+              result.hasJavaGenericServices |= input.ReadBool(ref result.javaGenericServices_);

               break;

             }

             case 144: {

-              PyGenericServices = input.ReadBool();

+              result.hasPyGenericServices |= input.ReadBool(ref result.pyGenericServices_);

               break;

             }

             case 7994: {

-              global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddUninterpretedOption(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.uninterpretedOption_, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.DefaultInstance, extensionRegistry);

               break;

             }

           }

@@ -4885,21 +4859,19 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              MessageSetWireFormat = input.ReadBool();

+              result.hasMessageSetWireFormat |= input.ReadBool(ref result.messageSetWireFormat_);

               break;

             }

             case 16: {

-              NoStandardDescriptorAccessor = input.ReadBool();

+              result.hasNoStandardDescriptorAccessor |= input.ReadBool(ref result.noStandardDescriptorAccessor_);

               break;

             }

             case 7994: {

-              global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddUninterpretedOption(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.uninterpretedOption_, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.DefaultInstance, extensionRegistry);

               break;

             }

           }

@@ -5278,37 +5250,35 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Types.CType), rawValue)) {

+              object unknown;

+              if(input.ReadEnum(ref result.ctype_, out unknown)) {

+                result.hasCtype = true;

+              } else if(unknown is int) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(1, (ulong) rawValue);

-              } else {

-                Ctype = (global::Google.ProtocolBuffers.DescriptorProtos.FieldOptions.Types.CType) rawValue;

+                unknownFields.MergeVarintField(1, (ulong)(int)unknown);

               }

               break;

             }

             case 16: {

-              Packed = input.ReadBool();

+              result.hasPacked |= input.ReadBool(ref result.packed_);

               break;

             }

             case 24: {

-              Deprecated = input.ReadBool();

+              result.hasDeprecated |= input.ReadBool(ref result.deprecated_);

               break;

             }

             case 74: {

-              ExperimentalMapKey = input.ReadString();

+              result.hasExperimentalMapKey |= input.ReadString(ref result.experimentalMapKey_);

               break;

             }

             case 7994: {

-              global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddUninterpretedOption(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.uninterpretedOption_, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.DefaultInstance, extensionRegistry);

               break;

             }

           }

@@ -5632,13 +5602,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 7994: {

-              global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddUninterpretedOption(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.uninterpretedOption_, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.DefaultInstance, extensionRegistry);

               break;

             }

           }

@@ -5889,13 +5857,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 7994: {

-              global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddUninterpretedOption(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.uninterpretedOption_, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.DefaultInstance, extensionRegistry);

               break;

             }

           }

@@ -6146,13 +6112,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 7994: {

-              global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddUninterpretedOption(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.uninterpretedOption_, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.DefaultInstance, extensionRegistry);

               break;

             }

           }

@@ -6403,13 +6367,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 7994: {

-              global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddUninterpretedOption(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.uninterpretedOption_, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.DefaultInstance, extensionRegistry);

               break;

             }

           }

@@ -6700,15 +6662,15 @@
                   if (unknownFields == null) {

                     unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                   }

-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 10: {

-                  NamePart_ = input.ReadString();

+                  result.hasNamePart_ |= input.ReadString(ref result.namePart_);

                   break;

                 }

                 case 16: {

-                  IsExtension = input.ReadBool();

+                  result.hasIsExtension |= input.ReadBool(ref result.isExtension_);

                   break;

                 }

               }

@@ -7027,33 +6989,31 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 18: {

-              global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart.Builder subBuilder = global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddName(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.name_, global::Google.ProtocolBuffers.DescriptorProtos.UninterpretedOption.Types.NamePart.DefaultInstance, extensionRegistry);

               break;

             }

             case 26: {

-              IdentifierValue = input.ReadString();

+              result.hasIdentifierValue |= input.ReadString(ref result.identifierValue_);

               break;

             }

             case 32: {

-              PositiveIntValue = input.ReadUInt64();

+              result.hasPositiveIntValue |= input.ReadUInt64(ref result.positiveIntValue_);

               break;

             }

             case 40: {

-              NegativeIntValue = input.ReadInt64();

+              result.hasNegativeIntValue |= input.ReadInt64(ref result.negativeIntValue_);

               break;

             }

             case 49: {

-              DoubleValue = input.ReadDouble();

+              result.hasDoubleValue |= input.ReadDouble(ref result.doubleValue_);

               break;

             }

             case 58: {

-              StringValue = input.ReadBytes();

+              result.hasStringValue |= input.ReadBytes(ref result.stringValue_);

               break;

             }

           }

diff --git a/src/ProtocolBuffers/Descriptors/EnumDescriptor.cs b/src/ProtocolBuffers/Descriptors/EnumDescriptor.cs
index 80c2bd0..2922190 100644
--- a/src/ProtocolBuffers/Descriptors/EnumDescriptor.cs
+++ b/src/ProtocolBuffers/Descriptors/EnumDescriptor.cs
@@ -98,6 +98,10 @@
         {

             return FindValueByNumber(number);

         }

+        IEnumLite IEnumLiteMap.FindValueByName(string name)

+        {

+            return FindValueByName(name);

+        }

 

         /// <summary>

         /// Finds an enum value by name.

diff --git a/src/ProtocolBuffers/EnumLite.cs b/src/ProtocolBuffers/EnumLite.cs
index 4c2f8b7..35223fc 100644
--- a/src/ProtocolBuffers/EnumLite.cs
+++ b/src/ProtocolBuffers/EnumLite.cs
@@ -70,6 +70,7 @@
     {

         bool IsValidValue(IEnumLite value);

         IEnumLite FindValueByNumber(int number);

+        IEnumLite FindValueByName(string name);

     }

 

     public class EnumLiteMap<TEnum> : IEnumLiteMap<IEnumLite>

@@ -125,6 +126,14 @@
             return items.TryGetValue(number, out val) ? val : null;

         }

 

+        public IEnumLite FindValueByName(string name)

+        {

+            IEnumLite val;

+            if(Enum.IsDefined(typeof(TEnum), name))

+                return items.TryGetValue((int)Enum.Parse(typeof(TEnum), name, false), out val) ? val : null;

+            return null;

+        }

+

         public bool IsValidValue(IEnumLite value)

         {

             return items.ContainsKey(value.Number);

diff --git a/src/ProtocolBuffers/ExtendableBuilder.cs b/src/ProtocolBuffers/ExtendableBuilder.cs
index 532520e..49265f4 100644
--- a/src/ProtocolBuffers/ExtendableBuilder.cs
+++ b/src/ProtocolBuffers/ExtendableBuilder.cs
@@ -131,9 +131,9 @@
         /// <returns>true unless the tag is an end-group tag</returns>

         [CLSCompliant(false)]

         protected override bool ParseUnknownField(CodedInputStream input, UnknownFieldSet.Builder unknownFields,

-                                                  ExtensionRegistry extensionRegistry, uint tag)

+                                                  ExtensionRegistry extensionRegistry, uint tag, string fieldName)

         {

-            return unknownFields.MergeFieldFrom(input, extensionRegistry, this, tag);

+            return unknownFields.MergeFieldFrom(input, extensionRegistry, this, tag, fieldName);

         }

 

         // ---------------------------------------------------------------

diff --git a/src/ProtocolBuffers/ExtendableBuilderLite.cs b/src/ProtocolBuffers/ExtendableBuilderLite.cs
index fc748e6..f9508d4 100644
--- a/src/ProtocolBuffers/ExtendableBuilderLite.cs
+++ b/src/ProtocolBuffers/ExtendableBuilderLite.cs
@@ -134,7 +134,7 @@
         /// <returns>true unless the tag is an end-group tag</returns>

         [CLSCompliant(false)]

         protected override bool ParseUnknownField(CodedInputStream input,

-                                                  ExtensionRegistry extensionRegistry, uint tag)

+                                                  ExtensionRegistry extensionRegistry, uint tag, string fieldName)

         {

             FieldSet extensions = MessageBeingBuilt.Extensions;

 

@@ -142,119 +142,81 @@
             int fieldNumber = WireFormat.GetTagFieldNumber(tag);

             IGeneratedExtensionLite extension = extensionRegistry[DefaultInstanceForType, fieldNumber];

 

-            bool unknown = false;

-            bool packed = false;

-            if (extension == null)

-            {

-                unknown = true; // Unknown field.

-            }

-            else if (wireType ==

-                     FieldMappingAttribute.WireTypeFromFieldType(extension.Descriptor.FieldType, false /* isPacked */))

-            {

-                packed = false; // Normal, unpacked value.

-            }

-            else if (extension.Descriptor.IsRepeated &&

-                     //?? just returns true ?? extension.Descriptor.type.isPackable() &&

-                     wireType ==

-                     FieldMappingAttribute.WireTypeFromFieldType(extension.Descriptor.FieldType, true /* isPacked */))

-            {

-                packed = true; // Packed value.

-            }

-            else

-            {

-                unknown = true; // Wrong wire type.

-            }

-

-            if (unknown)

-            {

-                // Unknown field or wrong wire type.  Skip.

+            if (extension == null)//unknown field

                 return input.SkipField();

-            }

 

-            if (packed)

+            IFieldDescriptorLite field = extension.Descriptor;

+            if (!field.IsRepeated && wireType != WireFormat.GetWireType(field.FieldType)) //invalid wire type

+                return input.SkipField();

+

+            switch (field.FieldType)

             {

-                int length = (int) Math.Min(int.MaxValue, input.ReadRawVarint32());

-                int limit = input.PushLimit(length);

-                if (extension.Descriptor.FieldType == FieldType.Enum)

-                {

-                    while (!input.ReachedLimit)

+                case FieldType.Group:

+                case FieldType.Message:

                     {

-                        int rawValue = input.ReadEnum();

-                        Object value =

-                            extension.Descriptor.EnumType.FindValueByNumber(rawValue);

-                        if (value == null)

+                        if (!field.IsRepeated)

                         {

-                            // If the number isn't recognized as a valid value for this

-                            // enum, drop it (don't even add it to unknownFields).

-                            return true;

-                        }

-                        extensions.AddRepeatedField(extension.Descriptor, value);

-                    }

-                }

-                else

-                {

-                    while (!input.ReachedLimit)

-                    {

-                        Object value = input.ReadPrimitiveField(extension.Descriptor.FieldType);

-                        extensions.AddRepeatedField(extension.Descriptor, value);

-                    }

-                }

-                input.PopLimit(limit);

-            }

-            else

-            {

-                Object value;

-                switch (extension.Descriptor.MappedType)

-                {

-                    case MappedType.Message:

-                        {

-                            IBuilderLite subBuilder = null;

-                            if (!extension.Descriptor.IsRepeated)

-                            {

-                                IMessageLite existingValue = extensions[extension.Descriptor] as IMessageLite;

-                                if (existingValue != null)

-                                {

-                                    subBuilder = existingValue.WeakToBuilder();

-                                }

-                            }

-                            if (subBuilder == null)

-                            {

-                                subBuilder = extension.MessageDefaultInstance.WeakCreateBuilderForType();

-                            }

-                            if (extension.Descriptor.FieldType == FieldType.Group)

-                            {

-                                input.ReadGroup(extension.Number, subBuilder, extensionRegistry);

-                            }

+                            IMessageLite message = extensions[extension.Descriptor] as IMessageLite;

+                            IBuilderLite subBuilder = (message ?? extension.MessageDefaultInstance).WeakToBuilder();

+

+                            if (field.FieldType == FieldType.Group)

+                                input.ReadGroup(field.FieldNumber, subBuilder, extensionRegistry);

                             else

-                            {

                                 input.ReadMessage(subBuilder, extensionRegistry);

-                            }

-                            value = subBuilder.WeakBuild();

-                            break;

+                            

+                            extensions[field] = subBuilder.WeakBuild();

                         }

-                    case MappedType.Enum:

-                        int rawValue = input.ReadEnum();

-                        value = extension.Descriptor.EnumType.FindValueByNumber(rawValue);

-                        // If the number isn't recognized as a valid value for this enum,

-                        // drop it.

-                        if (value == null)

+                        else

                         {

+                            List<IMessageLite> list = new List<IMessageLite>();

+                            if (field.FieldType == FieldType.Group)

+                                input.ReadGroupArray(tag, fieldName, list, extension.MessageDefaultInstance, extensionRegistry);

+                            else

+                                input.ReadMessageArray(tag, fieldName, list, extension.MessageDefaultInstance, extensionRegistry);

+

+                            foreach (IMessageLite m in list)

+                                extensions.AddRepeatedField(field, m);

                             return true;

                         }

                         break;

-                    default:

-                        value = input.ReadPrimitiveField(extension.Descriptor.FieldType);

-                        break;

-                }

+                    }

+                case FieldType.Enum:

+                    {

+                        if (!field.IsRepeated)

+                        {

+                            object unknown;

+                            IEnumLite value = null;

+                            if (input.ReadEnum(ref value, out unknown, field.EnumType))

+                                extensions[field] = value;

+                        }

+                        else

+                        {

+                            ICollection<object> unknown;

+                            List<IEnumLite> list = new List<IEnumLite>();

+                            input.ReadEnumArray(tag, fieldName, list, out unknown, field.EnumType);

 

-                if (extension.Descriptor.IsRepeated)

-                {

-                    extensions.AddRepeatedField(extension.Descriptor, value);

-                }

-                else

-                {

-                    extensions[extension.Descriptor] = value;

-                }

+                            foreach (IEnumLite en in list)

+                                extensions.AddRepeatedField(field, en);

+                        }

+                        break;

+                    }

+                default:

+                    {

+                        if (!field.IsRepeated)

+                        {

+                            object value = null;

+                            if (input.ReadPrimitiveField(field.FieldType, ref value))

+                                extensions[field] = value;

+                        }

+                        else

+                        {

+                            List<object> list = new List<object>();

+                            input.ReadPrimitiveArray(field.FieldType, tag, fieldName, list);

+                            foreach (object oval in list)

+                                extensions.AddRepeatedField(field, oval);

+                        }

+                        break;

+                    }

             }

 

             return true;

diff --git a/src/ProtocolBuffers/GeneratedBuilder.cs b/src/ProtocolBuffers/GeneratedBuilder.cs
index b44cd63..699320a 100644
--- a/src/ProtocolBuffers/GeneratedBuilder.cs
+++ b/src/ProtocolBuffers/GeneratedBuilder.cs
@@ -116,7 +116,7 @@
         /// <returns>true unless the tag is an end-group tag</returns>

         [CLSCompliant(false)]

         protected virtual bool ParseUnknownField(CodedInputStream input, UnknownFieldSet.Builder unknownFields,

-                                                 ExtensionRegistry extensionRegistry, uint tag)

+                                                 ExtensionRegistry extensionRegistry, uint tag, string fieldName)

         {

             return unknownFields.MergeFieldFrom(tag, input);

         }

diff --git a/src/ProtocolBuffers/GeneratedBuilderLite.cs b/src/ProtocolBuffers/GeneratedBuilderLite.cs
index 810324c..2562842 100644
--- a/src/ProtocolBuffers/GeneratedBuilderLite.cs
+++ b/src/ProtocolBuffers/GeneratedBuilderLite.cs
@@ -99,7 +99,7 @@
         /// <returns>true unless the tag is an end-group tag</returns>

         [CLSCompliant(false)]

         protected virtual bool ParseUnknownField(CodedInputStream input,

-                                                 ExtensionRegistry extensionRegistry, uint tag)

+                                                 ExtensionRegistry extensionRegistry, uint tag, string fieldName)

         {

             return input.SkipField();

         }

diff --git a/src/ProtocolBuffers/UnknownFieldSet.cs b/src/ProtocolBuffers/UnknownFieldSet.cs
index ff6a153..e0f1cff 100644
--- a/src/ProtocolBuffers/UnknownFieldSet.cs
+++ b/src/ProtocolBuffers/UnknownFieldSet.cs
@@ -450,14 +450,33 @@
                 switch (WireFormat.GetTagWireType(tag))

                 {

                     case WireFormat.WireType.Varint:

-                        GetFieldBuilder(number).AddVarint(input.ReadUInt64());

-                        return true;

+                        {

+                            ulong uint64 = 0;

+                            if(input.ReadUInt64(ref uint64))

+                                GetFieldBuilder(number).AddVarint(uint64);

+                            return true;

+                        }

+                    case WireFormat.WireType.Fixed32:

+                        {

+                            uint uint32 = 0;

+                            if (input.ReadFixed32(ref uint32))

+                                GetFieldBuilder(number).AddFixed32(uint32);

+                            return true;

+                        }

                     case WireFormat.WireType.Fixed64:

-                        GetFieldBuilder(number).AddFixed64(input.ReadFixed64());

-                        return true;

+                        {

+                            ulong uint64 = 0;

+                            if (input.ReadFixed64(ref uint64))

+                                GetFieldBuilder(number).AddFixed64(uint64);

+                            return true;

+                        }

                     case WireFormat.WireType.LengthDelimited:

-                        GetFieldBuilder(number).AddLengthDelimited(input.ReadBytes());

-                        return true;

+                        {

+                            ByteString bytes = null;

+                            if (input.ReadBytes(ref bytes))

+                                GetFieldBuilder(number).AddLengthDelimited(bytes);

+                            return true;

+                        }

                     case WireFormat.WireType.StartGroup:

                         {

                             Builder subBuilder = CreateBuilder();

@@ -469,9 +488,6 @@
                         }

                     case WireFormat.WireType.EndGroup:

                         return false;

-                    case WireFormat.WireType.Fixed32:

-                        GetFieldBuilder(number).AddFixed32(input.ReadFixed32());

-                        return true;

                     default:

                         throw InvalidProtocolBufferException.InvalidWireType();

                 }

@@ -598,7 +614,7 @@
                         break;

                     }

 

-                    if (!MergeFieldFrom(input, extensionRegistry, builder, tag))

+                    if (!MergeFieldFrom(input, extensionRegistry, builder, tag, name))

                     {

                         // end group tag

                         break;

@@ -616,7 +632,7 @@
             /// <param name="tag">The tag, which should already have been read from the input</param>

             /// <returns>true unless the tag is an end-group tag</returns>

             internal bool MergeFieldFrom(CodedInputStream input,

-                                         ExtensionRegistry extensionRegistry, IBuilder builder, uint tag)

+                                         ExtensionRegistry extensionRegistry, IBuilder builder, uint tag, string fieldName)

             {

                 MessageDescriptor type = builder.DescriptorForType;

                 if (type.Options.MessageSetWireFormat && tag == WireFormat.MessageSetTag.ItemStart)

@@ -655,92 +671,81 @@
                     return MergeFieldFrom(tag, input);

                 }

 

-                if (field.IsPacked)

+                switch (field.FieldType)

                 {

-                    int length = (int) input.ReadRawVarint32();

-                    int limit = input.PushLimit(length);

-                    if (field.FieldType == FieldType.Enum)

-                    {

-                        while (!input.ReachedLimit)

+                    case FieldType.Group:

+                    case FieldType.Message:

                         {

-                            int rawValue = input.ReadEnum();

-                            object value = field.EnumType.FindValueByNumber(rawValue);

-                            if (value == null)

+                            IBuilderLite subBuilder = (defaultFieldInstance != null) ? defaultFieldInstance.WeakCreateBuilderForType() : builder.CreateBuilderForField(field);

+                            if (!field.IsRepeated)

                             {

-                                // If the number isn't recognized as a valid value for this

-                                // enum, drop it (don't even add it to unknownFields).

+                                subBuilder.WeakMergeFrom((IMessageLite)builder[field]);

+                                if (field.FieldType == FieldType.Group)

+                                    input.ReadGroup(field.FieldNumber, subBuilder, extensionRegistry);

+                                else

+                                    input.ReadMessage(subBuilder, extensionRegistry);

+                                builder[field] = subBuilder.WeakBuild();

+                            }

+                            else

+                            {

+                                List<IMessageLite> list = new List<IMessageLite>();

+                                if (field.FieldType == FieldType.Group)

+                                    input.ReadGroupArray(tag, fieldName, list, subBuilder.WeakDefaultInstanceForType, extensionRegistry);

+                                else

+                                    input.ReadMessageArray(tag, fieldName, list, subBuilder.WeakDefaultInstanceForType, extensionRegistry);

+

+                                foreach (IMessageLite m in list)

+                                    builder.WeakAddRepeatedField(field, m);

                                 return true;

                             }

-                            builder.WeakAddRepeatedField(field, value);

-                        }

-                    }

-                    else

-                    {

-                        while (!input.ReachedLimit)

-                        {

-                            Object value = input.ReadPrimitiveField(field.FieldType);

-                            builder.WeakAddRepeatedField(field, value);

-                        }

-                    }

-                    input.PopLimit(limit);

-                }

-                else

-                {

-                    object value;

-                    switch (field.FieldType)

-                    {

-                        case FieldType.Group:

-                        case FieldType.Message:

-                            {

-                                IBuilderLite subBuilder;

-                                if (defaultFieldInstance != null)

-                                {

-                                    subBuilder = defaultFieldInstance.WeakCreateBuilderForType();

-                                }

-                                else

-                                {

-                                    subBuilder = builder.CreateBuilderForField(field);

-                                }

-                                if (!field.IsRepeated)

-                                {

-                                    subBuilder.WeakMergeFrom((IMessageLite) builder[field]);

-                                }

-                                if (field.FieldType == FieldType.Group)

-                                {

-                                    input.ReadGroup(field.FieldNumber, subBuilder, extensionRegistry);

-                                }

-                                else

-                                {

-                                    input.ReadMessage(subBuilder, extensionRegistry);

-                                }

-                                value = subBuilder.WeakBuild();

-                                break;

-                            }

-                        case FieldType.Enum:

-                            {

-                                int rawValue = input.ReadEnum();

-                                value = field.EnumType.FindValueByNumber(rawValue);

-                                // If the number isn't recognized as a valid value for this enum,

-                                // drop it.

-                                if (value == null)

-                                {

-                                    MergeVarintField(fieldNumber, (ulong) rawValue);

-                                    return true;

-                                }

-                                break;

-                            }

-                        default:

-                            value = input.ReadPrimitiveField(field.FieldType);

                             break;

-                    }

-                    if (field.IsRepeated)

-                    {

-                        builder.WeakAddRepeatedField(field, value);

-                    }

-                    else

-                    {

-                        builder[field] = value;

-                    }

+                        }

+                    case FieldType.Enum:

+                        {

+                            if (!field.IsRepeated)

+                            {

+                                object unknown;

+                                IEnumLite value = null;

+                                if (input.ReadEnum(ref value, out unknown, field.EnumType))

+                                    builder[field] = value;

+                                else if(unknown is int)

+                                    MergeVarintField(fieldNumber, (ulong)(int)unknown);

+                            }

+                            else

+                            {

+                                ICollection<object> unknown;

+                                List<IEnumLite> list = new List<IEnumLite>();

+                                input.ReadEnumArray(tag, fieldName, list, out unknown, field.EnumType);

+                                

+                                foreach (IEnumLite en in list)

+                                    builder.WeakAddRepeatedField(field, en);

+

+                                if (unknown != null)

+                                {

+                                    foreach (object oval in unknown)

+                                        if (oval is int)

+                                            MergeVarintField(fieldNumber, (ulong)(int)oval);

+                                }

+                            }

+                            break;

+                        }

+                    default:

+                        {

+                            if (!field.IsRepeated)

+                            {

+                                object value = null;

+                                if (input.ReadPrimitiveField(field.FieldType, ref value))

+                                    builder[field] = value;

+                            }

+                            else

+                            {

+                                List<object> list = new List<object>();

+                                input.ReadPrimitiveArray(field.FieldType, tag, fieldName, list);

+                                foreach (object oval in list)

+                                    builder.WeakAddRepeatedField(field, oval);

+                            }

+                            break;

+                        }

                 }

                 return true;

             }

@@ -787,9 +792,9 @@
 

                     if (tag == WireFormat.MessageSetTag.TypeID)

                     {

-                        typeId = input.ReadInt32();

+                        typeId = 0;

                         // Zero is not a valid type ID.

-                        if (typeId != 0)

+                        if (input.ReadInt32(ref typeId) && typeId != 0)

                         {

                             ExtensionInfo extension = extensionRegistry[type, typeId];

                             if (extension != null)

@@ -824,23 +829,21 @@
                     }

                     else if (tag == WireFormat.MessageSetTag.Message)

                     {

-                        if (typeId == 0)

-                        {

-                            // We haven't seen a type ID yet, so we have to store the raw bytes for now.

-                            rawBytes = input.ReadBytes();

-                        }

-                        else if (subBuilder == null)

-                        {

-                            // We don't know how to parse this.  Ignore it.

-                            MergeField(typeId,

-                                       UnknownField.CreateBuilder().AddLengthDelimited(input.ReadBytes()).Build());

-                        }

-                        else

+                        if(subBuilder != null)

                         {

                             // We already know the type, so we can parse directly from the input

                             // with no copying.  Hooray!

                             input.ReadMessage(subBuilder, extensionRegistry);

                         }

+                        else if (input.ReadBytes(ref rawBytes))

+                        {

+                            if (typeId != 0)

+                            {

+                                // We don't know how to parse this.  Ignore it.

+                                MergeField(typeId,

+                                           UnknownField.CreateBuilder().AddLengthDelimited(rawBytes).Build());

+                            }

+                        }

                     }

                     else

                     {

diff --git a/src/ProtocolBuffersLite.Test/TestProtos/UnitTestExtrasLiteProtoFile.cs b/src/ProtocolBuffersLite.Test/TestProtos/UnitTestExtrasLiteProtoFile.cs
index 4597268..abe47a2 100644
--- a/src/ProtocolBuffersLite.Test/TestProtos/UnitTestExtrasLiteProtoFile.cs
+++ b/src/ProtocolBuffersLite.Test/TestProtos/UnitTestExtrasLiteProtoFile.cs
@@ -258,18 +258,18 @@
               if (pb::WireFormat.IsEndGroupTag(tag)) {

                 return this;

               }

-              ParseUnknownField(input, extensionRegistry, tag);

+              ParseUnknownField(input, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              D = input.ReadInt32();

+              result.hasD |= input.ReadInt32(ref result.d_);

               break;

             }

             case 16: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ExtraEnum), rawValue)) {

-              } else {

-                En = (global::Google.ProtocolBuffers.TestProtos.ExtraEnum) rawValue;

+              object unknown;

+              if(input.ReadEnum(ref result.en_, out unknown)) {

+                result.hasEn = true;

+              } else if(unknown is int) {

               }

               break;

             }

@@ -555,18 +555,18 @@
                   if (pb::WireFormat.IsEndGroupTag(tag)) {

                     return this;

                   }

-                  ParseUnknownField(input, extensionRegistry, tag);

+                  ParseUnknownField(input, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 10: {

-                  Number = input.ReadString();

+                  result.hasNumber |= input.ReadString(ref result.number_);

                   break;

                 }

                 case 16: {

-                  int rawValue = input.ReadEnum();

-                  if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneType), rawValue)) {

-                  } else {

-                    Type = (global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneType) rawValue;

+                  object unknown;

+                  if(input.ReadEnum(ref result.type_, out unknown)) {

+                    result.hasType = true;

+                  } else if(unknown is int) {

                   }

                   break;

                 }

@@ -893,27 +893,27 @@
                   if (pb::WireFormat.IsEndGroupTag(tag)) {

                     return this;

                   }

-                  ParseUnknownField(input, extensionRegistry, tag);

+                  ParseUnknownField(input, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 10: {

-                  Address = input.ReadString();

+                  result.hasAddress |= input.ReadString(ref result.address_);

                   break;

                 }

                 case 18: {

-                  Address2 = input.ReadString();

+                  result.hasAddress2 |= input.ReadString(ref result.address2_);

                   break;

                 }

                 case 26: {

-                  City = input.ReadString();

+                  result.hasCity |= input.ReadString(ref result.city_);

                   break;

                 }

                 case 34: {

-                  State = input.ReadString();

+                  result.hasState |= input.ReadString(ref result.state_);

                   break;

                 }

                 case 45: {

-                  Zip = input.ReadFixed32();

+                  result.hasZip |= input.ReadFixed32(ref result.zip_);

                   break;

                 }

               }

@@ -1341,40 +1341,31 @@
               if (pb::WireFormat.IsEndGroupTag(tag)) {

                 return this;

               }

-              ParseUnknownField(input, extensionRegistry, tag);

+              ParseUnknownField(input, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              Name = input.ReadString();

+              result.hasName |= input.ReadString(ref result.name_);

               break;

             }

             case 16: {

-              Id = input.ReadInt32();

+              result.hasId |= input.ReadInt32(ref result.id_);

               break;

             }

             case 26: {

-              Email = input.ReadString();

+              result.hasEmail |= input.ReadString(ref result.email_);

               break;

             }

             case 34: {

-              global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddPhone(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.phone_, global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.PhoneNumber.DefaultInstance, extensionRegistry);

               break;

             }

             case 43: {

-              global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses.CreateBuilder();

-              input.ReadGroup(5, subBuilder, extensionRegistry);

-              AddAddresses(subBuilder.BuildPartial());

+              input.ReadGroupArray(tag, field_name, result.addresses_, global::Google.ProtocolBuffers.TestProtos.TestInteropPersonLite.Types.Addresses.DefaultInstance, extensionRegistry);

               break;

             }

             case 82: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddCodes(input.ReadInt32());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.Int32, tag, field_name, result.codes_);

               break;

             }

           }

@@ -1729,11 +1720,11 @@
               if (pb::WireFormat.IsEndGroupTag(tag)) {

                 return this;

               }

-              ParseUnknownField(input, extensionRegistry, tag);

+              ParseUnknownField(input, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              Number = input.ReadString();

+              result.hasNumber |= input.ReadString(ref result.number_);

               break;

             }

           }

diff --git a/src/ProtocolBuffersLite.Test/TestProtos/UnitTestImportLiteProtoFile.cs b/src/ProtocolBuffersLite.Test/TestProtos/UnitTestImportLiteProtoFile.cs
index 26eb96a..0e890f3 100644
--- a/src/ProtocolBuffersLite.Test/TestProtos/UnitTestImportLiteProtoFile.cs
+++ b/src/ProtocolBuffersLite.Test/TestProtos/UnitTestImportLiteProtoFile.cs
@@ -218,11 +218,11 @@
               if (pb::WireFormat.IsEndGroupTag(tag)) {

                 return this;

               }

-              ParseUnknownField(input, extensionRegistry, tag);

+              ParseUnknownField(input, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              D = input.ReadInt32();

+              result.hasD |= input.ReadInt32(ref result.d_);

               break;

             }

           }

diff --git a/src/ProtocolBuffersLite.Test/TestProtos/UnitTestImportProtoFile.cs b/src/ProtocolBuffersLite.Test/TestProtos/UnitTestImportProtoFile.cs
index d97466d..cbd6cea 100644
--- a/src/ProtocolBuffersLite.Test/TestProtos/UnitTestImportProtoFile.cs
+++ b/src/ProtocolBuffersLite.Test/TestProtos/UnitTestImportProtoFile.cs
@@ -249,11 +249,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              D = input.ReadInt32();

+              result.hasD |= input.ReadInt32(ref result.d_);

               break;

             }

           }

diff --git a/src/ProtocolBuffersLite.Test/TestProtos/UnitTestLiteImportNonLiteProtoFile.cs b/src/ProtocolBuffersLite.Test/TestProtos/UnitTestLiteImportNonLiteProtoFile.cs
index 4ff7efb..cc9778f 100644
--- a/src/ProtocolBuffersLite.Test/TestProtos/UnitTestLiteImportNonLiteProtoFile.cs
+++ b/src/ProtocolBuffersLite.Test/TestProtos/UnitTestLiteImportNonLiteProtoFile.cs
@@ -207,7 +207,7 @@
               if (pb::WireFormat.IsEndGroupTag(tag)) {

                 return this;

               }

-              ParseUnknownField(input, extensionRegistry, tag);

+              ParseUnknownField(input, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

diff --git a/src/ProtocolBuffersLite.Test/TestProtos/UnitTestLiteProtoFile.cs b/src/ProtocolBuffersLite.Test/TestProtos/UnitTestLiteProtoFile.cs
index 5347a8b..c843f3f 100644
--- a/src/ProtocolBuffersLite.Test/TestProtos/UnitTestLiteProtoFile.cs
+++ b/src/ProtocolBuffersLite.Test/TestProtos/UnitTestLiteProtoFile.cs
@@ -1261,11 +1261,11 @@
                   if (pb::WireFormat.IsEndGroupTag(tag)) {

                     return this;

                   }

-                  ParseUnknownField(input, extensionRegistry, tag);

+                  ParseUnknownField(input, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 8: {

-                  Bb = input.ReadInt32();

+                  result.hasBb |= input.ReadInt32(ref result.bb_);

                   break;

                 }

               }

@@ -1479,11 +1479,11 @@
                   if (pb::WireFormat.IsEndGroupTag(tag)) {

                     return this;

                   }

-                  ParseUnknownField(input, extensionRegistry, tag);

+                  ParseUnknownField(input, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 136: {

-                  A = input.ReadInt32();

+                  result.hasA |= input.ReadInt32(ref result.a_);

                   break;

                 }

               }

@@ -1697,11 +1697,11 @@
                   if (pb::WireFormat.IsEndGroupTag(tag)) {

                     return this;

                   }

-                  ParseUnknownField(input, extensionRegistry, tag);

+                  ParseUnknownField(input, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 376: {

-                  A = input.ReadInt32();

+                  result.hasA |= input.ReadInt32(ref result.a_);

                   break;

                 }

               }

@@ -3627,67 +3627,67 @@
               if (pb::WireFormat.IsEndGroupTag(tag)) {

                 return this;

               }

-              ParseUnknownField(input, extensionRegistry, tag);

+              ParseUnknownField(input, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              OptionalInt32 = input.ReadInt32();

+              result.hasOptionalInt32 |= input.ReadInt32(ref result.optionalInt32_);

               break;

             }

             case 16: {

-              OptionalInt64 = input.ReadInt64();

+              result.hasOptionalInt64 |= input.ReadInt64(ref result.optionalInt64_);

               break;

             }

             case 24: {

-              OptionalUint32 = input.ReadUInt32();

+              result.hasOptionalUint32 |= input.ReadUInt32(ref result.optionalUint32_);

               break;

             }

             case 32: {

-              OptionalUint64 = input.ReadUInt64();

+              result.hasOptionalUint64 |= input.ReadUInt64(ref result.optionalUint64_);

               break;

             }

             case 40: {

-              OptionalSint32 = input.ReadSInt32();

+              result.hasOptionalSint32 |= input.ReadSInt32(ref result.optionalSint32_);

               break;

             }

             case 48: {

-              OptionalSint64 = input.ReadSInt64();

+              result.hasOptionalSint64 |= input.ReadSInt64(ref result.optionalSint64_);

               break;

             }

             case 61: {

-              OptionalFixed32 = input.ReadFixed32();

+              result.hasOptionalFixed32 |= input.ReadFixed32(ref result.optionalFixed32_);

               break;

             }

             case 65: {

-              OptionalFixed64 = input.ReadFixed64();

+              result.hasOptionalFixed64 |= input.ReadFixed64(ref result.optionalFixed64_);

               break;

             }

             case 77: {

-              OptionalSfixed32 = input.ReadSFixed32();

+              result.hasOptionalSfixed32 |= input.ReadSFixed32(ref result.optionalSfixed32_);

               break;

             }

             case 81: {

-              OptionalSfixed64 = input.ReadSFixed64();

+              result.hasOptionalSfixed64 |= input.ReadSFixed64(ref result.optionalSfixed64_);

               break;

             }

             case 93: {

-              OptionalFloat = input.ReadFloat();

+              result.hasOptionalFloat |= input.ReadFloat(ref result.optionalFloat_);

               break;

             }

             case 97: {

-              OptionalDouble = input.ReadDouble();

+              result.hasOptionalDouble |= input.ReadDouble(ref result.optionalDouble_);

               break;

             }

             case 104: {

-              OptionalBool = input.ReadBool();

+              result.hasOptionalBool |= input.ReadBool(ref result.optionalBool_);

               break;

             }

             case 114: {

-              OptionalString = input.ReadString();

+              result.hasOptionalString |= input.ReadString(ref result.optionalString_);

               break;

             }

             case 122: {

-              OptionalBytes = input.ReadBytes();

+              result.hasOptionalBytes |= input.ReadBytes(ref result.optionalBytes_);

               break;

             }

             case 131: {

@@ -3727,243 +3727,226 @@
               break;

             }

             case 168: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.TestAllTypesLite.Types.NestedEnum), rawValue)) {

-              } else {

-                OptionalNestedEnum = (global::Google.ProtocolBuffers.TestProtos.TestAllTypesLite.Types.NestedEnum) rawValue;

+              object unknown;

+              if(input.ReadEnum(ref result.optionalNestedEnum_, out unknown)) {

+                result.hasOptionalNestedEnum = true;

+              } else if(unknown is int) {

               }

               break;

             }

             case 176: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnumLite), rawValue)) {

-              } else {

-                OptionalForeignEnum = (global::Google.ProtocolBuffers.TestProtos.ForeignEnumLite) rawValue;

+              object unknown;

+              if(input.ReadEnum(ref result.optionalForeignEnum_, out unknown)) {

+                result.hasOptionalForeignEnum = true;

+              } else if(unknown is int) {

               }

               break;

             }

             case 184: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ImportEnumLite), rawValue)) {

-              } else {

-                OptionalImportEnum = (global::Google.ProtocolBuffers.TestProtos.ImportEnumLite) rawValue;

+              object unknown;

+              if(input.ReadEnum(ref result.optionalImportEnum_, out unknown)) {

+                result.hasOptionalImportEnum = true;

+              } else if(unknown is int) {

               }

               break;

             }

             case 194: {

-              OptionalStringPiece = input.ReadString();

+              result.hasOptionalStringPiece |= input.ReadString(ref result.optionalStringPiece_);

               break;

             }

             case 202: {

-              OptionalCord = input.ReadString();

+              result.hasOptionalCord |= input.ReadString(ref result.optionalCord_);

               break;

             }

             case 248: {

-              AddRepeatedInt32(input.ReadInt32());

+              input.ReadPrimitiveArray(pbd::FieldType.Int32, tag, field_name, result.repeatedInt32_);

               break;

             }

             case 256: {

-              AddRepeatedInt64(input.ReadInt64());

+              input.ReadPrimitiveArray(pbd::FieldType.Int64, tag, field_name, result.repeatedInt64_);

               break;

             }

             case 264: {

-              AddRepeatedUint32(input.ReadUInt32());

+              input.ReadPrimitiveArray(pbd::FieldType.UInt32, tag, field_name, result.repeatedUint32_);

               break;

             }

             case 272: {

-              AddRepeatedUint64(input.ReadUInt64());

+              input.ReadPrimitiveArray(pbd::FieldType.UInt64, tag, field_name, result.repeatedUint64_);

               break;

             }

             case 280: {

-              AddRepeatedSint32(input.ReadSInt32());

+              input.ReadPrimitiveArray(pbd::FieldType.SInt32, tag, field_name, result.repeatedSint32_);

               break;

             }

             case 288: {

-              AddRepeatedSint64(input.ReadSInt64());

+              input.ReadPrimitiveArray(pbd::FieldType.SInt64, tag, field_name, result.repeatedSint64_);

               break;

             }

             case 301: {

-              AddRepeatedFixed32(input.ReadFixed32());

+              input.ReadPrimitiveArray(pbd::FieldType.Fixed32, tag, field_name, result.repeatedFixed32_);

               break;

             }

             case 305: {

-              AddRepeatedFixed64(input.ReadFixed64());

+              input.ReadPrimitiveArray(pbd::FieldType.Fixed64, tag, field_name, result.repeatedFixed64_);

               break;

             }

             case 317: {

-              AddRepeatedSfixed32(input.ReadSFixed32());

+              input.ReadPrimitiveArray(pbd::FieldType.SFixed32, tag, field_name, result.repeatedSfixed32_);

               break;

             }

             case 321: {

-              AddRepeatedSfixed64(input.ReadSFixed64());

+              input.ReadPrimitiveArray(pbd::FieldType.SFixed64, tag, field_name, result.repeatedSfixed64_);

               break;

             }

             case 333: {

-              AddRepeatedFloat(input.ReadFloat());

+              input.ReadPrimitiveArray(pbd::FieldType.Float, tag, field_name, result.repeatedFloat_);

               break;

             }

             case 337: {

-              AddRepeatedDouble(input.ReadDouble());

+              input.ReadPrimitiveArray(pbd::FieldType.Double, tag, field_name, result.repeatedDouble_);

               break;

             }

             case 344: {

-              AddRepeatedBool(input.ReadBool());

+              input.ReadPrimitiveArray(pbd::FieldType.Bool, tag, field_name, result.repeatedBool_);

               break;

             }

             case 354: {

-              AddRepeatedString(input.ReadString());

+              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedString_);

               break;

             }

             case 362: {

-              AddRepeatedBytes(input.ReadBytes());

+              input.ReadPrimitiveArray(pbd::FieldType.Bytes, tag, field_name, result.repeatedBytes_);

               break;

             }

             case 371: {

-              global::Google.ProtocolBuffers.TestProtos.TestAllTypesLite.Types.RepeatedGroup.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestAllTypesLite.Types.RepeatedGroup.CreateBuilder();

-              input.ReadGroup(46, subBuilder, extensionRegistry);

-              AddRepeatedGroup(subBuilder.BuildPartial());

+              input.ReadGroupArray(tag, field_name, result.repeatedGroup_, global::Google.ProtocolBuffers.TestProtos.TestAllTypesLite.Types.RepeatedGroup.DefaultInstance, extensionRegistry);

               break;

             }

             case 386: {

-              global::Google.ProtocolBuffers.TestProtos.TestAllTypesLite.Types.NestedMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestAllTypesLite.Types.NestedMessage.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddRepeatedNestedMessage(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.repeatedNestedMessage_, global::Google.ProtocolBuffers.TestProtos.TestAllTypesLite.Types.NestedMessage.DefaultInstance, extensionRegistry);

               break;

             }

             case 394: {

-              global::Google.ProtocolBuffers.TestProtos.ForeignMessageLite.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.ForeignMessageLite.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddRepeatedForeignMessage(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.repeatedForeignMessage_, global::Google.ProtocolBuffers.TestProtos.ForeignMessageLite.DefaultInstance, extensionRegistry);

               break;

             }

             case 402: {

-              global::Google.ProtocolBuffers.TestProtos.ImportMessageLite.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.ImportMessageLite.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddRepeatedImportMessage(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.repeatedImportMessage_, global::Google.ProtocolBuffers.TestProtos.ImportMessageLite.DefaultInstance, extensionRegistry);

               break;

             }

             case 408: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.TestAllTypesLite.Types.NestedEnum), rawValue)) {

-              } else {

-                AddRepeatedNestedEnum((global::Google.ProtocolBuffers.TestProtos.TestAllTypesLite.Types.NestedEnum) rawValue);

-              }

+              scg::ICollection<object> unknownItems;

+              input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.TestAllTypesLite.Types.NestedEnum>(tag, field_name, result.repeatedNestedEnum_, out unknownItems);

               break;

             }

             case 416: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnumLite), rawValue)) {

-              } else {

-                AddRepeatedForeignEnum((global::Google.ProtocolBuffers.TestProtos.ForeignEnumLite) rawValue);

-              }

+              scg::ICollection<object> unknownItems;

+              input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.ForeignEnumLite>(tag, field_name, result.repeatedForeignEnum_, out unknownItems);

               break;

             }

             case 424: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ImportEnumLite), rawValue)) {

-              } else {

-                AddRepeatedImportEnum((global::Google.ProtocolBuffers.TestProtos.ImportEnumLite) rawValue);

-              }

+              scg::ICollection<object> unknownItems;

+              input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.ImportEnumLite>(tag, field_name, result.repeatedImportEnum_, out unknownItems);

               break;

             }

             case 434: {

-              AddRepeatedStringPiece(input.ReadString());

+              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedStringPiece_);

               break;

             }

             case 442: {

-              AddRepeatedCord(input.ReadString());

+              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedCord_);

               break;

             }

             case 488: {

-              DefaultInt32 = input.ReadInt32();

+              result.hasDefaultInt32 |= input.ReadInt32(ref result.defaultInt32_);

               break;

             }

             case 496: {

-              DefaultInt64 = input.ReadInt64();

+              result.hasDefaultInt64 |= input.ReadInt64(ref result.defaultInt64_);

               break;

             }

             case 504: {

-              DefaultUint32 = input.ReadUInt32();

+              result.hasDefaultUint32 |= input.ReadUInt32(ref result.defaultUint32_);

               break;

             }

             case 512: {

-              DefaultUint64 = input.ReadUInt64();

+              result.hasDefaultUint64 |= input.ReadUInt64(ref result.defaultUint64_);

               break;

             }

             case 520: {

-              DefaultSint32 = input.ReadSInt32();

+              result.hasDefaultSint32 |= input.ReadSInt32(ref result.defaultSint32_);

               break;

             }

             case 528: {

-              DefaultSint64 = input.ReadSInt64();

+              result.hasDefaultSint64 |= input.ReadSInt64(ref result.defaultSint64_);

               break;

             }

             case 541: {

-              DefaultFixed32 = input.ReadFixed32();

+              result.hasDefaultFixed32 |= input.ReadFixed32(ref result.defaultFixed32_);

               break;

             }

             case 545: {

-              DefaultFixed64 = input.ReadFixed64();

+              result.hasDefaultFixed64 |= input.ReadFixed64(ref result.defaultFixed64_);

               break;

             }

             case 557: {

-              DefaultSfixed32 = input.ReadSFixed32();

+              result.hasDefaultSfixed32 |= input.ReadSFixed32(ref result.defaultSfixed32_);

               break;

             }

             case 561: {

-              DefaultSfixed64 = input.ReadSFixed64();

+              result.hasDefaultSfixed64 |= input.ReadSFixed64(ref result.defaultSfixed64_);

               break;

             }

             case 573: {

-              DefaultFloat = input.ReadFloat();

+              result.hasDefaultFloat |= input.ReadFloat(ref result.defaultFloat_);

               break;

             }

             case 577: {

-              DefaultDouble = input.ReadDouble();

+              result.hasDefaultDouble |= input.ReadDouble(ref result.defaultDouble_);

               break;

             }

             case 584: {

-              DefaultBool = input.ReadBool();

+              result.hasDefaultBool |= input.ReadBool(ref result.defaultBool_);

               break;

             }

             case 594: {

-              DefaultString = input.ReadString();

+              result.hasDefaultString |= input.ReadString(ref result.defaultString_);

               break;

             }

             case 602: {

-              DefaultBytes = input.ReadBytes();

+              result.hasDefaultBytes |= input.ReadBytes(ref result.defaultBytes_);

               break;

             }

             case 648: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.TestAllTypesLite.Types.NestedEnum), rawValue)) {

-              } else {

-                DefaultNestedEnum = (global::Google.ProtocolBuffers.TestProtos.TestAllTypesLite.Types.NestedEnum) rawValue;

+              object unknown;

+              if(input.ReadEnum(ref result.defaultNestedEnum_, out unknown)) {

+                result.hasDefaultNestedEnum = true;

+              } else if(unknown is int) {

               }

               break;

             }

             case 656: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnumLite), rawValue)) {

-              } else {

-                DefaultForeignEnum = (global::Google.ProtocolBuffers.TestProtos.ForeignEnumLite) rawValue;

+              object unknown;

+              if(input.ReadEnum(ref result.defaultForeignEnum_, out unknown)) {

+                result.hasDefaultForeignEnum = true;

+              } else if(unknown is int) {

               }

               break;

             }

             case 664: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ImportEnumLite), rawValue)) {

-              } else {

-                DefaultImportEnum = (global::Google.ProtocolBuffers.TestProtos.ImportEnumLite) rawValue;

+              object unknown;

+              if(input.ReadEnum(ref result.defaultImportEnum_, out unknown)) {

+                result.hasDefaultImportEnum = true;

+              } else if(unknown is int) {

               }

               break;

             }

             case 674: {

-              DefaultStringPiece = input.ReadString();

+              result.hasDefaultStringPiece |= input.ReadString(ref result.defaultStringPiece_);

               break;

             }

             case 682: {

-              DefaultCord = input.ReadString();

+              result.hasDefaultCord |= input.ReadString(ref result.defaultCord_);

               break;

             }

           }

@@ -5747,11 +5730,11 @@
               if (pb::WireFormat.IsEndGroupTag(tag)) {

                 return this;

               }

-              ParseUnknownField(input, extensionRegistry, tag);

+              ParseUnknownField(input, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              C = input.ReadInt32();

+              result.hasC |= input.ReadInt32(ref result.c_);

               break;

             }

           }

@@ -6456,137 +6439,64 @@
               if (pb::WireFormat.IsEndGroupTag(tag)) {

                 return this;

               }

-              ParseUnknownField(input, extensionRegistry, tag);

+              ParseUnknownField(input, extensionRegistry, tag, field_name);

               break;

             }

             case 722: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedInt32(input.ReadInt32());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.Int32, tag, field_name, result.packedInt32_);

               break;

             }

             case 730: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedInt64(input.ReadInt64());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.Int64, tag, field_name, result.packedInt64_);

               break;

             }

             case 738: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedUint32(input.ReadUInt32());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.UInt32, tag, field_name, result.packedUint32_);

               break;

             }

             case 746: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedUint64(input.ReadUInt64());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.UInt64, tag, field_name, result.packedUint64_);

               break;

             }

             case 754: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedSint32(input.ReadSInt32());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.SInt32, tag, field_name, result.packedSint32_);

               break;

             }

             case 762: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedSint64(input.ReadSInt64());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.SInt64, tag, field_name, result.packedSint64_);

               break;

             }

             case 770: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedFixed32(input.ReadFixed32());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.Fixed32, tag, field_name, result.packedFixed32_);

               break;

             }

             case 778: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedFixed64(input.ReadFixed64());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.Fixed64, tag, field_name, result.packedFixed64_);

               break;

             }

             case 786: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedSfixed32(input.ReadSFixed32());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.SFixed32, tag, field_name, result.packedSfixed32_);

               break;

             }

             case 794: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedSfixed64(input.ReadSFixed64());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.SFixed64, tag, field_name, result.packedSfixed64_);

               break;

             }

             case 802: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedFloat(input.ReadFloat());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.Float, tag, field_name, result.packedFloat_);

               break;

             }

             case 810: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedDouble(input.ReadDouble());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.Double, tag, field_name, result.packedDouble_);

               break;

             }

             case 818: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedBool(input.ReadBool());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.Bool, tag, field_name, result.packedBool_);

               break;

             }

             case 826: {

-              int length = input.ReadInt32();

-              int oldLimit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                int rawValue = input.ReadEnum();

-                if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnumLite), rawValue)) {

-                } else {

-                  AddPackedEnum((global::Google.ProtocolBuffers.TestProtos.ForeignEnumLite) rawValue);

-                }

-              }

-              input.PopLimit(oldLimit);

+              scg::ICollection<object> unknownItems;

+              input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.ForeignEnumLite>(tag, field_name, result.packedEnum_, out unknownItems);

               break;

             }

           }

@@ -7152,7 +7062,7 @@
               if (pb::WireFormat.IsEndGroupTag(tag)) {

                 return this;

               }

-              ParseUnknownField(input, extensionRegistry, tag);

+              ParseUnknownField(input, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -7348,11 +7258,11 @@
               if (pb::WireFormat.IsEndGroupTag(tag)) {

                 return this;

               }

-              ParseUnknownField(input, extensionRegistry, tag);

+              ParseUnknownField(input, extensionRegistry, tag, field_name);

               break;

             }

             case 136: {

-              A = input.ReadInt32();

+              result.hasA |= input.ReadInt32(ref result.a_);

               break;

             }

           }

@@ -7566,11 +7476,11 @@
               if (pb::WireFormat.IsEndGroupTag(tag)) {

                 return this;

               }

-              ParseUnknownField(input, extensionRegistry, tag);

+              ParseUnknownField(input, extensionRegistry, tag, field_name);

               break;

             }

             case 376: {

-              A = input.ReadInt32();

+              result.hasA |= input.ReadInt32(ref result.a_);

               break;

             }

           }

@@ -7770,7 +7680,7 @@
               if (pb::WireFormat.IsEndGroupTag(tag)) {

                 return this;

               }

-              ParseUnknownField(input, extensionRegistry, tag);

+              ParseUnknownField(input, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -7946,7 +7856,7 @@
               if (pb::WireFormat.IsEndGroupTag(tag)) {

                 return this;

               }

-              ParseUnknownField(input, extensionRegistry, tag);

+              ParseUnknownField(input, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -8142,11 +8052,11 @@
               if (pb::WireFormat.IsEndGroupTag(tag)) {

                 return this;

               }

-              ParseUnknownField(input, extensionRegistry, tag);

+              ParseUnknownField(input, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              DeprecatedField = input.ReadInt32();

+              result.hasDeprecatedField |= input.ReadInt32(ref result.deprecatedField_);

               break;

             }

           }

diff --git a/src/ProtocolBuffersLite.Test/TestProtos/UnitTestProtoFile.cs b/src/ProtocolBuffersLite.Test/TestProtos/UnitTestProtoFile.cs
index ce2fbc8..d564a02 100644
--- a/src/ProtocolBuffersLite.Test/TestProtos/UnitTestProtoFile.cs
+++ b/src/ProtocolBuffersLite.Test/TestProtos/UnitTestProtoFile.cs
@@ -1246,11 +1246,11 @@
                   if (unknownFields == null) {

                     unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                   }

-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 8: {

-                  Bb = input.ReadInt32();

+                  result.hasBb |= input.ReadInt32(ref result.bb_);

                   break;

                 }

               }

@@ -1470,11 +1470,11 @@
                   if (unknownFields == null) {

                     unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                   }

-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 136: {

-                  A = input.ReadInt32();

+                  result.hasA |= input.ReadInt32(ref result.a_);

                   break;

                 }

               }

@@ -1694,11 +1694,11 @@
                   if (unknownFields == null) {

                     unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                   }

-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 376: {

-                  A = input.ReadInt32();

+                  result.hasA |= input.ReadInt32(ref result.a_);

                   break;

                 }

               }

@@ -3349,67 +3349,67 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              OptionalInt32 = input.ReadInt32();

+              result.hasOptionalInt32 |= input.ReadInt32(ref result.optionalInt32_);

               break;

             }

             case 16: {

-              OptionalInt64 = input.ReadInt64();

+              result.hasOptionalInt64 |= input.ReadInt64(ref result.optionalInt64_);

               break;

             }

             case 24: {

-              OptionalUint32 = input.ReadUInt32();

+              result.hasOptionalUint32 |= input.ReadUInt32(ref result.optionalUint32_);

               break;

             }

             case 32: {

-              OptionalUint64 = input.ReadUInt64();

+              result.hasOptionalUint64 |= input.ReadUInt64(ref result.optionalUint64_);

               break;

             }

             case 40: {

-              OptionalSint32 = input.ReadSInt32();

+              result.hasOptionalSint32 |= input.ReadSInt32(ref result.optionalSint32_);

               break;

             }

             case 48: {

-              OptionalSint64 = input.ReadSInt64();

+              result.hasOptionalSint64 |= input.ReadSInt64(ref result.optionalSint64_);

               break;

             }

             case 61: {

-              OptionalFixed32 = input.ReadFixed32();

+              result.hasOptionalFixed32 |= input.ReadFixed32(ref result.optionalFixed32_);

               break;

             }

             case 65: {

-              OptionalFixed64 = input.ReadFixed64();

+              result.hasOptionalFixed64 |= input.ReadFixed64(ref result.optionalFixed64_);

               break;

             }

             case 77: {

-              OptionalSfixed32 = input.ReadSFixed32();

+              result.hasOptionalSfixed32 |= input.ReadSFixed32(ref result.optionalSfixed32_);

               break;

             }

             case 81: {

-              OptionalSfixed64 = input.ReadSFixed64();

+              result.hasOptionalSfixed64 |= input.ReadSFixed64(ref result.optionalSfixed64_);

               break;

             }

             case 93: {

-              OptionalFloat = input.ReadFloat();

+              result.hasOptionalFloat |= input.ReadFloat(ref result.optionalFloat_);

               break;

             }

             case 97: {

-              OptionalDouble = input.ReadDouble();

+              result.hasOptionalDouble |= input.ReadDouble(ref result.optionalDouble_);

               break;

             }

             case 104: {

-              OptionalBool = input.ReadBool();

+              result.hasOptionalBool |= input.ReadBool(ref result.optionalBool_);

               break;

             }

             case 114: {

-              OptionalString = input.ReadString();

+              result.hasOptionalString |= input.ReadString(ref result.optionalString_);

               break;

             }

             case 122: {

-              OptionalBytes = input.ReadBytes();

+              result.hasOptionalBytes |= input.ReadBytes(ref result.optionalBytes_);

               break;

             }

             case 131: {

@@ -3449,279 +3449,274 @@
               break;

             }

             case 168: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum), rawValue)) {

+              object unknown;

+              if(input.ReadEnum(ref result.optionalNestedEnum_, out unknown)) {

+                result.hasOptionalNestedEnum = true;

+              } else if(unknown is int) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(21, (ulong) rawValue);

-              } else {

-                OptionalNestedEnum = (global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum) rawValue;

+                unknownFields.MergeVarintField(21, (ulong)(int)unknown);

               }

               break;

             }

             case 176: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnum), rawValue)) {

+              object unknown;

+              if(input.ReadEnum(ref result.optionalForeignEnum_, out unknown)) {

+                result.hasOptionalForeignEnum = true;

+              } else if(unknown is int) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(22, (ulong) rawValue);

-              } else {

-                OptionalForeignEnum = (global::Google.ProtocolBuffers.TestProtos.ForeignEnum) rawValue;

+                unknownFields.MergeVarintField(22, (ulong)(int)unknown);

               }

               break;

             }

             case 184: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ImportEnum), rawValue)) {

+              object unknown;

+              if(input.ReadEnum(ref result.optionalImportEnum_, out unknown)) {

+                result.hasOptionalImportEnum = true;

+              } else if(unknown is int) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(23, (ulong) rawValue);

-              } else {

-                OptionalImportEnum = (global::Google.ProtocolBuffers.TestProtos.ImportEnum) rawValue;

+                unknownFields.MergeVarintField(23, (ulong)(int)unknown);

               }

               break;

             }

             case 194: {

-              OptionalStringPiece = input.ReadString();

+              result.hasOptionalStringPiece |= input.ReadString(ref result.optionalStringPiece_);

               break;

             }

             case 202: {

-              OptionalCord = input.ReadString();

+              result.hasOptionalCord |= input.ReadString(ref result.optionalCord_);

               break;

             }

             case 248: {

-              AddRepeatedInt32(input.ReadInt32());

+              input.ReadPrimitiveArray(pbd::FieldType.Int32, tag, field_name, result.repeatedInt32_);

               break;

             }

             case 256: {

-              AddRepeatedInt64(input.ReadInt64());

+              input.ReadPrimitiveArray(pbd::FieldType.Int64, tag, field_name, result.repeatedInt64_);

               break;

             }

             case 264: {

-              AddRepeatedUint32(input.ReadUInt32());

+              input.ReadPrimitiveArray(pbd::FieldType.UInt32, tag, field_name, result.repeatedUint32_);

               break;

             }

             case 272: {

-              AddRepeatedUint64(input.ReadUInt64());

+              input.ReadPrimitiveArray(pbd::FieldType.UInt64, tag, field_name, result.repeatedUint64_);

               break;

             }

             case 280: {

-              AddRepeatedSint32(input.ReadSInt32());

+              input.ReadPrimitiveArray(pbd::FieldType.SInt32, tag, field_name, result.repeatedSint32_);

               break;

             }

             case 288: {

-              AddRepeatedSint64(input.ReadSInt64());

+              input.ReadPrimitiveArray(pbd::FieldType.SInt64, tag, field_name, result.repeatedSint64_);

               break;

             }

             case 301: {

-              AddRepeatedFixed32(input.ReadFixed32());

+              input.ReadPrimitiveArray(pbd::FieldType.Fixed32, tag, field_name, result.repeatedFixed32_);

               break;

             }

             case 305: {

-              AddRepeatedFixed64(input.ReadFixed64());

+              input.ReadPrimitiveArray(pbd::FieldType.Fixed64, tag, field_name, result.repeatedFixed64_);

               break;

             }

             case 317: {

-              AddRepeatedSfixed32(input.ReadSFixed32());

+              input.ReadPrimitiveArray(pbd::FieldType.SFixed32, tag, field_name, result.repeatedSfixed32_);

               break;

             }

             case 321: {

-              AddRepeatedSfixed64(input.ReadSFixed64());

+              input.ReadPrimitiveArray(pbd::FieldType.SFixed64, tag, field_name, result.repeatedSfixed64_);

               break;

             }

             case 333: {

-              AddRepeatedFloat(input.ReadFloat());

+              input.ReadPrimitiveArray(pbd::FieldType.Float, tag, field_name, result.repeatedFloat_);

               break;

             }

             case 337: {

-              AddRepeatedDouble(input.ReadDouble());

+              input.ReadPrimitiveArray(pbd::FieldType.Double, tag, field_name, result.repeatedDouble_);

               break;

             }

             case 344: {

-              AddRepeatedBool(input.ReadBool());

+              input.ReadPrimitiveArray(pbd::FieldType.Bool, tag, field_name, result.repeatedBool_);

               break;

             }

             case 354: {

-              AddRepeatedString(input.ReadString());

+              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedString_);

               break;

             }

             case 362: {

-              AddRepeatedBytes(input.ReadBytes());

+              input.ReadPrimitiveArray(pbd::FieldType.Bytes, tag, field_name, result.repeatedBytes_);

               break;

             }

             case 371: {

-              global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup.CreateBuilder();

-              input.ReadGroup(46, subBuilder, extensionRegistry);

-              AddRepeatedGroup(subBuilder.BuildPartial());

+              input.ReadGroupArray(tag, field_name, result.repeatedGroup_, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.RepeatedGroup.DefaultInstance, extensionRegistry);

               break;

             }

             case 386: {

-              global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddRepeatedNestedMessage(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.repeatedNestedMessage_, global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedMessage.DefaultInstance, extensionRegistry);

               break;

             }

             case 394: {

-              global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.ForeignMessage.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddRepeatedForeignMessage(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.repeatedForeignMessage_, global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance, extensionRegistry);

               break;

             }

             case 402: {

-              global::Google.ProtocolBuffers.TestProtos.ImportMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.ImportMessage.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddRepeatedImportMessage(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.repeatedImportMessage_, global::Google.ProtocolBuffers.TestProtos.ImportMessage.DefaultInstance, extensionRegistry);

               break;

             }

             case 408: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum), rawValue)) {

+              scg::ICollection<object> unknownItems;

+              input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum>(tag, field_name, result.repeatedNestedEnum_, out unknownItems);

+              if (unknownItems != null) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(51, (ulong) rawValue);

-              } else {

-                AddRepeatedNestedEnum((global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum) rawValue);

+                foreach (object rawValue in unknownItems)

+                  if (rawValue is int)

+                    unknownFields.MergeVarintField(51, (ulong)(int)rawValue);

               }

               break;

             }

             case 416: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnum), rawValue)) {

+              scg::ICollection<object> unknownItems;

+              input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>(tag, field_name, result.repeatedForeignEnum_, out unknownItems);

+              if (unknownItems != null) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(52, (ulong) rawValue);

-              } else {

-                AddRepeatedForeignEnum((global::Google.ProtocolBuffers.TestProtos.ForeignEnum) rawValue);

+                foreach (object rawValue in unknownItems)

+                  if (rawValue is int)

+                    unknownFields.MergeVarintField(52, (ulong)(int)rawValue);

               }

               break;

             }

             case 424: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ImportEnum), rawValue)) {

+              scg::ICollection<object> unknownItems;

+              input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.ImportEnum>(tag, field_name, result.repeatedImportEnum_, out unknownItems);

+              if (unknownItems != null) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(53, (ulong) rawValue);

-              } else {

-                AddRepeatedImportEnum((global::Google.ProtocolBuffers.TestProtos.ImportEnum) rawValue);

+                foreach (object rawValue in unknownItems)

+                  if (rawValue is int)

+                    unknownFields.MergeVarintField(53, (ulong)(int)rawValue);

               }

               break;

             }

             case 434: {

-              AddRepeatedStringPiece(input.ReadString());

+              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedStringPiece_);

               break;

             }

             case 442: {

-              AddRepeatedCord(input.ReadString());

+              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedCord_);

               break;

             }

             case 488: {

-              DefaultInt32 = input.ReadInt32();

+              result.hasDefaultInt32 |= input.ReadInt32(ref result.defaultInt32_);

               break;

             }

             case 496: {

-              DefaultInt64 = input.ReadInt64();

+              result.hasDefaultInt64 |= input.ReadInt64(ref result.defaultInt64_);

               break;

             }

             case 504: {

-              DefaultUint32 = input.ReadUInt32();

+              result.hasDefaultUint32 |= input.ReadUInt32(ref result.defaultUint32_);

               break;

             }

             case 512: {

-              DefaultUint64 = input.ReadUInt64();

+              result.hasDefaultUint64 |= input.ReadUInt64(ref result.defaultUint64_);

               break;

             }

             case 520: {

-              DefaultSint32 = input.ReadSInt32();

+              result.hasDefaultSint32 |= input.ReadSInt32(ref result.defaultSint32_);

               break;

             }

             case 528: {

-              DefaultSint64 = input.ReadSInt64();

+              result.hasDefaultSint64 |= input.ReadSInt64(ref result.defaultSint64_);

               break;

             }

             case 541: {

-              DefaultFixed32 = input.ReadFixed32();

+              result.hasDefaultFixed32 |= input.ReadFixed32(ref result.defaultFixed32_);

               break;

             }

             case 545: {

-              DefaultFixed64 = input.ReadFixed64();

+              result.hasDefaultFixed64 |= input.ReadFixed64(ref result.defaultFixed64_);

               break;

             }

             case 557: {

-              DefaultSfixed32 = input.ReadSFixed32();

+              result.hasDefaultSfixed32 |= input.ReadSFixed32(ref result.defaultSfixed32_);

               break;

             }

             case 561: {

-              DefaultSfixed64 = input.ReadSFixed64();

+              result.hasDefaultSfixed64 |= input.ReadSFixed64(ref result.defaultSfixed64_);

               break;

             }

             case 573: {

-              DefaultFloat = input.ReadFloat();

+              result.hasDefaultFloat |= input.ReadFloat(ref result.defaultFloat_);

               break;

             }

             case 577: {

-              DefaultDouble = input.ReadDouble();

+              result.hasDefaultDouble |= input.ReadDouble(ref result.defaultDouble_);

               break;

             }

             case 584: {

-              DefaultBool = input.ReadBool();

+              result.hasDefaultBool |= input.ReadBool(ref result.defaultBool_);

               break;

             }

             case 594: {

-              DefaultString = input.ReadString();

+              result.hasDefaultString |= input.ReadString(ref result.defaultString_);

               break;

             }

             case 602: {

-              DefaultBytes = input.ReadBytes();

+              result.hasDefaultBytes |= input.ReadBytes(ref result.defaultBytes_);

               break;

             }

             case 648: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum), rawValue)) {

+              object unknown;

+              if(input.ReadEnum(ref result.defaultNestedEnum_, out unknown)) {

+                result.hasDefaultNestedEnum = true;

+              } else if(unknown is int) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(81, (ulong) rawValue);

-              } else {

-                DefaultNestedEnum = (global::Google.ProtocolBuffers.TestProtos.TestAllTypes.Types.NestedEnum) rawValue;

+                unknownFields.MergeVarintField(81, (ulong)(int)unknown);

               }

               break;

             }

             case 656: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnum), rawValue)) {

+              object unknown;

+              if(input.ReadEnum(ref result.defaultForeignEnum_, out unknown)) {

+                result.hasDefaultForeignEnum = true;

+              } else if(unknown is int) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(82, (ulong) rawValue);

-              } else {

-                DefaultForeignEnum = (global::Google.ProtocolBuffers.TestProtos.ForeignEnum) rawValue;

+                unknownFields.MergeVarintField(82, (ulong)(int)unknown);

               }

               break;

             }

             case 664: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ImportEnum), rawValue)) {

+              object unknown;

+              if(input.ReadEnum(ref result.defaultImportEnum_, out unknown)) {

+                result.hasDefaultImportEnum = true;

+              } else if(unknown is int) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(83, (ulong) rawValue);

-              } else {

-                DefaultImportEnum = (global::Google.ProtocolBuffers.TestProtos.ImportEnum) rawValue;

+                unknownFields.MergeVarintField(83, (ulong)(int)unknown);

               }

               break;

             }

             case 674: {

-              DefaultStringPiece = input.ReadString();

+              result.hasDefaultStringPiece |= input.ReadString(ref result.defaultStringPiece_);

               break;

             }

             case 682: {

-              DefaultCord = input.ReadString();

+              result.hasDefaultCord |= input.ReadString(ref result.defaultCord_);

               break;

             }

           }

@@ -5511,11 +5506,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              DeprecatedInt32 = input.ReadInt32();

+              result.hasDeprecatedInt32 |= input.ReadInt32(ref result.deprecatedInt32_);

               break;

             }

           }

@@ -5735,11 +5730,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              C = input.ReadInt32();

+              result.hasC |= input.ReadInt32(ref result.c_);

               break;

             }

           }

@@ -5945,7 +5940,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -6147,11 +6142,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 136: {

-              A = input.ReadInt32();

+              result.hasA |= input.ReadInt32(ref result.a_);

               break;

             }

           }

@@ -6371,11 +6366,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 376: {

-              A = input.ReadInt32();

+              result.hasA |= input.ReadInt32(ref result.a_);

               break;

             }

           }

@@ -6578,7 +6573,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -7395,139 +7390,139 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              A = input.ReadInt32();

+              result.hasA |= input.ReadInt32(ref result.a_);

               break;

             }

             case 16: {

-              Dummy2 = input.ReadInt32();

+              result.hasDummy2 |= input.ReadInt32(ref result.dummy2_);

               break;

             }

             case 24: {

-              B = input.ReadInt32();

+              result.hasB |= input.ReadInt32(ref result.b_);

               break;

             }

             case 32: {

-              Dummy4 = input.ReadInt32();

+              result.hasDummy4 |= input.ReadInt32(ref result.dummy4_);

               break;

             }

             case 40: {

-              Dummy5 = input.ReadInt32();

+              result.hasDummy5 |= input.ReadInt32(ref result.dummy5_);

               break;

             }

             case 48: {

-              Dummy6 = input.ReadInt32();

+              result.hasDummy6 |= input.ReadInt32(ref result.dummy6_);

               break;

             }

             case 56: {

-              Dummy7 = input.ReadInt32();

+              result.hasDummy7 |= input.ReadInt32(ref result.dummy7_);

               break;

             }

             case 64: {

-              Dummy8 = input.ReadInt32();

+              result.hasDummy8 |= input.ReadInt32(ref result.dummy8_);

               break;

             }

             case 72: {

-              Dummy9 = input.ReadInt32();

+              result.hasDummy9 |= input.ReadInt32(ref result.dummy9_);

               break;

             }

             case 80: {

-              Dummy10 = input.ReadInt32();

+              result.hasDummy10 |= input.ReadInt32(ref result.dummy10_);

               break;

             }

             case 88: {

-              Dummy11 = input.ReadInt32();

+              result.hasDummy11 |= input.ReadInt32(ref result.dummy11_);

               break;

             }

             case 96: {

-              Dummy12 = input.ReadInt32();

+              result.hasDummy12 |= input.ReadInt32(ref result.dummy12_);

               break;

             }

             case 104: {

-              Dummy13 = input.ReadInt32();

+              result.hasDummy13 |= input.ReadInt32(ref result.dummy13_);

               break;

             }

             case 112: {

-              Dummy14 = input.ReadInt32();

+              result.hasDummy14 |= input.ReadInt32(ref result.dummy14_);

               break;

             }

             case 120: {

-              Dummy15 = input.ReadInt32();

+              result.hasDummy15 |= input.ReadInt32(ref result.dummy15_);

               break;

             }

             case 128: {

-              Dummy16 = input.ReadInt32();

+              result.hasDummy16 |= input.ReadInt32(ref result.dummy16_);

               break;

             }

             case 136: {

-              Dummy17 = input.ReadInt32();

+              result.hasDummy17 |= input.ReadInt32(ref result.dummy17_);

               break;

             }

             case 144: {

-              Dummy18 = input.ReadInt32();

+              result.hasDummy18 |= input.ReadInt32(ref result.dummy18_);

               break;

             }

             case 152: {

-              Dummy19 = input.ReadInt32();

+              result.hasDummy19 |= input.ReadInt32(ref result.dummy19_);

               break;

             }

             case 160: {

-              Dummy20 = input.ReadInt32();

+              result.hasDummy20 |= input.ReadInt32(ref result.dummy20_);

               break;

             }

             case 168: {

-              Dummy21 = input.ReadInt32();

+              result.hasDummy21 |= input.ReadInt32(ref result.dummy21_);

               break;

             }

             case 176: {

-              Dummy22 = input.ReadInt32();

+              result.hasDummy22 |= input.ReadInt32(ref result.dummy22_);

               break;

             }

             case 184: {

-              Dummy23 = input.ReadInt32();

+              result.hasDummy23 |= input.ReadInt32(ref result.dummy23_);

               break;

             }

             case 192: {

-              Dummy24 = input.ReadInt32();

+              result.hasDummy24 |= input.ReadInt32(ref result.dummy24_);

               break;

             }

             case 200: {

-              Dummy25 = input.ReadInt32();

+              result.hasDummy25 |= input.ReadInt32(ref result.dummy25_);

               break;

             }

             case 208: {

-              Dummy26 = input.ReadInt32();

+              result.hasDummy26 |= input.ReadInt32(ref result.dummy26_);

               break;

             }

             case 216: {

-              Dummy27 = input.ReadInt32();

+              result.hasDummy27 |= input.ReadInt32(ref result.dummy27_);

               break;

             }

             case 224: {

-              Dummy28 = input.ReadInt32();

+              result.hasDummy28 |= input.ReadInt32(ref result.dummy28_);

               break;

             }

             case 232: {

-              Dummy29 = input.ReadInt32();

+              result.hasDummy29 |= input.ReadInt32(ref result.dummy29_);

               break;

             }

             case 240: {

-              Dummy30 = input.ReadInt32();

+              result.hasDummy30 |= input.ReadInt32(ref result.dummy30_);

               break;

             }

             case 248: {

-              Dummy31 = input.ReadInt32();

+              result.hasDummy31 |= input.ReadInt32(ref result.dummy31_);

               break;

             }

             case 256: {

-              Dummy32 = input.ReadInt32();

+              result.hasDummy32 |= input.ReadInt32(ref result.dummy32_);

               break;

             }

             case 264: {

-              C = input.ReadInt32();

+              result.hasC |= input.ReadInt32(ref result.c_);

               break;

             }

           }

@@ -8370,7 +8365,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

@@ -8383,13 +8378,11 @@
               break;

             }

             case 18: {

-              global::Google.ProtocolBuffers.TestProtos.TestRequired.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.TestRequired.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddRepeatedMessage(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.repeatedMessage_, global::Google.ProtocolBuffers.TestProtos.TestRequired.DefaultInstance, extensionRegistry);

               break;

             }

             case 24: {

-              Dummy = input.ReadInt32();

+              result.hasDummy |= input.ReadInt32(ref result.dummy_);

               break;

             }

           }

@@ -8683,7 +8676,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

@@ -8911,7 +8904,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -9099,7 +9092,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -9289,7 +9282,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -9510,15 +9503,15 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              A = input.ReadInt32();

+              result.hasA |= input.ReadInt32(ref result.a_);

               break;

             }

             case 2147483640: {

-              Bb = input.ReadInt32();

+              result.hasBb |= input.ReadInt32(ref result.bb_);

               break;

             }

           }

@@ -9775,7 +9768,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

@@ -9788,7 +9781,7 @@
               break;

             }

             case 16: {

-              I = input.ReadInt32();

+              result.hasI |= input.ReadInt32(ref result.i_);

               break;

             }

           }

@@ -10044,7 +10037,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

@@ -10310,7 +10303,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

@@ -10323,7 +10316,7 @@
               break;

             }

             case 16: {

-              OptionalInt32 = input.ReadInt32();

+              result.hasOptionalInt32 |= input.ReadInt32(ref result.optionalInt32_);

               break;

             }

           }

@@ -10609,11 +10602,11 @@
                   if (unknownFields == null) {

                     unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                   }

-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 8: {

-                  A = input.ReadInt32();

+                  result.hasA |= input.ReadInt32(ref result.a_);

                   break;

                 }

               }

@@ -10833,11 +10826,11 @@
                   if (unknownFields == null) {

                     unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                   }

-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 8: {

-                  A = input.ReadInt32();

+                  result.hasA |= input.ReadInt32(ref result.a_);

                   break;

                 }

               }

@@ -11073,11 +11066,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              A = input.ReadInt32();

+              result.hasA |= input.ReadInt32(ref result.a_);

               break;

             }

             case 19: {

@@ -11447,17 +11440,15 @@
                   if (unknownFields == null) {

                     unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                   }

-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 8: {

-                  AddNestedmessageRepeatedInt32(input.ReadInt32());

+                  input.ReadPrimitiveArray(pbd::FieldType.Int32, tag, field_name, result.nestedmessageRepeatedInt32_);

                   break;

                 }

                 case 18: {

-                  global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.ForeignMessage.CreateBuilder();

-                  input.ReadMessage(subBuilder, extensionRegistry);

-                  AddNestedmessageRepeatedForeignmessage(subBuilder.BuildPartial());

+                  input.ReadMessageArray(tag, field_name, result.nestedmessageRepeatedForeignmessage_, global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance, extensionRegistry);

                   break;

                 }

               }

@@ -11701,7 +11692,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

@@ -12202,26 +12193,26 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              PrimitiveField = input.ReadInt32();

+              result.hasPrimitiveField |= input.ReadInt32(ref result.primitiveField_);

               break;

             }

             case 18: {

-              StringField = input.ReadString();

+              result.hasStringField |= input.ReadString(ref result.stringField_);

               break;

             }

             case 24: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnum), rawValue)) {

+              object unknown;

+              if(input.ReadEnum(ref result.enumField_, out unknown)) {

+                result.hasEnumField = true;

+              } else if(unknown is int) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(3, (ulong) rawValue);

-              } else {

-                EnumField = (global::Google.ProtocolBuffers.TestProtos.ForeignEnum) rawValue;

+                unknownFields.MergeVarintField(3, (ulong)(int)unknown);

               }

               break;

             }

@@ -12235,45 +12226,44 @@
               break;

             }

             case 42: {

-              StringPieceField = input.ReadString();

+              result.hasStringPieceField |= input.ReadString(ref result.stringPieceField_);

               break;

             }

             case 50: {

-              CordField = input.ReadString();

+              result.hasCordField |= input.ReadString(ref result.cordField_);

               break;

             }

             case 56: {

-              AddRepeatedPrimitiveField(input.ReadInt32());

+              input.ReadPrimitiveArray(pbd::FieldType.Int32, tag, field_name, result.repeatedPrimitiveField_);

               break;

             }

             case 66: {

-              AddRepeatedStringField(input.ReadString());

+              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedStringField_);

               break;

             }

             case 72: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnum), rawValue)) {

+              scg::ICollection<object> unknownItems;

+              input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>(tag, field_name, result.repeatedEnumField_, out unknownItems);

+              if (unknownItems != null) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(9, (ulong) rawValue);

-              } else {

-                AddRepeatedEnumField((global::Google.ProtocolBuffers.TestProtos.ForeignEnum) rawValue);

+                foreach (object rawValue in unknownItems)

+                  if (rawValue is int)

+                    unknownFields.MergeVarintField(9, (ulong)(int)rawValue);

               }

               break;

             }

             case 82: {

-              global::Google.ProtocolBuffers.TestProtos.ForeignMessage.Builder subBuilder = global::Google.ProtocolBuffers.TestProtos.ForeignMessage.CreateBuilder();

-              input.ReadMessage(subBuilder, extensionRegistry);

-              AddRepeatedMessageField(subBuilder.BuildPartial());

+              input.ReadMessageArray(tag, field_name, result.repeatedMessageField_, global::Google.ProtocolBuffers.TestProtos.ForeignMessage.DefaultInstance, extensionRegistry);

               break;

             }

             case 90: {

-              AddRepeatedStringPieceField(input.ReadString());

+              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedStringPieceField_);

               break;

             }

             case 98: {

-              AddRepeatedCordField(input.ReadString());

+              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedCordField_);

               break;

             }

           }

@@ -12822,19 +12812,19 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 8: {

-              MyInt = input.ReadInt64();

+              result.hasMyInt |= input.ReadInt64(ref result.myInt_);

               break;

             }

             case 90: {

-              MyString = input.ReadString();

+              result.hasMyString |= input.ReadString(ref result.myString_);

               break;

             }

             case 813: {

-              MyFloat = input.ReadFloat();

+              result.hasMyFloat |= input.ReadFloat(ref result.myFloat_);

               break;

             }

           }

@@ -13435,83 +13425,83 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              EscapedBytes = input.ReadBytes();

+              result.hasEscapedBytes |= input.ReadBytes(ref result.escapedBytes_);

               break;

             }

             case 16: {

-              LargeUint32 = input.ReadUInt32();

+              result.hasLargeUint32 |= input.ReadUInt32(ref result.largeUint32_);

               break;

             }

             case 24: {

-              LargeUint64 = input.ReadUInt64();

+              result.hasLargeUint64 |= input.ReadUInt64(ref result.largeUint64_);

               break;

             }

             case 32: {

-              SmallInt32 = input.ReadInt32();

+              result.hasSmallInt32 |= input.ReadInt32(ref result.smallInt32_);

               break;

             }

             case 40: {

-              SmallInt64 = input.ReadInt64();

+              result.hasSmallInt64 |= input.ReadInt64(ref result.smallInt64_);

               break;

             }

             case 50: {

-              Utf8String = input.ReadString();

+              result.hasUtf8String |= input.ReadString(ref result.utf8String_);

               break;

             }

             case 61: {

-              ZeroFloat = input.ReadFloat();

+              result.hasZeroFloat |= input.ReadFloat(ref result.zeroFloat_);

               break;

             }

             case 69: {

-              OneFloat = input.ReadFloat();

+              result.hasOneFloat |= input.ReadFloat(ref result.oneFloat_);

               break;

             }

             case 77: {

-              SmallFloat = input.ReadFloat();

+              result.hasSmallFloat |= input.ReadFloat(ref result.smallFloat_);

               break;

             }

             case 85: {

-              NegativeOneFloat = input.ReadFloat();

+              result.hasNegativeOneFloat |= input.ReadFloat(ref result.negativeOneFloat_);

               break;

             }

             case 93: {

-              NegativeFloat = input.ReadFloat();

+              result.hasNegativeFloat |= input.ReadFloat(ref result.negativeFloat_);

               break;

             }

             case 101: {

-              LargeFloat = input.ReadFloat();

+              result.hasLargeFloat |= input.ReadFloat(ref result.largeFloat_);

               break;

             }

             case 109: {

-              SmallNegativeFloat = input.ReadFloat();

+              result.hasSmallNegativeFloat |= input.ReadFloat(ref result.smallNegativeFloat_);

               break;

             }

             case 113: {

-              InfDouble = input.ReadDouble();

+              result.hasInfDouble |= input.ReadDouble(ref result.infDouble_);

               break;

             }

             case 121: {

-              NegInfDouble = input.ReadDouble();

+              result.hasNegInfDouble |= input.ReadDouble(ref result.negInfDouble_);

               break;

             }

             case 129: {

-              NanDouble = input.ReadDouble();

+              result.hasNanDouble |= input.ReadDouble(ref result.nanDouble_);

               break;

             }

             case 141: {

-              InfFloat = input.ReadFloat();

+              result.hasInfFloat |= input.ReadFloat(ref result.infFloat_);

               break;

             }

             case 149: {

-              NegInfFloat = input.ReadFloat();

+              result.hasNegInfFloat |= input.ReadFloat(ref result.negInfFloat_);

               break;

             }

             case 157: {

-              NanFloat = input.ReadFloat();

+              result.hasNanFloat |= input.ReadFloat(ref result.nanFloat_);

               break;

             }

           }

@@ -14061,11 +14051,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              Data = input.ReadString();

+              result.hasData |= input.ReadString(ref result.data_);

               break;

             }

           }

@@ -14286,11 +14276,11 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 10: {

-              Data = input.ReadBytes();

+              result.hasData |= input.ReadBytes(ref result.data_);

               break;

             }

           }

@@ -14921,141 +14911,72 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 722: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedInt32(input.ReadInt32());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.Int32, tag, field_name, result.packedInt32_);

               break;

             }

             case 730: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedInt64(input.ReadInt64());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.Int64, tag, field_name, result.packedInt64_);

               break;

             }

             case 738: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedUint32(input.ReadUInt32());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.UInt32, tag, field_name, result.packedUint32_);

               break;

             }

             case 746: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedUint64(input.ReadUInt64());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.UInt64, tag, field_name, result.packedUint64_);

               break;

             }

             case 754: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedSint32(input.ReadSInt32());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.SInt32, tag, field_name, result.packedSint32_);

               break;

             }

             case 762: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedSint64(input.ReadSInt64());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.SInt64, tag, field_name, result.packedSint64_);

               break;

             }

             case 770: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedFixed32(input.ReadFixed32());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.Fixed32, tag, field_name, result.packedFixed32_);

               break;

             }

             case 778: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedFixed64(input.ReadFixed64());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.Fixed64, tag, field_name, result.packedFixed64_);

               break;

             }

             case 786: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedSfixed32(input.ReadSFixed32());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.SFixed32, tag, field_name, result.packedSfixed32_);

               break;

             }

             case 794: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedSfixed64(input.ReadSFixed64());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.SFixed64, tag, field_name, result.packedSfixed64_);

               break;

             }

             case 802: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedFloat(input.ReadFloat());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.Float, tag, field_name, result.packedFloat_);

               break;

             }

             case 810: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedDouble(input.ReadDouble());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.Double, tag, field_name, result.packedDouble_);

               break;

             }

             case 818: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedBool(input.ReadBool());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.Bool, tag, field_name, result.packedBool_);

               break;

             }

             case 826: {

-              int length = input.ReadInt32();

-              int oldLimit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                int rawValue = input.ReadEnum();

-                if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnum), rawValue)) {

-                  if (unknownFields == null) {

-                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

-                  }

-                  unknownFields.MergeVarintField(103, (ulong) rawValue);

-                } else {

-                  AddPackedEnum((global::Google.ProtocolBuffers.TestProtos.ForeignEnum) rawValue);

+              scg::ICollection<object> unknownItems;

+              input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>(tag, field_name, result.packedEnum_, out unknownItems);

+              if (unknownItems != null) {

+                if (unknownFields == null) {

+                  unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

+                foreach (object rawValue in unknownItems)

+                  if (rawValue is int)

+                    unknownFields.MergeVarintField(103, (ulong)(int)rawValue);

               }

-              input.PopLimit(oldLimit);

               break;

             }

           }

@@ -15996,70 +15917,71 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 720: {

-              AddUnpackedInt32(input.ReadInt32());

+              input.ReadPrimitiveArray(pbd::FieldType.Int32, tag, field_name, result.unpackedInt32_);

               break;

             }

             case 728: {

-              AddUnpackedInt64(input.ReadInt64());

+              input.ReadPrimitiveArray(pbd::FieldType.Int64, tag, field_name, result.unpackedInt64_);

               break;

             }

             case 736: {

-              AddUnpackedUint32(input.ReadUInt32());

+              input.ReadPrimitiveArray(pbd::FieldType.UInt32, tag, field_name, result.unpackedUint32_);

               break;

             }

             case 744: {

-              AddUnpackedUint64(input.ReadUInt64());

+              input.ReadPrimitiveArray(pbd::FieldType.UInt64, tag, field_name, result.unpackedUint64_);

               break;

             }

             case 752: {

-              AddUnpackedSint32(input.ReadSInt32());

+              input.ReadPrimitiveArray(pbd::FieldType.SInt32, tag, field_name, result.unpackedSint32_);

               break;

             }

             case 760: {

-              AddUnpackedSint64(input.ReadSInt64());

+              input.ReadPrimitiveArray(pbd::FieldType.SInt64, tag, field_name, result.unpackedSint64_);

               break;

             }

             case 773: {

-              AddUnpackedFixed32(input.ReadFixed32());

+              input.ReadPrimitiveArray(pbd::FieldType.Fixed32, tag, field_name, result.unpackedFixed32_);

               break;

             }

             case 777: {

-              AddUnpackedFixed64(input.ReadFixed64());

+              input.ReadPrimitiveArray(pbd::FieldType.Fixed64, tag, field_name, result.unpackedFixed64_);

               break;

             }

             case 789: {

-              AddUnpackedSfixed32(input.ReadSFixed32());

+              input.ReadPrimitiveArray(pbd::FieldType.SFixed32, tag, field_name, result.unpackedSfixed32_);

               break;

             }

             case 793: {

-              AddUnpackedSfixed64(input.ReadSFixed64());

+              input.ReadPrimitiveArray(pbd::FieldType.SFixed64, tag, field_name, result.unpackedSfixed64_);

               break;

             }

             case 805: {

-              AddUnpackedFloat(input.ReadFloat());

+              input.ReadPrimitiveArray(pbd::FieldType.Float, tag, field_name, result.unpackedFloat_);

               break;

             }

             case 809: {

-              AddUnpackedDouble(input.ReadDouble());

+              input.ReadPrimitiveArray(pbd::FieldType.Double, tag, field_name, result.unpackedDouble_);

               break;

             }

             case 816: {

-              AddUnpackedBool(input.ReadBool());

+              input.ReadPrimitiveArray(pbd::FieldType.Bool, tag, field_name, result.unpackedBool_);

               break;

             }

             case 824: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnum), rawValue)) {

+              scg::ICollection<object> unknownItems;

+              input.ReadEnumArray<global::Google.ProtocolBuffers.TestProtos.ForeignEnum>(tag, field_name, result.unpackedEnum_, out unknownItems);

+              if (unknownItems != null) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(103, (ulong) rawValue);

-              } else {

-                AddUnpackedEnum((global::Google.ProtocolBuffers.TestProtos.ForeignEnum) rawValue);

+                foreach (object rawValue in unknownItems)

+                  if (rawValue is int)

+                    unknownFields.MergeVarintField(103, (ulong)(int)rawValue);

               }

               break;

             }

@@ -16632,7 +16554,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -16872,11 +16794,11 @@
                   if (unknownFields == null) {

                     unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                   }

-                  ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

                   break;

                 }

                 case 16800: {

-                  DynamicField = input.ReadInt32();

+                  result.hasDynamicField |= input.ReadInt32(ref result.dynamicField_);

                   break;

                 }

               }

@@ -17209,34 +17131,34 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 16005: {

-              ScalarExtension = input.ReadFixed32();

+              result.hasScalarExtension |= input.ReadFixed32(ref result.scalarExtension_);

               break;

             }

             case 16008: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.ForeignEnum), rawValue)) {

+              object unknown;

+              if(input.ReadEnum(ref result.enumExtension_, out unknown)) {

+                result.hasEnumExtension = true;

+              } else if(unknown is int) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(2001, (ulong) rawValue);

-              } else {

-                EnumExtension = (global::Google.ProtocolBuffers.TestProtos.ForeignEnum) rawValue;

+                unknownFields.MergeVarintField(2001, (ulong)(int)unknown);

               }

               break;

             }

             case 16016: {

-              int rawValue = input.ReadEnum();

-              if (!global::System.Enum.IsDefined(typeof(global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicEnumType), rawValue)) {

+              object unknown;

+              if(input.ReadEnum(ref result.dynamicEnumExtension_, out unknown)) {

+                result.hasDynamicEnumExtension = true;

+              } else if(unknown is int) {

                 if (unknownFields == null) {

                   unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

                 }

-                unknownFields.MergeVarintField(2002, (ulong) rawValue);

-              } else {

-                DynamicEnumExtension = (global::Google.ProtocolBuffers.TestProtos.TestDynamicExtensions.Types.DynamicEnumType) rawValue;

+                unknownFields.MergeVarintField(2002, (ulong)(int)unknown);

               }

               break;

             }

@@ -17259,16 +17181,11 @@
               break;

             }

             case 16042: {

-              AddRepeatedExtension(input.ReadString());

+              input.ReadPrimitiveArray(pbd::FieldType.String, tag, field_name, result.repeatedExtension_);

               break;

             }

             case 16050: {

-              int length = input.ReadInt32();

-              int limit = input.PushLimit(length);

-              while (!input.ReachedLimit) {

-                AddPackedExtension(input.ReadSInt32());

-              }

-              input.PopLimit(limit);

+              input.ReadPrimitiveArray(pbd::FieldType.SInt32, tag, field_name, result.packedExtension_);

               break;

             }

           }

@@ -17795,31 +17712,31 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

             case 101: {

-              AddRepeatedFixed32(input.ReadFixed32());

+              input.ReadPrimitiveArray(pbd::FieldType.Fixed32, tag, field_name, result.repeatedFixed32_);

               break;

             }

             case 104: {

-              AddRepeatedInt32(input.ReadInt32());

+              input.ReadPrimitiveArray(pbd::FieldType.Int32, tag, field_name, result.repeatedInt32_);

               break;

             }

             case 16369: {

-              AddRepeatedFixed64(input.ReadFixed64());

+              input.ReadPrimitiveArray(pbd::FieldType.Fixed64, tag, field_name, result.repeatedFixed64_);

               break;

             }

             case 16376: {

-              AddRepeatedInt64(input.ReadInt64());

+              input.ReadPrimitiveArray(pbd::FieldType.Int64, tag, field_name, result.repeatedInt64_);

               break;

             }

             case 2097141: {

-              AddRepeatedFloat(input.ReadFloat());

+              input.ReadPrimitiveArray(pbd::FieldType.Float, tag, field_name, result.repeatedFloat_);

               break;

             }

             case 2097144: {

-              AddRepeatedUint64(input.ReadUInt64());

+              input.ReadPrimitiveArray(pbd::FieldType.UInt64, tag, field_name, result.repeatedUint64_);

               break;

             }

           }

@@ -18173,7 +18090,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -18356,7 +18273,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -18539,7 +18456,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }

@@ -18722,7 +18639,7 @@
               if (unknownFields == null) {

                 unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);

               }

-              ParseUnknownField(input, unknownFields, extensionRegistry, tag);

+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);

               break;

             }

           }