Sfoglia il codice sorgente

Finished adding find tag by name

csharptest 14 anni fa
parent
commit
920b09a3b0
33 ha cambiato i file con 2549 aggiunte e 1135 eliminazioni
  1. 56 11
      src/AddressBook/AddressBookProtos.cs
  2. 37 47
      src/ProtoBench/Program.cs
  3. 3 17
      src/ProtoGen/EnumFieldGenerator.cs
  4. 1 1
      src/ProtoGen/ExtensionGenerator.cs
  5. 6 1
      src/ProtoGen/FieldGeneratorBase.cs
  6. 3 3
      src/ProtoGen/MessageFieldGenerator.cs
  7. 73 11
      src/ProtoGen/MessageGenerator.cs
  8. 4 4
      src/ProtoGen/PrimitiveFieldGenerator.cs
  9. 6 4
      src/ProtoGen/ProtoGen.csproj
  10. 4 49
      src/ProtoGen/RepeatedEnumFieldGenerator.cs
  11. 3 23
      src/ProtoGen/RepeatedMessageFieldGenerator.cs
  12. 4 31
      src/ProtoGen/RepeatedPrimitiveFieldGenerator.cs
  13. 17 82
      src/ProtoGen/SourceGenerators.cs
  14. 21 6
      src/ProtocolBuffers.Test/TestProtos/UnitTestCSharpOptionsProtoFile.cs
  15. 276 21
      src/ProtocolBuffers.Test/TestProtos/UnitTestCustomOptionsProtoFile.cs
  16. 17 2
      src/ProtocolBuffers.Test/TestProtos/UnitTestEmbedOptimizeForProtoFile.cs
  17. 250 190
      src/ProtocolBuffers.Test/TestProtos/UnitTestGoogleSpeedProtoFile.cs
  18. 14 2
      src/ProtocolBuffers.Test/TestProtos/UnitTestImportLiteProtoFile.cs
  19. 17 2
      src/ProtocolBuffers.Test/TestProtos/UnitTestImportProtoFile.cs
  20. 100 10
      src/ProtocolBuffers.Test/TestProtos/UnitTestMessageSetProtoFile.cs
  21. 17 2
      src/ProtocolBuffers.Test/TestProtos/UnitTestNoGenericServicesProtoFile.cs
  22. 302 149
      src/ProtocolBuffers.Test/TestProtos/UnitTestProtoFile.cs
  23. 68 8
      src/ProtocolBuffers.Test/TestProtos/UnitTestRpcInterop.cs
  24. 93 18
      src/ProtocolBuffers.Test/TestProtos/UnitTestXmlSerializerTestProtoFile.cs
  25. 91 31
      src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs
  26. 329 87
      src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs
  27. 30 0
      src/ProtocolBuffers/UnknownFieldSet.cs
  28. 87 27
      src/ProtocolBuffersLite.Test/TestProtos/UnitTestExtrasLiteProtoFile.cs
  29. 14 2
      src/ProtocolBuffersLite.Test/TestProtos/UnitTestImportLiteProtoFile.cs
  30. 17 2
      src/ProtocolBuffersLite.Test/TestProtos/UnitTestImportProtoFile.cs
  31. 13 1
      src/ProtocolBuffersLite.Test/TestProtos/UnitTestLiteImportNonLiteProtoFile.cs
  32. 274 142
      src/ProtocolBuffersLite.Test/TestProtos/UnitTestLiteProtoFile.cs
  33. 302 149
      src/ProtocolBuffersLite.Test/TestProtos/UnitTestProtoFile.cs

+ 56 - 11
src/AddressBook/AddressBookProtos.cs

@@ -67,6 +67,8 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class Person : pb::GeneratedMessage<Person, Person.Builder> {
     private static readonly Person defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _personFieldNames = new string[] { "email", "id", "name", "phone" };
+    private static readonly uint[] _personFieldTags = new uint[] { 26, 16, 10, 34 };
     public static Person DefaultInstance {
       get { return defaultInstance; }
     }
@@ -105,6 +107,8 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
       [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
       public sealed partial class PhoneNumber : pb::GeneratedMessage<PhoneNumber, PhoneNumber.Builder> {
         private static readonly PhoneNumber defaultInstance = new Builder().BuildPartial();
+        private static readonly string[] _phoneNumberFieldNames = new string[] { "number", "type" };
+        private static readonly uint[] _phoneNumberFieldTags = new uint[] { 10, 16 };
         public static PhoneNumber DefaultInstance {
           get { return defaultInstance; }
         }
@@ -154,11 +158,12 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
         
         public override void WriteTo(pb::ICodedOutputStream output) {
           int size = SerializedSize;
+          string[] field_names = _phoneNumberFieldNames;
           if (hasNumber) {
-            output.WriteString(1, "number", Number);
+            output.WriteString(1, field_names[0], Number);
           }
           if (hasType) {
-            output.WriteEnum(2, "type", (int) Type, Type.ToString());
+            output.WriteEnum(2, field_names[1], (int) Type, Type.ToString());
           }
           UnknownFields.WriteTo(output);
         }
@@ -290,6 +295,18 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
             uint tag;
             string field_name;
             while (input.ReadTag(out tag, out field_name)) {
+              if(tag == 0 && field_name != null) {
+                int field_ordinal = global::System.Array.BinarySearch(_phoneNumberFieldNames, field_name, global::System.StringComparer.Ordinal);
+                if(field_ordinal >= 0)
+                  tag = _phoneNumberFieldTags[field_ordinal];
+                else {
+                  if (unknownFields == null) {
+                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                  }
+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+                  continue;
+                }
+              }
               switch (tag) {
                 case 0: {
                   throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -308,7 +325,7 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
                   break;
                 }
                 case 10: {
-                  result.hasNumber |= input.ReadString(ref result.number_);
+                  result.hasNumber = input.ReadString(ref result.number_);
                   break;
                 }
                 case 16: {
@@ -433,17 +450,18 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _personFieldNames;
       if (hasName) {
-        output.WriteString(1, "name", Name);
+        output.WriteString(1, field_names[2], Name);
       }
       if (hasId) {
-        output.WriteInt32(2, "id", Id);
+        output.WriteInt32(2, field_names[1], Id);
       }
       if (hasEmail) {
-        output.WriteString(3, "email", Email);
+        output.WriteString(3, field_names[0], Email);
       }
       if (phone_.Count > 0) {
-        output.WriteArray(pbd::FieldType.Message, 4, "phone", phone_);
+        output.WriteArray(pbd::FieldType.Message, 4, field_names[3], phone_);
       }
       UnknownFields.WriteTo(output);
     }
@@ -588,6 +606,18 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_personFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _personFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -606,15 +636,15 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
               break;
             }
             case 10: {
-              result.hasName |= input.ReadString(ref result.name_);
+              result.hasName = input.ReadString(ref result.name_);
               break;
             }
             case 16: {
-              result.hasId |= input.ReadInt32(ref result.id_);
+              result.hasId = input.ReadInt32(ref result.id_);
               break;
             }
             case 26: {
-              result.hasEmail |= input.ReadString(ref result.email_);
+              result.hasEmail = input.ReadString(ref result.email_);
               break;
             }
             case 34: {
@@ -735,6 +765,8 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class AddressBook : pb::GeneratedMessage<AddressBook, AddressBook.Builder> {
     private static readonly AddressBook defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _addressBookFieldNames = new string[] { "person" };
+    private static readonly uint[] _addressBookFieldTags = new uint[] { 10 };
     public static AddressBook DefaultInstance {
       get { return defaultInstance; }
     }
@@ -778,8 +810,9 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _addressBookFieldNames;
       if (person_.Count > 0) {
-        output.WriteArray(pbd::FieldType.Message, 1, "person", person_);
+        output.WriteArray(pbd::FieldType.Message, 1, field_names[0], person_);
       }
       UnknownFields.WriteTo(output);
     }
@@ -906,6 +939,18 @@ namespace Google.ProtocolBuffers.Examples.AddressBook {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_addressBookFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _addressBookFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();

+ 37 - 47
src/ProtoBench/Program.cs

@@ -58,6 +58,7 @@ namespace Google.ProtocolBuffers.ProtoBench
 
         private static BenchmarkTest RunBenchmark;
 
+        [STAThread]
         public static int Main(string[] args)
         {
             List<string> temp = new List<string>(args);
@@ -160,58 +161,47 @@ namespace Google.ProtocolBuffers.ProtoBench
             long totalCount = 0;
             double best = double.MinValue, worst = double.MaxValue;
 
-            ThreadStart threadProc = 
-                delegate()
-                    {
-                        action();
-                        // Run it progressively more times until we've got a reasonable sample
-
-                        int iterations = 100;
-                        elapsed = TimeAction(action, iterations);
-                        while (elapsed.TotalMilliseconds < 1000)
-                        {
-                            elapsed += TimeAction(action, iterations);
-                            iterations *= 2;
-                        }
-
-                        TimeSpan target = TimeSpan.FromSeconds(1);
-
-                        elapsed = TimeAction(action, iterations);
-                        iterations = (int)((target.Ticks * iterations) / (double)elapsed.Ticks);
-                        elapsed = TimeAction(action, iterations);
-                        iterations = (int)((target.Ticks * iterations) / (double)elapsed.Ticks);
-                        elapsed = TimeAction(action, iterations);
-                        iterations = (int)((target.Ticks * iterations) / (double)elapsed.Ticks);
+            action();
+            // Run it progressively more times until we've got a reasonable sample
 
-                        double first = (iterations * dataSize) / (elapsed.TotalSeconds * 1024 * 1024);
-                        if (Verbose) Console.WriteLine("Round ---: Count = {1,6}, Bps = {2,8:f3}", 0, iterations, first);
-                        elapsed = TimeSpan.Zero;
-                        int max = FastTest ? 10 : 30;
+            int iterations = 100;
+            elapsed = TimeAction(action, iterations);
+            while (elapsed.TotalMilliseconds < 1000)
+            {
+                elapsed += TimeAction(action, iterations);
+                iterations *= 2;
+            }
 
-                        while (runs < max)
-                        {
-                            TimeSpan cycle = TimeAction(action, iterations);
-                            // Accumulate and scale for next cycle.
-                            
-                            double bps = (iterations * dataSize) / (cycle.TotalSeconds * 1024 * 1024);
-                            if (Verbose) Console.WriteLine("Round {0,3}: Count = {1,6}, Bps = {2,8:f3}", runs, iterations, bps);
+            TimeSpan target = TimeSpan.FromSeconds(1);
 
-                            best = Math.Max(best, bps);
-                            worst = Math.Min(worst, bps);
+            elapsed = TimeAction(action, iterations);
+            iterations = (int)((target.Ticks * iterations) / (double)elapsed.Ticks);
+            elapsed = TimeAction(action, iterations);
+            iterations = (int)((target.Ticks * iterations) / (double)elapsed.Ticks);
+            elapsed = TimeAction(action, iterations);
+            iterations = (int)((target.Ticks * iterations) / (double)elapsed.Ticks);
 
-                            runs++;
-                            elapsed += cycle;
-                            totalCount += iterations;
-                            iterations = (int) ((target.Ticks*totalCount)/(double) elapsed.Ticks);
-                        }
-                    };
+            double first = (iterations * dataSize) / (elapsed.TotalSeconds * 1024 * 1024);
+            if (Verbose) Console.WriteLine("Round ---: Count = {1,6}, Bps = {2,8:f3}", 0, iterations, first);
+            elapsed = TimeSpan.Zero;
+            int max = FastTest ? 10 : 30;
 
-            Thread work = new Thread(threadProc);
-            work.Name = "Worker";
-            work.Priority = ThreadPriority.Highest;
-            work.SetApartmentState(ApartmentState.STA);
-            work.Start();
-            work.Join();
+            while (runs < max)
+            {
+                TimeSpan cycle = TimeAction(action, iterations);
+                // Accumulate and scale for next cycle.
+                
+                double bps = (iterations * dataSize) / (cycle.TotalSeconds * 1024 * 1024);
+                if (Verbose) Console.WriteLine("Round {0,3}: Count = {1,6}, Bps = {2,8:f3}", runs, iterations, bps);
+
+                best = Math.Max(best, bps);
+                worst = Math.Min(worst, bps);
+
+                runs++;
+                elapsed += cycle;
+                totalCount += iterations;
+                iterations = (int) ((target.Ticks*totalCount)/(double) elapsed.Ticks);
+            }
 
             Console.WriteLine("{0}: averages {1} per {2:f3}s for {3} runs; avg: {4:f3}mbps; best: {5:f3}mbps; worst: {6:f3}mbps",
                               name, totalCount / runs, elapsed.TotalSeconds / runs, runs,

+ 3 - 17
src/ProtoGen/EnumFieldGenerator.cs

@@ -40,8 +40,8 @@ namespace Google.ProtocolBuffers.ProtoGen
 {
     internal class EnumFieldGenerator : FieldGeneratorBase, IFieldSourceGenerator
     {
-        internal EnumFieldGenerator(FieldDescriptor descriptor)
-            : base(descriptor)
+        internal EnumFieldGenerator(FieldDescriptor descriptor, int fieldOrdinal)
+            : base(descriptor, fieldOrdinal)
         {
         }
 
@@ -107,26 +107,12 @@ namespace Google.ProtocolBuffers.ProtoGen
                 writer.WriteLine("  unknownFields.MergeVarintField({0}, (ulong)(int)unknown);", Number);
             }
             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)
         {
             writer.WriteLine("if (has{0}) {{", PropertyName);
-            writer.WriteLine("  output.WriteEnum({0}, \"{2}\", (int) {1}, {1}.ToString());", Number, PropertyName, Descriptor.Name);
+            writer.WriteLine("  output.WriteEnum({0}, field_names[{2}], (int) {1}, {1}.ToString());", Number, PropertyName, FieldOrdinal);
             writer.WriteLine("}");
         }
 

+ 1 - 1
src/ProtoGen/ExtensionGenerator.cs

@@ -48,7 +48,7 @@ namespace Google.ProtocolBuffers.ProtoGen
         private readonly string name;
 
         internal ExtensionGenerator(FieldDescriptor descriptor)
-            : base(descriptor)
+            : base(descriptor, 0)
         {
             if (Descriptor.ExtensionScope != null)
             {

+ 6 - 1
src/ProtoGen/FieldGeneratorBase.cs

@@ -42,15 +42,20 @@ namespace Google.ProtocolBuffers.ProtoGen
 {
     internal abstract class FieldGeneratorBase : SourceGeneratorBase<FieldDescriptor>
     {
-        protected FieldGeneratorBase(FieldDescriptor descriptor)
+        private readonly int _fieldOrdinal;
+
+        protected FieldGeneratorBase(FieldDescriptor descriptor, int fieldOrdinal)
             : base(descriptor)
         {
+            _fieldOrdinal = fieldOrdinal;
         }
 
         public abstract void WriteHash(TextGenerator writer);
         public abstract void WriteEquals(TextGenerator writer);
         public abstract void WriteToString(TextGenerator writer);
 
+        public int FieldOrdinal { get { return _fieldOrdinal; } }
+
         private static bool AllPrintableAscii(string text)
         {
             foreach (char c in text)

+ 3 - 3
src/ProtoGen/MessageFieldGenerator.cs

@@ -40,8 +40,8 @@ namespace Google.ProtocolBuffers.ProtoGen
 {
     internal class MessageFieldGenerator : FieldGeneratorBase, IFieldSourceGenerator
     {
-        internal MessageFieldGenerator(FieldDescriptor descriptor)
-            : base(descriptor)
+        internal MessageFieldGenerator(FieldDescriptor descriptor, int fieldOrdinal)
+            : base(descriptor, fieldOrdinal)
         {
         }
 
@@ -129,7 +129,7 @@ namespace Google.ProtocolBuffers.ProtoGen
         public void GenerateSerializationCode(TextGenerator writer)
         {
             writer.WriteLine("if (has{0}) {{", PropertyName);
-            writer.WriteLine("  output.Write{0}({1}, \"{3}\", {2});", MessageOrGroup, Number, PropertyName, Descriptor.Name);
+            writer.WriteLine("  output.Write{0}({1}, field_names[{3}], {2});", MessageOrGroup, Number, PropertyName, FieldOrdinal);
             writer.WriteLine("}");
         }
 

+ 73 - 11
src/ProtoGen/MessageGenerator.cs

@@ -44,6 +44,8 @@ namespace Google.ProtocolBuffers.ProtoGen
 {
     internal class MessageGenerator : SourceGeneratorBase<MessageDescriptor>, ISourceGenerator
     {
+        private string[] _fieldNames;
+
         internal MessageGenerator(MessageDescriptor descriptor) : base(descriptor)
         {
         }
@@ -136,6 +138,33 @@ namespace Google.ProtocolBuffers.ProtoGen
             }
         }
 
+        public string[] FieldNames
+        {
+            get
+            {
+                if (_fieldNames == null)
+                {
+                    List<string> names = new List<string>();
+                    foreach (FieldDescriptor fieldDescriptor in Descriptor.Fields)
+                        names.Add(fieldDescriptor.Name);
+                    //if you change this, the search must also change in GenerateBuilderParsingMethods
+                    names.Sort(StringComparer.Ordinal);
+                    _fieldNames = names.ToArray();
+                }
+                return _fieldNames;
+            }
+        }
+
+        internal int FieldOrdinal(FieldDescriptor field)
+        {
+            return Array.BinarySearch(FieldNames, field.Name, StringComparer.Ordinal);
+        }
+
+        private IFieldSourceGenerator CreateFieldGenerator(FieldDescriptor fieldDescriptor)
+        {
+            return SourceGenerators.CreateFieldGenerator(fieldDescriptor, FieldOrdinal(fieldDescriptor));
+        }
+
         public void Generate(TextGenerator writer)
         {
             writer.WriteLine("[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]");
@@ -148,6 +177,18 @@ namespace Google.ProtocolBuffers.ProtoGen
             writer.Indent();
             // Must call BuildPartial() to make sure all lists are made read-only
             writer.WriteLine("private static readonly {0} defaultInstance = new Builder().BuildPartial();", ClassName);
+
+            if (OptimizeSpeed)
+            {
+                writer.WriteLine("private static readonly string[] _{0}FieldNames = new string[] {{ {2}{1}{2} }};",
+                    NameHelpers.UnderscoresToCamelCase(ClassName), String.Join("\", \"", FieldNames), FieldNames.Length > 0 ? "\"" : "");
+                List<string> tags = new List<string>();
+                foreach (string name in FieldNames)
+                    tags.Add(WireFormat.MakeTag(Descriptor.FindFieldByName(name)).ToString());
+
+                writer.WriteLine("private static readonly uint[] _{0}FieldTags = new uint[] {{ {1} }};",
+                    NameHelpers.UnderscoresToCamelCase(ClassName), String.Join(", ", tags.ToArray()));
+            }
             writer.WriteLine("public static {0} DefaultInstance {{", ClassName);
             writer.WriteLine("  get { return defaultInstance; }");
             writer.WriteLine("}");
@@ -202,7 +243,7 @@ namespace Google.ProtocolBuffers.ProtoGen
                 // Rats: we lose the debug comment here :(
                 writer.WriteLine("public const int {0} = {1};", GetFieldConstantName(fieldDescriptor),
                                  fieldDescriptor.FieldNumber);
-                SourceGenerators.CreateFieldGenerator(fieldDescriptor).GenerateMembers(writer);
+                CreateFieldGenerator(fieldDescriptor).GenerateMembers(writer);
                 writer.WriteLine();
             }
 
@@ -244,7 +285,7 @@ namespace Google.ProtocolBuffers.ProtoGen
             writer.WriteLine("int hash = GetType().GetHashCode();");
             foreach (FieldDescriptor fieldDescriptor in Descriptor.Fields)
             {
-                SourceGenerators.CreateFieldGenerator(fieldDescriptor).WriteHash(writer);
+                CreateFieldGenerator(fieldDescriptor).WriteHash(writer);
             }
             if (callbase) writer.WriteLine("hash ^= base.GetHashCode();");
             writer.WriteLine("return hash;");
@@ -258,7 +299,7 @@ namespace Google.ProtocolBuffers.ProtoGen
             writer.WriteLine("if (other == null) return false;");
             foreach (FieldDescriptor fieldDescriptor in Descriptor.Fields)
             {
-                SourceGenerators.CreateFieldGenerator(fieldDescriptor).WriteEquals(writer);
+                CreateFieldGenerator(fieldDescriptor).WriteEquals(writer);
             }
             if (callbase) writer.WriteLine("if (!base.Equals(other)) return false;");
             writer.WriteLine("return true;");
@@ -274,7 +315,7 @@ namespace Google.ProtocolBuffers.ProtoGen
                     delegate(FieldDescriptor a, FieldDescriptor b) { return a.FieldNumber.CompareTo(b.FieldNumber); }));
             foreach (FieldDescriptor fieldDescriptor in sorted)
             {
-                SourceGenerators.CreateFieldGenerator(fieldDescriptor).WriteToString(writer);
+                CreateFieldGenerator(fieldDescriptor).WriteToString(writer);
             }
             if (callbase) writer.WriteLine("base.PrintTo(writer);");
             writer.Outdent();
@@ -295,6 +336,7 @@ namespace Google.ProtocolBuffers.ProtoGen
             writer.Indent();
             // Make sure we've computed the serialized length, so that packed fields are generated correctly.
             writer.WriteLine("int size = SerializedSize;");
+            writer.WriteLine("string[] field_names = _{0}FieldNames;", NameHelpers.UnderscoresToCamelCase(ClassName));
             if (Descriptor.Proto.ExtensionRangeList.Count > 0)
             {
                 writer.WriteLine(
@@ -349,7 +391,7 @@ namespace Google.ProtocolBuffers.ProtoGen
             writer.WriteLine("size = 0;");
             foreach (FieldDescriptor field in Descriptor.Fields)
             {
-                SourceGenerators.CreateFieldGenerator(field).GenerateSerializedSizeCode(writer);
+                CreateFieldGenerator(field).GenerateSerializedSizeCode(writer);
             }
             if (Descriptor.Proto.ExtensionRangeCount > 0)
             {
@@ -376,9 +418,9 @@ namespace Google.ProtocolBuffers.ProtoGen
             writer.WriteLine();
         }
 
-        private static void GenerateSerializeOneField(TextGenerator writer, FieldDescriptor fieldDescriptor)
+        private void GenerateSerializeOneField(TextGenerator writer, FieldDescriptor fieldDescriptor)
         {
-            SourceGenerators.CreateFieldGenerator(fieldDescriptor).GenerateSerializationCode(writer);
+            CreateFieldGenerator(fieldDescriptor).GenerateSerializationCode(writer);
         }
 
         private static void GenerateSerializeOneExtensionRange(TextGenerator writer, ExtensionRange extensionRange)
@@ -509,7 +551,7 @@ namespace Google.ProtocolBuffers.ProtoGen
             {
                 writer.WriteLine();
                 // No field comment :(
-                SourceGenerators.CreateFieldGenerator(field).GenerateBuilderMembers(writer);
+                CreateFieldGenerator(field).GenerateBuilderMembers(writer);
             }
             writer.Outdent();
             writer.WriteLine("}");
@@ -554,7 +596,7 @@ namespace Google.ProtocolBuffers.ProtoGen
             writer.WriteLine("}");
             foreach (FieldDescriptor field in Descriptor.Fields)
             {
-                SourceGenerators.CreateFieldGenerator(field).GenerateBuildingCode(writer);
+                CreateFieldGenerator(field).GenerateBuildingCode(writer);
             }
             writer.WriteLine("{0} returnMe = result;", ClassName);
             writer.WriteLine("result = null;");
@@ -581,7 +623,7 @@ namespace Google.ProtocolBuffers.ProtoGen
                 writer.WriteLine("if (other == {0}.DefaultInstance) return this;", FullClassName);
                 foreach (FieldDescriptor field in Descriptor.Fields)
                 {
-                    SourceGenerators.CreateFieldGenerator(field).GenerateMergingCode(writer);
+                    CreateFieldGenerator(field).GenerateMergingCode(writer);
                 }
                 // if message type has extensions
                 if (Descriptor.Proto.ExtensionRangeCount > 0)
@@ -619,6 +661,26 @@ namespace Google.ProtocolBuffers.ProtoGen
             writer.WriteLine("string field_name;");
             writer.WriteLine("while (input.ReadTag(out tag, out field_name)) {");
             writer.Indent();
+            writer.WriteLine("if(tag == 0 && field_name != null) {");
+            writer.Indent();
+            //if you change from StringComparer.Ordinal, the array sort in FieldNames { get; } must also change
+            writer.WriteLine("int field_ordinal = global::System.Array.BinarySearch(_{0}FieldNames, field_name, global::System.StringComparer.Ordinal);", 
+                NameHelpers.UnderscoresToCamelCase(ClassName));
+            writer.WriteLine("if(field_ordinal >= 0)");
+            writer.WriteLine("  tag = _{0}FieldTags[field_ordinal];", NameHelpers.UnderscoresToCamelCase(ClassName));
+            writer.WriteLine("else {");
+            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("  ParseUnknownField(input, {0}extensionRegistry, tag, field_name);", UseLiteRuntime ? "" : "unknownFields, ");
+            writer.WriteLine("  continue;");
+            writer.WriteLine("}");
+            writer.Outdent();
+            writer.WriteLine("}");
+
             writer.WriteLine("switch (tag) {");
             writer.Indent();
             writer.WriteLine("case 0: {"); // 0 signals EOF / limit reached
@@ -661,7 +723,7 @@ namespace Google.ProtocolBuffers.ProtoGen
 
                 writer.WriteLine("case {0}: {{", tag);
                 writer.Indent();
-                SourceGenerators.CreateFieldGenerator(field).GenerateParsingCode(writer);
+                CreateFieldGenerator(field).GenerateParsingCode(writer);
                 writer.WriteLine("break;");
                 writer.Outdent();
                 writer.WriteLine("}");

+ 4 - 4
src/ProtoGen/PrimitiveFieldGenerator.cs

@@ -41,8 +41,8 @@ namespace Google.ProtocolBuffers.ProtoGen
     // TODO(jonskeet): Refactor this. There's loads of common code here.
     internal class PrimitiveFieldGenerator : FieldGeneratorBase, IFieldSourceGenerator
     {
-        internal PrimitiveFieldGenerator(FieldDescriptor descriptor)
-            : base(descriptor)
+        internal PrimitiveFieldGenerator(FieldDescriptor descriptor, int fieldOrdinal)
+            : base(descriptor, fieldOrdinal)
         {
         }
 
@@ -97,13 +97,13 @@ namespace Google.ProtocolBuffers.ProtoGen
 
         public void GenerateParsingCode(TextGenerator writer)
         {
-            writer.WriteLine("result.has{0} |= input.Read{1}(ref result.{2}_);", PropertyName, CapitalizedTypeName, Name);
+            writer.WriteLine("result.has{0} = input.Read{1}(ref result.{2}_);", PropertyName, CapitalizedTypeName, Name);
         }
 
         public void GenerateSerializationCode(TextGenerator writer)
         {
             writer.WriteLine("if (has{0}) {{", PropertyName);
-            writer.WriteLine("  output.Write{0}({1}, \"{3}\", {2});", CapitalizedTypeName, Number, PropertyName, Descriptor.Name);
+            writer.WriteLine("  output.Write{0}({1}, field_names[{3}], {2});", CapitalizedTypeName, Number, PropertyName, FieldOrdinal);
             writer.WriteLine("}");
         }
 

+ 6 - 4
src/ProtoGen/ProtoGen.csproj

@@ -56,10 +56,6 @@
     <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Google.ProtocolBuffers, Version=2.3.0.277, Culture=neutral, PublicKeyToken=17b3b1f090c3ea48, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\build\2.3.0.304\Google.ProtocolBuffers.dll</HintPath>
-    </Reference>
     <Reference Include="mscorlib" />
     <Reference Include="System" />
     <Reference Include="System.Data" />
@@ -113,6 +109,12 @@
       <Install>true</Install>
     </BootstrapperPackage>
   </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\ProtocolBuffers\ProtocolBuffers.csproj">
+      <Project>{6908BDCE-D925-43F3-94AC-A531E6DF2591}</Project>
+      <Name>ProtocolBuffers</Name>
+    </ProjectReference>
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.

+ 4 - 49
src/ProtoGen/RepeatedEnumFieldGenerator.cs

@@ -41,8 +41,8 @@ namespace Google.ProtocolBuffers.ProtoGen
 {
     internal class RepeatedEnumFieldGenerator : FieldGeneratorBase, IFieldSourceGenerator
     {
-        internal RepeatedEnumFieldGenerator(FieldDescriptor descriptor)
-            : base(descriptor)
+        internal RepeatedEnumFieldGenerator(FieldDescriptor descriptor, int fieldOrdinal)
+            : base(descriptor, fieldOrdinal)
         {
         }
 
@@ -125,37 +125,6 @@ namespace Google.ProtocolBuffers.ProtoGen
                 writer.WriteLine("      unknownFields.MergeVarintField({0}, (ulong)(int)rawValue);", Number);
                 writer.WriteLine("}");
             }
-
-            //// 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)
@@ -163,23 +132,9 @@ namespace Google.ProtocolBuffers.ProtoGen
             writer.WriteLine("if ({0}_.Count > 0) {{", Name);
             writer.Indent();
             if (Descriptor.IsPacked)
-                writer.WriteLine("output.WritePackedArray(pbd::FieldType.{3}, {0}, \"{2}\", {1}MemoizedSerializedSize, {1}_);", Number, Name, Descriptor.Name, Descriptor.FieldType);
+                writer.WriteLine("output.WritePackedArray(pbd::FieldType.{3}, {0}, field_names[{2}], {1}MemoizedSerializedSize, {1}_);", Number, Name, FieldOrdinal, Descriptor.FieldType);
             else
-                writer.WriteLine("output.WriteArray(pbd::FieldType.{3}, {0}, \"{2}\", {1}_);", Number, Name, Descriptor.Name, Descriptor.FieldType);
-            //if (Descriptor.IsPacked)
-            //{
-            //    writer.WriteLine("output.WriteRawVarint32({0});", WireFormat.MakeTag(Descriptor));
-            //    writer.WriteLine("output.WriteRawVarint32((uint) {0}MemoizedSerializedSize);", Name);
-            //    writer.WriteLine("foreach (int element in {0}_) {{", Name);
-            //    writer.WriteLine("  output.WriteEnumNoTag(element);");
-            //    writer.WriteLine("}");
-            //}
-            //else
-            //{
-            //    writer.WriteLine("foreach (int element in {0}_) {{", Name);
-            //    writer.WriteLine("  output.WriteEnum({0}, element);", Number);
-            //    writer.WriteLine("}");
-            //}
+                writer.WriteLine("output.WriteArray(pbd::FieldType.{3}, {0}, field_names[{2}], {1}_);", Number, Name, FieldOrdinal, Descriptor.FieldType);
             writer.Outdent();
             writer.WriteLine("}");
         }

+ 3 - 23
src/ProtoGen/RepeatedMessageFieldGenerator.cs

@@ -41,8 +41,8 @@ namespace Google.ProtocolBuffers.ProtoGen
 {
     internal class RepeatedMessageFieldGenerator : FieldGeneratorBase, IFieldSourceGenerator
     {
-        internal RepeatedMessageFieldGenerator(FieldDescriptor descriptor)
-            : base(descriptor)
+        internal RepeatedMessageFieldGenerator(FieldDescriptor descriptor, int fieldOrdinal)
+            : base(descriptor, fieldOrdinal)
         {
         }
 
@@ -123,33 +123,13 @@ namespace Google.ProtocolBuffers.ProtoGen
         public void GenerateParsingCode(TextGenerator writer)
         {
             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)
         {
             writer.WriteLine("if ({0}_.Count > 0) {{", Name);
             writer.Indent();
-
-            // Arrays of message types do not currently support 'packed' storage
-            //if (Descriptor.IsPacked)
-            //    writer.WriteLine("output.WritePackedArray(pbd::FieldType.{3}, {0}, \"{2}\", {1}MemoizedSerializedSize, {1}_);", Number, Name, Descriptor.Name, Descriptor.FieldType);
-            //else
-            writer.WriteLine("output.WriteArray(pbd::FieldType.{3}, {0}, \"{2}\", {1}_);", Number, Name, Descriptor.Name, Descriptor.FieldType);
-
-            //writer.WriteLine("foreach ({0} element in {1}List) {{", TypeName, PropertyName);
-            //writer.WriteLine("  output.Write{0}({1}, element);", MessageOrGroup, Number);
-            //writer.WriteLine("}");
+            writer.WriteLine("output.WriteArray(pbd::FieldType.{3}, {0}, field_names[{2}], {1}_);", Number, Name, FieldOrdinal, Descriptor.FieldType);
             writer.Outdent();
             writer.WriteLine("}");
         }

+ 4 - 31
src/ProtoGen/RepeatedPrimitiveFieldGenerator.cs

@@ -41,8 +41,8 @@ namespace Google.ProtocolBuffers.ProtoGen
 {
     internal class RepeatedPrimitiveFieldGenerator : FieldGeneratorBase, IFieldSourceGenerator
     {
-        internal RepeatedPrimitiveFieldGenerator(FieldDescriptor descriptor)
-            : base(descriptor)
+        internal RepeatedPrimitiveFieldGenerator(FieldDescriptor descriptor, int fieldOrdinal)
+            : base(descriptor, fieldOrdinal)
         {
         }
 
@@ -122,19 +122,6 @@ namespace Google.ProtocolBuffers.ProtoGen
         public void GenerateParsingCode(TextGenerator writer)
         {
             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)
@@ -142,23 +129,9 @@ namespace Google.ProtocolBuffers.ProtoGen
             writer.WriteLine("if ({0}_.Count > 0) {{", Name);
             writer.Indent();
             if (Descriptor.IsPacked)
-                writer.WriteLine("output.WritePackedArray(pbd::FieldType.{3}, {0}, \"{2}\", {1}MemoizedSerializedSize, {1}_);", Number, Name, Descriptor.Name, Descriptor.FieldType);
+                writer.WriteLine("output.WritePackedArray(pbd::FieldType.{3}, {0}, field_names[{2}], {1}MemoizedSerializedSize, {1}_);", Number, Name, FieldOrdinal, Descriptor.FieldType);
             else
-                writer.WriteLine("output.WriteArray(pbd::FieldType.{3}, {0}, \"{2}\", {1}_);", Number, Name, Descriptor.Name, Descriptor.FieldType);
-            //if (Descriptor.IsPacked)
-            //{
-            //    writer.WriteLine("output.WriteRawVarint32({0});", WireFormat.MakeTag(Descriptor));
-            //    writer.WriteLine("output.WriteRawVarint32((uint) {0}MemoizedSerializedSize);", Name);
-            //    writer.WriteLine("foreach ({0} element in {1}_) {{", TypeName, Name);
-            //    writer.WriteLine("  output.Write{0}NoTag(element);", CapitalizedTypeName);
-            //    writer.WriteLine("}");
-            //}
-            //else
-            //{
-            //    writer.WriteLine("foreach ({0} element in {1}_) {{", TypeName, Name);
-            //    writer.WriteLine("  output.Write{0}({1}, element);", CapitalizedTypeName, Number);
-            //    writer.WriteLine("}");
-            //}
+                writer.WriteLine("output.WriteArray(pbd::FieldType.{3}, {0}, field_names[{2}], {1}_);", Number, Name, FieldOrdinal, Descriptor.FieldType);
             writer.Outdent();
             writer.WriteLine("}");
         }

+ 17 - 82
src/ProtoGen/SourceGenerators.cs

@@ -44,98 +44,33 @@ namespace Google.ProtocolBuffers.ProtoGen
 
     internal static class SourceGenerators
     {
-        private static readonly Dictionary<Type, Func<IDescriptor, ISourceGenerator>> GeneratorFactories = new Dictionary
-            <Type, Func<IDescriptor, ISourceGenerator>>
-                                                                                                               {
-                                                                                                                   {
-                                                                                                                       typeof
-                                                                                                                       (
-                                                                                                                       FileDescriptor
-                                                                                                                       )
-                                                                                                                       ,
-                                                                                                                       descriptor
-                                                                                                                       =>
-                                                                                                                       new UmbrellaClassGenerator
-                                                                                                                           ((
-                                                                                                                            FileDescriptor
-                                                                                                                            )
-                                                                                                                            descriptor)
-                                                                                                                       },
-                                                                                                                   {
-                                                                                                                       typeof
-                                                                                                                       (
-                                                                                                                       EnumDescriptor
-                                                                                                                       )
-                                                                                                                       ,
-                                                                                                                       descriptor
-                                                                                                                       =>
-                                                                                                                       new EnumGenerator
-                                                                                                                           ((
-                                                                                                                            EnumDescriptor
-                                                                                                                            )
-                                                                                                                            descriptor)
-                                                                                                                       },
-                                                                                                                   {
-                                                                                                                       typeof
-                                                                                                                       (
-                                                                                                                       ServiceDescriptor
-                                                                                                                       )
-                                                                                                                       ,
-                                                                                                                       descriptor
-                                                                                                                       =>
-                                                                                                                       new ServiceGenerator
-                                                                                                                           ((
-                                                                                                                            ServiceDescriptor
-                                                                                                                            )
-                                                                                                                            descriptor)
-                                                                                                                       },
-                                                                                                                   {
-                                                                                                                       typeof
-                                                                                                                       (
-                                                                                                                       MessageDescriptor
-                                                                                                                       )
-                                                                                                                       ,
-                                                                                                                       descriptor
-                                                                                                                       =>
-                                                                                                                       new MessageGenerator
-                                                                                                                           ((
-                                                                                                                            MessageDescriptor
-                                                                                                                            )
-                                                                                                                            descriptor)
-                                                                                                                       },
-                                                                                                                   // For other fields, we have IFieldSourceGenerators.
-                                                                                                                   {
-                                                                                                                       typeof
-                                                                                                                       (
-                                                                                                                       FieldDescriptor
-                                                                                                                       )
-                                                                                                                       ,
-                                                                                                                       descriptor
-                                                                                                                       =>
-                                                                                                                       new ExtensionGenerator
-                                                                                                                           ((
-                                                                                                                            FieldDescriptor
-                                                                                                                            )
-                                                                                                                            descriptor)
-                                                                                                                       }
-                                                                                                               };
+        private static readonly Dictionary<Type, Func<IDescriptor, ISourceGenerator>> GeneratorFactories = 
+            new Dictionary<Type, Func<IDescriptor, ISourceGenerator>>
+            {
+                {typeof(FileDescriptor),descriptor=>new UmbrellaClassGenerator((FileDescriptor)descriptor)},
+                {typeof(EnumDescriptor),descriptor=>new EnumGenerator((EnumDescriptor)descriptor)},
+                {typeof(ServiceDescriptor),descriptor=>new ServiceGenerator((ServiceDescriptor)descriptor)},
+                {typeof(MessageDescriptor),descriptor=>new MessageGenerator((MessageDescriptor)descriptor)},
+                // For other fields, we have IFieldSourceGenerators.
+                {typeof(FieldDescriptor),descriptor=>new ExtensionGenerator((FieldDescriptor)descriptor)}
+            };
 
-        public static IFieldSourceGenerator CreateFieldGenerator(FieldDescriptor field)
+        public static IFieldSourceGenerator CreateFieldGenerator(FieldDescriptor field, int fieldOrdinal)
         {
             switch (field.MappedType)
             {
                 case MappedType.Message:
                     return field.IsRepeated
-                               ? (IFieldSourceGenerator) new RepeatedMessageFieldGenerator(field)
-                               : new MessageFieldGenerator(field);
+                               ? (IFieldSourceGenerator) new RepeatedMessageFieldGenerator(field, fieldOrdinal)
+                               : new MessageFieldGenerator(field, fieldOrdinal);
                 case MappedType.Enum:
                     return field.IsRepeated
-                               ? (IFieldSourceGenerator) new RepeatedEnumFieldGenerator(field)
-                               : new EnumFieldGenerator(field);
+                               ? (IFieldSourceGenerator)new RepeatedEnumFieldGenerator(field, fieldOrdinal)
+                               : new EnumFieldGenerator(field, fieldOrdinal);
                 default:
                     return field.IsRepeated
-                               ? (IFieldSourceGenerator) new RepeatedPrimitiveFieldGenerator(field)
-                               : new PrimitiveFieldGenerator(field);
+                               ? (IFieldSourceGenerator)new RepeatedPrimitiveFieldGenerator(field, fieldOrdinal)
+                               : new PrimitiveFieldGenerator(field, fieldOrdinal);
             }
         }
 

+ 21 - 6
src/ProtocolBuffers.Test/TestProtos/UnitTestCSharpOptionsProtoFile.cs

@@ -59,6 +59,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class OptionsMessage : pb::GeneratedMessage<OptionsMessage, OptionsMessage.Builder> {
     private static readonly OptionsMessage defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _optionsMessageFieldNames = new string[] { "customized", "normal", "options_message" };
+    private static readonly uint[] _optionsMessageFieldTags = new uint[] { 26, 10, 18 };
     public static OptionsMessage DefaultInstance {
       get { return defaultInstance; }
     }
@@ -117,14 +119,15 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _optionsMessageFieldNames;
       if (hasNormal) {
-        output.WriteString(1, "normal", Normal);
+        output.WriteString(1, field_names[1], Normal);
       }
       if (hasOptionsMessage_) {
-        output.WriteString(2, "options_message", OptionsMessage_);
+        output.WriteString(2, field_names[2], OptionsMessage_);
       }
       if (hasCustomName) {
-        output.WriteString(3, "customized", CustomName);
+        output.WriteString(3, field_names[0], CustomName);
       }
       UnknownFields.WriteTo(output);
     }
@@ -262,6 +265,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_optionsMessageFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _optionsMessageFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -280,15 +295,15 @@ namespace Google.ProtocolBuffers.TestProtos {
               break;
             }
             case 10: {
-              result.hasNormal |= input.ReadString(ref result.normal_);
+              result.hasNormal = input.ReadString(ref result.normal_);
               break;
             }
             case 18: {
-              result.hasOptionsMessage_ |= input.ReadString(ref result.optionsMessage_);
+              result.hasOptionsMessage_ = input.ReadString(ref result.optionsMessage_);
               break;
             }
             case 26: {
-              result.hasCustomName |= input.ReadString(ref result.customized_);
+              result.hasCustomName = input.ReadString(ref result.customized_);
               break;
             }
           }

+ 276 - 21
src/ProtocolBuffers.Test/TestProtos/UnitTestCustomOptionsProtoFile.cs

@@ -399,6 +399,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestMessageWithCustomOptions : pb::GeneratedMessage<TestMessageWithCustomOptions, TestMessageWithCustomOptions.Builder> {
     private static readonly TestMessageWithCustomOptions defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _testMessageWithCustomOptionsFieldNames = new string[] { "field1" };
+    private static readonly uint[] _testMessageWithCustomOptionsFieldTags = new uint[] { 10 };
     public static TestMessageWithCustomOptions DefaultInstance {
       get { return defaultInstance; }
     }
@@ -452,8 +454,9 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _testMessageWithCustomOptionsFieldNames;
       if (hasField1) {
-        output.WriteString(1, "field1", Field1);
+        output.WriteString(1, field_names[0], Field1);
       }
       UnknownFields.WriteTo(output);
     }
@@ -579,6 +582,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_testMessageWithCustomOptionsFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _testMessageWithCustomOptionsFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -597,7 +612,7 @@ namespace Google.ProtocolBuffers.TestProtos {
               break;
             }
             case 10: {
-              result.hasField1 |= input.ReadString(ref result.field1_);
+              result.hasField1 = input.ReadString(ref result.field1_);
               break;
             }
           }
@@ -639,6 +654,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class CustomOptionFooRequest : pb::GeneratedMessage<CustomOptionFooRequest, CustomOptionFooRequest.Builder> {
     private static readonly CustomOptionFooRequest defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _customOptionFooRequestFieldNames = new string[] {  };
+    private static readonly uint[] _customOptionFooRequestFieldTags = new uint[] {  };
     public static CustomOptionFooRequest DefaultInstance {
       get { return defaultInstance; }
     }
@@ -667,6 +684,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _customOptionFooRequestFieldNames;
       UnknownFields.WriteTo(output);
     }
     
@@ -785,6 +803,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_customOptionFooRequestFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _customOptionFooRequestFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -822,6 +852,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class CustomOptionFooResponse : pb::GeneratedMessage<CustomOptionFooResponse, CustomOptionFooResponse.Builder> {
     private static readonly CustomOptionFooResponse defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _customOptionFooResponseFieldNames = new string[] {  };
+    private static readonly uint[] _customOptionFooResponseFieldTags = new uint[] {  };
     public static CustomOptionFooResponse DefaultInstance {
       get { return defaultInstance; }
     }
@@ -850,6 +882,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _customOptionFooResponseFieldNames;
       UnknownFields.WriteTo(output);
     }
     
@@ -968,6 +1001,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_customOptionFooResponseFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _customOptionFooResponseFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1005,6 +1050,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class DummyMessageContainingEnum : pb::GeneratedMessage<DummyMessageContainingEnum, DummyMessageContainingEnum.Builder> {
     private static readonly DummyMessageContainingEnum defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _dummyMessageContainingEnumFieldNames = new string[] {  };
+    private static readonly uint[] _dummyMessageContainingEnumFieldTags = new uint[] {  };
     public static DummyMessageContainingEnum DefaultInstance {
       get { return defaultInstance; }
     }
@@ -1048,6 +1095,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _dummyMessageContainingEnumFieldNames;
       UnknownFields.WriteTo(output);
     }
     
@@ -1166,6 +1214,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_dummyMessageContainingEnumFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _dummyMessageContainingEnumFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1203,6 +1263,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class DummyMessageInvalidAsOptionType : pb::GeneratedMessage<DummyMessageInvalidAsOptionType, DummyMessageInvalidAsOptionType.Builder> {
     private static readonly DummyMessageInvalidAsOptionType defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _dummyMessageInvalidAsOptionTypeFieldNames = new string[] {  };
+    private static readonly uint[] _dummyMessageInvalidAsOptionTypeFieldTags = new uint[] {  };
     public static DummyMessageInvalidAsOptionType DefaultInstance {
       get { return defaultInstance; }
     }
@@ -1231,6 +1293,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _dummyMessageInvalidAsOptionTypeFieldNames;
       UnknownFields.WriteTo(output);
     }
     
@@ -1349,6 +1412,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_dummyMessageInvalidAsOptionTypeFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _dummyMessageInvalidAsOptionTypeFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1386,6 +1461,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class CustomOptionMinIntegerValues : pb::GeneratedMessage<CustomOptionMinIntegerValues, CustomOptionMinIntegerValues.Builder> {
     private static readonly CustomOptionMinIntegerValues defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _customOptionMinIntegerValuesFieldNames = new string[] {  };
+    private static readonly uint[] _customOptionMinIntegerValuesFieldTags = new uint[] {  };
     public static CustomOptionMinIntegerValues DefaultInstance {
       get { return defaultInstance; }
     }
@@ -1414,6 +1491,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _customOptionMinIntegerValuesFieldNames;
       UnknownFields.WriteTo(output);
     }
     
@@ -1532,6 +1610,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_customOptionMinIntegerValuesFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _customOptionMinIntegerValuesFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1569,6 +1659,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class CustomOptionMaxIntegerValues : pb::GeneratedMessage<CustomOptionMaxIntegerValues, CustomOptionMaxIntegerValues.Builder> {
     private static readonly CustomOptionMaxIntegerValues defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _customOptionMaxIntegerValuesFieldNames = new string[] {  };
+    private static readonly uint[] _customOptionMaxIntegerValuesFieldTags = new uint[] {  };
     public static CustomOptionMaxIntegerValues DefaultInstance {
       get { return defaultInstance; }
     }
@@ -1597,6 +1689,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _customOptionMaxIntegerValuesFieldNames;
       UnknownFields.WriteTo(output);
     }
     
@@ -1715,6 +1808,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_customOptionMaxIntegerValuesFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _customOptionMaxIntegerValuesFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1752,6 +1857,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class CustomOptionOtherValues : pb::GeneratedMessage<CustomOptionOtherValues, CustomOptionOtherValues.Builder> {
     private static readonly CustomOptionOtherValues defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _customOptionOtherValuesFieldNames = new string[] {  };
+    private static readonly uint[] _customOptionOtherValuesFieldTags = new uint[] {  };
     public static CustomOptionOtherValues DefaultInstance {
       get { return defaultInstance; }
     }
@@ -1780,6 +1887,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _customOptionOtherValuesFieldNames;
       UnknownFields.WriteTo(output);
     }
     
@@ -1898,6 +2006,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_customOptionOtherValuesFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _customOptionOtherValuesFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1935,6 +2055,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class SettingRealsFromPositiveInts : pb::GeneratedMessage<SettingRealsFromPositiveInts, SettingRealsFromPositiveInts.Builder> {
     private static readonly SettingRealsFromPositiveInts defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _settingRealsFromPositiveIntsFieldNames = new string[] {  };
+    private static readonly uint[] _settingRealsFromPositiveIntsFieldTags = new uint[] {  };
     public static SettingRealsFromPositiveInts DefaultInstance {
       get { return defaultInstance; }
     }
@@ -1963,6 +2085,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _settingRealsFromPositiveIntsFieldNames;
       UnknownFields.WriteTo(output);
     }
     
@@ -2081,6 +2204,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_settingRealsFromPositiveIntsFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _settingRealsFromPositiveIntsFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -2118,6 +2253,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class SettingRealsFromNegativeInts : pb::GeneratedMessage<SettingRealsFromNegativeInts, SettingRealsFromNegativeInts.Builder> {
     private static readonly SettingRealsFromNegativeInts defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _settingRealsFromNegativeIntsFieldNames = new string[] {  };
+    private static readonly uint[] _settingRealsFromNegativeIntsFieldTags = new uint[] {  };
     public static SettingRealsFromNegativeInts DefaultInstance {
       get { return defaultInstance; }
     }
@@ -2146,6 +2283,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _settingRealsFromNegativeIntsFieldNames;
       UnknownFields.WriteTo(output);
     }
     
@@ -2264,6 +2402,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_settingRealsFromNegativeIntsFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _settingRealsFromNegativeIntsFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -2301,6 +2451,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class ComplexOptionType1 : pb::ExtendableMessage<ComplexOptionType1, ComplexOptionType1.Builder> {
     private static readonly ComplexOptionType1 defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _complexOptionType1FieldNames = new string[] { "foo", "foo2", "foo3" };
+    private static readonly uint[] _complexOptionType1FieldTags = new uint[] { 8, 16, 24 };
     public static ComplexOptionType1 DefaultInstance {
       get { return defaultInstance; }
     }
@@ -2360,15 +2512,16 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _complexOptionType1FieldNames;
       pb::ExtendableMessage<ComplexOptionType1, ComplexOptionType1.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
       if (hasFoo) {
-        output.WriteInt32(1, "foo", Foo);
+        output.WriteInt32(1, field_names[0], Foo);
       }
       if (hasFoo2) {
-        output.WriteInt32(2, "foo2", Foo2);
+        output.WriteInt32(2, field_names[1], Foo2);
       }
       if (hasFoo3) {
-        output.WriteInt32(3, "foo3", Foo3);
+        output.WriteInt32(3, field_names[2], Foo3);
       }
       extensionWriter.WriteUntil(536870912, output);
       UnknownFields.WriteTo(output);
@@ -2509,6 +2662,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_complexOptionType1FieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _complexOptionType1FieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -2527,15 +2692,15 @@ namespace Google.ProtocolBuffers.TestProtos {
               break;
             }
             case 8: {
-              result.hasFoo |= input.ReadInt32(ref result.foo_);
+              result.hasFoo = input.ReadInt32(ref result.foo_);
               break;
             }
             case 16: {
-              result.hasFoo2 |= input.ReadInt32(ref result.foo2_);
+              result.hasFoo2 = input.ReadInt32(ref result.foo2_);
               break;
             }
             case 24: {
-              result.hasFoo3 |= input.ReadInt32(ref result.foo3_);
+              result.hasFoo3 = input.ReadInt32(ref result.foo3_);
               break;
             }
           }
@@ -2612,6 +2777,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class ComplexOptionType2 : pb::ExtendableMessage<ComplexOptionType2, ComplexOptionType2.Builder> {
     private static readonly ComplexOptionType2 defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _complexOptionType2FieldNames = new string[] { "bar", "baz", "fred" };
+    private static readonly uint[] _complexOptionType2FieldTags = new uint[] { 10, 16, 26 };
     public static ComplexOptionType2 DefaultInstance {
       get { return defaultInstance; }
     }
@@ -2642,6 +2809,8 @@ namespace Google.ProtocolBuffers.TestProtos {
       [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
       public sealed partial class ComplexOptionType4 : pb::GeneratedMessage<ComplexOptionType4, ComplexOptionType4.Builder> {
         private static readonly ComplexOptionType4 defaultInstance = new Builder().BuildPartial();
+        private static readonly string[] _complexOptionType4FieldNames = new string[] { "waldo" };
+        private static readonly uint[] _complexOptionType4FieldTags = new uint[] { 8 };
         public static ComplexOptionType4 DefaultInstance {
           get { return defaultInstance; }
         }
@@ -2682,8 +2851,9 @@ namespace Google.ProtocolBuffers.TestProtos {
         
         public override void WriteTo(pb::ICodedOutputStream output) {
           int size = SerializedSize;
+          string[] field_names = _complexOptionType4FieldNames;
           if (hasWaldo) {
-            output.WriteInt32(1, "waldo", Waldo);
+            output.WriteInt32(1, field_names[0], Waldo);
           }
           UnknownFields.WriteTo(output);
         }
@@ -2809,6 +2979,18 @@ namespace Google.ProtocolBuffers.TestProtos {
             uint tag;
             string field_name;
             while (input.ReadTag(out tag, out field_name)) {
+              if(tag == 0 && field_name != null) {
+                int field_ordinal = global::System.Array.BinarySearch(_complexOptionType4FieldNames, field_name, global::System.StringComparer.Ordinal);
+                if(field_ordinal >= 0)
+                  tag = _complexOptionType4FieldTags[field_ordinal];
+                else {
+                  if (unknownFields == null) {
+                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                  }
+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+                  continue;
+                }
+              }
               switch (tag) {
                 case 0: {
                   throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -2827,7 +3009,7 @@ namespace Google.ProtocolBuffers.TestProtos {
                   break;
                 }
                 case 8: {
-                  result.hasWaldo |= input.ReadInt32(ref result.waldo_);
+                  result.hasWaldo = input.ReadInt32(ref result.waldo_);
                   break;
                 }
               }
@@ -2908,15 +3090,16 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _complexOptionType2FieldNames;
       pb::ExtendableMessage<ComplexOptionType2, ComplexOptionType2.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
       if (hasBar) {
-        output.WriteMessage(1, "bar", Bar);
+        output.WriteMessage(1, field_names[0], Bar);
       }
       if (hasBaz) {
-        output.WriteInt32(2, "baz", Baz);
+        output.WriteInt32(2, field_names[1], Baz);
       }
       if (hasFred) {
-        output.WriteMessage(3, "fred", Fred);
+        output.WriteMessage(3, field_names[2], Fred);
       }
       extensionWriter.WriteUntil(536870912, output);
       UnknownFields.WriteTo(output);
@@ -3057,6 +3240,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_complexOptionType2FieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _complexOptionType2FieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -3084,7 +3279,7 @@ namespace Google.ProtocolBuffers.TestProtos {
               break;
             }
             case 16: {
-              result.hasBaz |= input.ReadInt32(ref result.baz_);
+              result.hasBaz = input.ReadInt32(ref result.baz_);
               break;
             }
             case 26: {
@@ -3206,6 +3401,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class ComplexOptionType3 : pb::GeneratedMessage<ComplexOptionType3, ComplexOptionType3.Builder> {
     private static readonly ComplexOptionType3 defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _complexOptionType3FieldNames = new string[] { "complexoptiontype5", "qux" };
+    private static readonly uint[] _complexOptionType3FieldTags = new uint[] { 19, 8 };
     public static ComplexOptionType3 DefaultInstance {
       get { return defaultInstance; }
     }
@@ -3236,6 +3433,8 @@ namespace Google.ProtocolBuffers.TestProtos {
       [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
       public sealed partial class ComplexOptionType5 : pb::GeneratedMessage<ComplexOptionType5, ComplexOptionType5.Builder> {
         private static readonly ComplexOptionType5 defaultInstance = new Builder().BuildPartial();
+        private static readonly string[] _complexOptionType5FieldNames = new string[] { "plugh" };
+        private static readonly uint[] _complexOptionType5FieldTags = new uint[] { 24 };
         public static ComplexOptionType5 DefaultInstance {
           get { return defaultInstance; }
         }
@@ -3274,8 +3473,9 @@ namespace Google.ProtocolBuffers.TestProtos {
         
         public override void WriteTo(pb::ICodedOutputStream output) {
           int size = SerializedSize;
+          string[] field_names = _complexOptionType5FieldNames;
           if (hasPlugh) {
-            output.WriteInt32(3, "plugh", Plugh);
+            output.WriteInt32(3, field_names[0], Plugh);
           }
           UnknownFields.WriteTo(output);
         }
@@ -3401,6 +3601,18 @@ namespace Google.ProtocolBuffers.TestProtos {
             uint tag;
             string field_name;
             while (input.ReadTag(out tag, out field_name)) {
+              if(tag == 0 && field_name != null) {
+                int field_ordinal = global::System.Array.BinarySearch(_complexOptionType5FieldNames, field_name, global::System.StringComparer.Ordinal);
+                if(field_ordinal >= 0)
+                  tag = _complexOptionType5FieldTags[field_ordinal];
+                else {
+                  if (unknownFields == null) {
+                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                  }
+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+                  continue;
+                }
+              }
               switch (tag) {
                 case 0: {
                   throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -3419,7 +3631,7 @@ namespace Google.ProtocolBuffers.TestProtos {
                   break;
                 }
                 case 24: {
-                  result.hasPlugh |= input.ReadInt32(ref result.plugh_);
+                  result.hasPlugh = input.ReadInt32(ref result.plugh_);
                   break;
                 }
               }
@@ -3486,11 +3698,12 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _complexOptionType3FieldNames;
       if (hasQux) {
-        output.WriteInt32(1, "qux", Qux);
+        output.WriteInt32(1, field_names[1], Qux);
       }
       if (hasComplexOptionType5) {
-        output.WriteGroup(2, "complexoptiontype5", ComplexOptionType5);
+        output.WriteGroup(2, field_names[0], ComplexOptionType5);
       }
       UnknownFields.WriteTo(output);
     }
@@ -3622,6 +3835,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_complexOptionType3FieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _complexOptionType3FieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -3640,7 +3865,7 @@ namespace Google.ProtocolBuffers.TestProtos {
               break;
             }
             case 8: {
-              result.hasQux |= input.ReadInt32(ref result.qux_);
+              result.hasQux = input.ReadInt32(ref result.qux_);
               break;
             }
             case 19: {
@@ -3726,6 +3951,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class ComplexOpt6 : pb::GeneratedMessage<ComplexOpt6, ComplexOpt6.Builder> {
     private static readonly ComplexOpt6 defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _complexOpt6FieldNames = new string[] { "xyzzy" };
+    private static readonly uint[] _complexOpt6FieldTags = new uint[] { 60751608 };
     public static ComplexOpt6 DefaultInstance {
       get { return defaultInstance; }
     }
@@ -3764,8 +3991,9 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _complexOpt6FieldNames;
       if (hasXyzzy) {
-        output.WriteInt32(7593951, "xyzzy", Xyzzy);
+        output.WriteInt32(7593951, field_names[0], Xyzzy);
       }
       UnknownFields.WriteTo(output);
     }
@@ -3891,6 +4119,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_complexOpt6FieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _complexOpt6FieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -3909,7 +4149,7 @@ namespace Google.ProtocolBuffers.TestProtos {
               break;
             }
             case 60751608: {
-              result.hasXyzzy |= input.ReadInt32(ref result.xyzzy_);
+              result.hasXyzzy = input.ReadInt32(ref result.xyzzy_);
               break;
             }
           }
@@ -3950,6 +4190,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class VariousComplexOptions : pb::GeneratedMessage<VariousComplexOptions, VariousComplexOptions.Builder> {
     private static readonly VariousComplexOptions defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _variousComplexOptionsFieldNames = new string[] {  };
+    private static readonly uint[] _variousComplexOptionsFieldTags = new uint[] {  };
     public static VariousComplexOptions DefaultInstance {
       get { return defaultInstance; }
     }
@@ -3978,6 +4220,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _variousComplexOptionsFieldNames;
       UnknownFields.WriteTo(output);
     }
     
@@ -4096,6 +4339,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_variousComplexOptionsFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _variousComplexOptionsFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();

+ 17 - 2
src/ProtocolBuffers.Test/TestProtos/UnitTestEmbedOptimizeForProtoFile.cs

@@ -63,6 +63,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestEmbedOptimizedForSize : pb::GeneratedMessage<TestEmbedOptimizedForSize, TestEmbedOptimizedForSize.Builder> {
     private static readonly TestEmbedOptimizedForSize defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _testEmbedOptimizedForSizeFieldNames = new string[] { "optional_message", "repeated_message" };
+    private static readonly uint[] _testEmbedOptimizedForSizeFieldTags = new uint[] { 10, 18 };
     public static TestEmbedOptimizedForSize DefaultInstance {
       get { return defaultInstance; }
     }
@@ -119,11 +121,12 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _testEmbedOptimizedForSizeFieldNames;
       if (hasOptionalMessage) {
-        output.WriteMessage(1, "optional_message", OptionalMessage);
+        output.WriteMessage(1, field_names[0], OptionalMessage);
       }
       if (repeatedMessage_.Count > 0) {
-        output.WriteArray(pbd::FieldType.Message, 2, "repeated_message", repeatedMessage_);
+        output.WriteArray(pbd::FieldType.Message, 2, field_names[1], repeatedMessage_);
       }
       UnknownFields.WriteTo(output);
     }
@@ -256,6 +259,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_testEmbedOptimizedForSizeFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _testEmbedOptimizedForSizeFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();

File diff suppressed because it is too large
+ 250 - 190
src/ProtocolBuffers.Test/TestProtos/UnitTestGoogleSpeedProtoFile.cs


+ 14 - 2
src/ProtocolBuffers.Test/TestProtos/UnitTestImportLiteProtoFile.cs

@@ -42,6 +42,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class ImportMessageLite : pb::GeneratedMessageLite<ImportMessageLite, ImportMessageLite.Builder> {
     private static readonly ImportMessageLite defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _importMessageLiteFieldNames = new string[] { "d" };
+    private static readonly uint[] _importMessageLiteFieldTags = new uint[] { 8 };
     public static ImportMessageLite DefaultInstance {
       get { return defaultInstance; }
     }
@@ -72,8 +74,9 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _importMessageLiteFieldNames;
       if (hasD) {
-        output.WriteInt32(1, "d", D);
+        output.WriteInt32(1, field_names[0], D);
       }
     }
     
@@ -210,6 +213,15 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_importMessageLiteFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _importMessageLiteFieldTags[field_ordinal];
+            else {
+              ParseUnknownField(input, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -222,7 +234,7 @@ namespace Google.ProtocolBuffers.TestProtos {
               break;
             }
             case 8: {
-              result.hasD |= input.ReadInt32(ref result.d_);
+              result.hasD = input.ReadInt32(ref result.d_);
               break;
             }
           }

+ 17 - 2
src/ProtocolBuffers.Test/TestProtos/UnitTestImportProtoFile.cs

@@ -70,6 +70,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class ImportMessage : pb::GeneratedMessage<ImportMessage, ImportMessage.Builder> {
     private static readonly ImportMessage defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _importMessageFieldNames = new string[] { "d" };
+    private static readonly uint[] _importMessageFieldTags = new uint[] { 8 };
     public static ImportMessage DefaultInstance {
       get { return defaultInstance; }
     }
@@ -108,8 +110,9 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _importMessageFieldNames;
       if (hasD) {
-        output.WriteInt32(1, "d", D);
+        output.WriteInt32(1, field_names[0], D);
       }
       UnknownFields.WriteTo(output);
     }
@@ -235,6 +238,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_importMessageFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _importMessageFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -253,7 +268,7 @@ namespace Google.ProtocolBuffers.TestProtos {
               break;
             }
             case 8: {
-              result.hasD |= input.ReadInt32(ref result.d_);
+              result.hasD = input.ReadInt32(ref result.d_);
               break;
             }
           }

+ 100 - 10
src/ProtocolBuffers.Test/TestProtos/UnitTestMessageSetProtoFile.cs

@@ -102,6 +102,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestMessageSet : pb::ExtendableMessage<TestMessageSet, TestMessageSet.Builder> {
     private static readonly TestMessageSet defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _testMessageSetFieldNames = new string[] {  };
+    private static readonly uint[] _testMessageSetFieldTags = new uint[] {  };
     public static TestMessageSet DefaultInstance {
       get { return defaultInstance; }
     }
@@ -131,6 +133,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _testMessageSetFieldNames;
       pb::ExtendableMessage<TestMessageSet, TestMessageSet.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
       extensionWriter.WriteUntil(536870912, output);
       UnknownFields.WriteAsMessageSetTo(output);
@@ -253,6 +256,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_testMessageSetFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _testMessageSetFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -290,6 +305,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestMessageSetContainer : pb::GeneratedMessage<TestMessageSetContainer, TestMessageSetContainer.Builder> {
     private static readonly TestMessageSetContainer defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _testMessageSetContainerFieldNames = new string[] { "message_set" };
+    private static readonly uint[] _testMessageSetContainerFieldTags = new uint[] { 10 };
     public static TestMessageSetContainer DefaultInstance {
       get { return defaultInstance; }
     }
@@ -328,8 +345,9 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _testMessageSetContainerFieldNames;
       if (hasMessageSet) {
-        output.WriteMessage(1, "message_set", MessageSet);
+        output.WriteMessage(1, field_names[0], MessageSet);
       }
       UnknownFields.WriteTo(output);
     }
@@ -455,6 +473,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_testMessageSetContainerFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _testMessageSetContainerFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -537,6 +567,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestMessageSetExtension1 : pb::GeneratedMessage<TestMessageSetExtension1, TestMessageSetExtension1.Builder> {
     private static readonly TestMessageSetExtension1 defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _testMessageSetExtension1FieldNames = new string[] { "i" };
+    private static readonly uint[] _testMessageSetExtension1FieldTags = new uint[] { 120 };
     public static TestMessageSetExtension1 DefaultInstance {
       get { return defaultInstance; }
     }
@@ -577,8 +609,9 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _testMessageSetExtension1FieldNames;
       if (hasI) {
-        output.WriteInt32(15, "i", I);
+        output.WriteInt32(15, field_names[0], I);
       }
       UnknownFields.WriteTo(output);
     }
@@ -704,6 +737,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_testMessageSetExtension1FieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _testMessageSetExtension1FieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -722,7 +767,7 @@ namespace Google.ProtocolBuffers.TestProtos {
               break;
             }
             case 120: {
-              result.hasI |= input.ReadInt32(ref result.i_);
+              result.hasI = input.ReadInt32(ref result.i_);
               break;
             }
           }
@@ -763,6 +808,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestMessageSetExtension2 : pb::GeneratedMessage<TestMessageSetExtension2, TestMessageSetExtension2.Builder> {
     private static readonly TestMessageSetExtension2 defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _testMessageSetExtension2FieldNames = new string[] { "str" };
+    private static readonly uint[] _testMessageSetExtension2FieldTags = new uint[] { 202 };
     public static TestMessageSetExtension2 DefaultInstance {
       get { return defaultInstance; }
     }
@@ -803,8 +850,9 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _testMessageSetExtension2FieldNames;
       if (hasStr) {
-        output.WriteString(25, "str", Str);
+        output.WriteString(25, field_names[0], Str);
       }
       UnknownFields.WriteTo(output);
     }
@@ -930,6 +978,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_testMessageSetExtension2FieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _testMessageSetExtension2FieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -948,7 +1008,7 @@ namespace Google.ProtocolBuffers.TestProtos {
               break;
             }
             case 202: {
-              result.hasStr |= input.ReadString(ref result.str_);
+              result.hasStr = input.ReadString(ref result.str_);
               break;
             }
           }
@@ -990,6 +1050,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class RawMessageSet : pb::GeneratedMessage<RawMessageSet, RawMessageSet.Builder> {
     private static readonly RawMessageSet defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _rawMessageSetFieldNames = new string[] { "item" };
+    private static readonly uint[] _rawMessageSetFieldTags = new uint[] { 11 };
     public static RawMessageSet DefaultInstance {
       get { return defaultInstance; }
     }
@@ -1020,6 +1082,8 @@ namespace Google.ProtocolBuffers.TestProtos {
       [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
       public sealed partial class Item : pb::GeneratedMessage<Item, Item.Builder> {
         private static readonly Item defaultInstance = new Builder().BuildPartial();
+        private static readonly string[] _itemFieldNames = new string[] { "message", "type_id" };
+        private static readonly uint[] _itemFieldTags = new uint[] { 26, 16 };
         public static Item DefaultInstance {
           get { return defaultInstance; }
         }
@@ -1070,11 +1134,12 @@ namespace Google.ProtocolBuffers.TestProtos {
         
         public override void WriteTo(pb::ICodedOutputStream output) {
           int size = SerializedSize;
+          string[] field_names = _itemFieldNames;
           if (hasTypeId) {
-            output.WriteInt32(2, "type_id", TypeId);
+            output.WriteInt32(2, field_names[1], TypeId);
           }
           if (hasMessage) {
-            output.WriteBytes(3, "message", Message);
+            output.WriteBytes(3, field_names[0], Message);
           }
           UnknownFields.WriteTo(output);
         }
@@ -1206,6 +1271,18 @@ namespace Google.ProtocolBuffers.TestProtos {
             uint tag;
             string field_name;
             while (input.ReadTag(out tag, out field_name)) {
+              if(tag == 0 && field_name != null) {
+                int field_ordinal = global::System.Array.BinarySearch(_itemFieldNames, field_name, global::System.StringComparer.Ordinal);
+                if(field_ordinal >= 0)
+                  tag = _itemFieldTags[field_ordinal];
+                else {
+                  if (unknownFields == null) {
+                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                  }
+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+                  continue;
+                }
+              }
               switch (tag) {
                 case 0: {
                   throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1224,11 +1301,11 @@ namespace Google.ProtocolBuffers.TestProtos {
                   break;
                 }
                 case 16: {
-                  result.hasTypeId |= input.ReadInt32(ref result.typeId_);
+                  result.hasTypeId = input.ReadInt32(ref result.typeId_);
                   break;
                 }
                 case 26: {
-                  result.hasMessage |= input.ReadBytes(ref result.message_);
+                  result.hasMessage = input.ReadBytes(ref result.message_);
                   break;
                 }
               }
@@ -1306,8 +1383,9 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _rawMessageSetFieldNames;
       if (item_.Count > 0) {
-        output.WriteArray(pbd::FieldType.Group, 1, "item", item_);
+        output.WriteArray(pbd::FieldType.Group, 1, field_names[0], item_);
       }
       UnknownFields.WriteTo(output);
     }
@@ -1434,6 +1512,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_rawMessageSetFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _rawMessageSetFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();

+ 17 - 2
src/ProtocolBuffers.Test/TestProtos/UnitTestNoGenericServicesProtoFile.cs

@@ -80,6 +80,8 @@ namespace Google.ProtocolBuffers.TestProtos.NoGenericService {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestMessage : pb::ExtendableMessage<TestMessage, TestMessage.Builder> {
     private static readonly TestMessage defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _testMessageFieldNames = new string[] { "a" };
+    private static readonly uint[] _testMessageFieldTags = new uint[] { 8 };
     public static TestMessage DefaultInstance {
       get { return defaultInstance; }
     }
@@ -119,9 +121,10 @@ namespace Google.ProtocolBuffers.TestProtos.NoGenericService {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _testMessageFieldNames;
       pb::ExtendableMessage<TestMessage, TestMessage.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
       if (hasA) {
-        output.WriteInt32(1, "a", A);
+        output.WriteInt32(1, field_names[0], A);
       }
       extensionWriter.WriteUntil(536870912, output);
       UnknownFields.WriteTo(output);
@@ -250,6 +253,18 @@ namespace Google.ProtocolBuffers.TestProtos.NoGenericService {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_testMessageFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _testMessageFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -268,7 +283,7 @@ namespace Google.ProtocolBuffers.TestProtos.NoGenericService {
               break;
             }
             case 8: {
-              result.hasA |= input.ReadInt32(ref result.a_);
+              result.hasA = input.ReadInt32(ref result.a_);
               break;
             }
           }

File diff suppressed because it is too large
+ 302 - 149
src/ProtocolBuffers.Test/TestProtos/UnitTestProtoFile.cs


+ 68 - 8
src/ProtocolBuffers.Test/TestProtos/UnitTestRpcInterop.cs

@@ -82,6 +82,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class SearchRequest : pb::GeneratedMessage<SearchRequest, SearchRequest.Builder> {
     private static readonly SearchRequest defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _searchRequestFieldNames = new string[] { "Criteria" };
+    private static readonly uint[] _searchRequestFieldTags = new uint[] { 10 };
     public static SearchRequest DefaultInstance {
       get { return defaultInstance; }
     }
@@ -122,8 +124,9 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _searchRequestFieldNames;
       if (criteria_.Count > 0) {
-        output.WriteArray(pbd::FieldType.String, 1, "Criteria", criteria_);
+        output.WriteArray(pbd::FieldType.String, 1, field_names[0], criteria_);
       }
       UnknownFields.WriteTo(output);
     }
@@ -255,6 +258,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_searchRequestFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _searchRequestFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -324,6 +339,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class SearchResponse : pb::GeneratedMessage<SearchResponse, SearchResponse.Builder> {
     private static readonly SearchResponse defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _searchResponseFieldNames = new string[] { "results" };
+    private static readonly uint[] _searchResponseFieldTags = new uint[] { 10 };
     public static SearchResponse DefaultInstance {
       get { return defaultInstance; }
     }
@@ -354,6 +371,8 @@ namespace Google.ProtocolBuffers.TestProtos {
       [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
       public sealed partial class ResultItem : pb::GeneratedMessage<ResultItem, ResultItem.Builder> {
         private static readonly ResultItem defaultInstance = new Builder().BuildPartial();
+        private static readonly string[] _resultItemFieldNames = new string[] { "name", "url" };
+        private static readonly uint[] _resultItemFieldTags = new uint[] { 18, 10 };
         public static ResultItem DefaultInstance {
           get { return defaultInstance; }
         }
@@ -403,11 +422,12 @@ namespace Google.ProtocolBuffers.TestProtos {
         
         public override void WriteTo(pb::ICodedOutputStream output) {
           int size = SerializedSize;
+          string[] field_names = _resultItemFieldNames;
           if (hasUrl) {
-            output.WriteString(1, "url", Url);
+            output.WriteString(1, field_names[1], Url);
           }
           if (hasName) {
-            output.WriteString(2, "name", Name);
+            output.WriteString(2, field_names[0], Name);
           }
           UnknownFields.WriteTo(output);
         }
@@ -539,6 +559,18 @@ namespace Google.ProtocolBuffers.TestProtos {
             uint tag;
             string field_name;
             while (input.ReadTag(out tag, out field_name)) {
+              if(tag == 0 && field_name != null) {
+                int field_ordinal = global::System.Array.BinarySearch(_resultItemFieldNames, field_name, global::System.StringComparer.Ordinal);
+                if(field_ordinal >= 0)
+                  tag = _resultItemFieldTags[field_ordinal];
+                else {
+                  if (unknownFields == null) {
+                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                  }
+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+                  continue;
+                }
+              }
               switch (tag) {
                 case 0: {
                   throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -557,11 +589,11 @@ namespace Google.ProtocolBuffers.TestProtos {
                   break;
                 }
                 case 10: {
-                  result.hasUrl |= input.ReadString(ref result.url_);
+                  result.hasUrl = input.ReadString(ref result.url_);
                   break;
                 }
                 case 18: {
-                  result.hasName |= input.ReadString(ref result.name_);
+                  result.hasName = input.ReadString(ref result.name_);
                   break;
                 }
               }
@@ -643,8 +675,9 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _searchResponseFieldNames;
       if (results_.Count > 0) {
-        output.WriteArray(pbd::FieldType.Message, 1, "results", results_);
+        output.WriteArray(pbd::FieldType.Message, 1, field_names[0], results_);
       }
       UnknownFields.WriteTo(output);
     }
@@ -771,6 +804,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_searchResponseFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _searchResponseFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -850,6 +895,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class RefineSearchRequest : pb::GeneratedMessage<RefineSearchRequest, RefineSearchRequest.Builder> {
     private static readonly RefineSearchRequest defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _refineSearchRequestFieldNames = new string[] { "Criteria", "previous_results" };
+    private static readonly uint[] _refineSearchRequestFieldTags = new uint[] { 10, 18 };
     public static RefineSearchRequest DefaultInstance {
       get { return defaultInstance; }
     }
@@ -902,11 +949,12 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _refineSearchRequestFieldNames;
       if (criteria_.Count > 0) {
-        output.WriteArray(pbd::FieldType.String, 1, "Criteria", criteria_);
+        output.WriteArray(pbd::FieldType.String, 1, field_names[0], criteria_);
       }
       if (hasPreviousResults) {
-        output.WriteMessage(2, "previous_results", PreviousResults);
+        output.WriteMessage(2, field_names[1], PreviousResults);
       }
       UnknownFields.WriteTo(output);
     }
@@ -1044,6 +1092,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_refineSearchRequestFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _refineSearchRequestFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();

+ 93 - 18
src/ProtocolBuffers.Test/TestProtos/UnitTestXmlSerializerTestProtoFile.cs

@@ -129,6 +129,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestXmlChild : pb::GeneratedMessage<TestXmlChild, TestXmlChild.Builder> {
     private static readonly TestXmlChild defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _testXmlChildFieldNames = new string[] { "binary", "options" };
+    private static readonly uint[] _testXmlChildFieldTags = new uint[] { 34, 24 };
     public static TestXmlChild DefaultInstance {
       get { return defaultInstance; }
     }
@@ -179,11 +181,12 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _testXmlChildFieldNames;
       if (options_.Count > 0) {
-        output.WriteArray(pbd::FieldType.Enum, 3, "options", options_);
+        output.WriteArray(pbd::FieldType.Enum, 3, field_names[1], options_);
       }
       if (hasBinary) {
-        output.WriteBytes(4, "binary", Binary);
+        output.WriteBytes(4, field_names[0], Binary);
       }
       UnknownFields.WriteTo(output);
     }
@@ -323,6 +326,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_testXmlChildFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _testXmlChildFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -355,7 +370,7 @@ namespace Google.ProtocolBuffers.TestProtos {
               break;
             }
             case 34: {
-              result.hasBinary |= input.ReadBytes(ref result.binary_);
+              result.hasBinary = input.ReadBytes(ref result.binary_);
               break;
             }
           }
@@ -423,6 +438,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestXmlNoFields : pb::GeneratedMessage<TestXmlNoFields, TestXmlNoFields.Builder> {
     private static readonly TestXmlNoFields defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _testXmlNoFieldsFieldNames = new string[] {  };
+    private static readonly uint[] _testXmlNoFieldsFieldTags = new uint[] {  };
     public static TestXmlNoFields DefaultInstance {
       get { return defaultInstance; }
     }
@@ -451,6 +468,7 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _testXmlNoFieldsFieldNames;
       UnknownFields.WriteTo(output);
     }
     
@@ -569,6 +587,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_testXmlNoFieldsFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _testXmlNoFieldsFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -606,6 +636,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestXmlMessage : pb::ExtendableMessage<TestXmlMessage, TestXmlMessage.Builder> {
     private static readonly TestXmlMessage defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _testXmlMessageFieldNames = new string[] { "child", "children", "number", "numbers", "text", "textlines", "valid" };
+    private static readonly uint[] _testXmlMessageFieldTags = new uint[] { 10, 3211, 48, 16, 26, 5602, 40 };
     public static TestXmlMessage DefaultInstance {
       get { return defaultInstance; }
     }
@@ -636,6 +668,8 @@ namespace Google.ProtocolBuffers.TestProtos {
       [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
       public sealed partial class Children : pb::GeneratedMessage<Children, Children.Builder> {
         private static readonly Children defaultInstance = new Builder().BuildPartial();
+        private static readonly string[] _childrenFieldNames = new string[] { "binary", "options" };
+        private static readonly uint[] _childrenFieldTags = new uint[] { 34, 24 };
         public static Children DefaultInstance {
           get { return defaultInstance; }
         }
@@ -686,11 +720,12 @@ namespace Google.ProtocolBuffers.TestProtos {
         
         public override void WriteTo(pb::ICodedOutputStream output) {
           int size = SerializedSize;
+          string[] field_names = _childrenFieldNames;
           if (options_.Count > 0) {
-            output.WriteArray(pbd::FieldType.Enum, 3, "options", options_);
+            output.WriteArray(pbd::FieldType.Enum, 3, field_names[1], options_);
           }
           if (hasBinary) {
-            output.WriteBytes(4, "binary", Binary);
+            output.WriteBytes(4, field_names[0], Binary);
           }
           UnknownFields.WriteTo(output);
         }
@@ -830,6 +865,18 @@ namespace Google.ProtocolBuffers.TestProtos {
             uint tag;
             string field_name;
             while (input.ReadTag(out tag, out field_name)) {
+              if(tag == 0 && field_name != null) {
+                int field_ordinal = global::System.Array.BinarySearch(_childrenFieldNames, field_name, global::System.StringComparer.Ordinal);
+                if(field_ordinal >= 0)
+                  tag = _childrenFieldTags[field_ordinal];
+                else {
+                  if (unknownFields == null) {
+                    unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+                  }
+                  ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+                  continue;
+                }
+              }
               switch (tag) {
                 case 0: {
                   throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -862,7 +909,7 @@ namespace Google.ProtocolBuffers.TestProtos {
                   break;
                 }
                 case 34: {
-                  result.hasBinary |= input.ReadBytes(ref result.binary_);
+                  result.hasBinary = input.ReadBytes(ref result.binary_);
                   break;
                 }
               }
@@ -1013,28 +1060,29 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _testXmlMessageFieldNames;
       pb::ExtendableMessage<TestXmlMessage, TestXmlMessage.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
       if (hasChild) {
-        output.WriteMessage(1, "child", Child);
+        output.WriteMessage(1, field_names[0], Child);
       }
       if (numbers_.Count > 0) {
-        output.WriteArray(pbd::FieldType.Int32, 2, "numbers", numbers_);
+        output.WriteArray(pbd::FieldType.Int32, 2, field_names[3], numbers_);
       }
       if (hasText) {
-        output.WriteString(3, "text", Text);
+        output.WriteString(3, field_names[4], Text);
       }
       if (hasValid) {
-        output.WriteBool(5, "valid", Valid);
+        output.WriteBool(5, field_names[6], Valid);
       }
       if (hasNumber) {
-        output.WriteInt64(6, "number", Number);
+        output.WriteInt64(6, field_names[2], Number);
       }
       extensionWriter.WriteUntil(200, output);
       if (children_.Count > 0) {
-        output.WriteArray(pbd::FieldType.Group, 401, "children", children_);
+        output.WriteArray(pbd::FieldType.Group, 401, field_names[1], children_);
       }
       if (textlines_.Count > 0) {
-        output.WriteArray(pbd::FieldType.String, 700, "textlines", textlines_);
+        output.WriteArray(pbd::FieldType.String, 700, field_names[5], textlines_);
       }
       UnknownFields.WriteTo(output);
     }
@@ -1211,6 +1259,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_testXmlMessageFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _testXmlMessageFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1243,15 +1303,15 @@ namespace Google.ProtocolBuffers.TestProtos {
               break;
             }
             case 26: {
-              result.hasText |= input.ReadString(ref result.text_);
+              result.hasText = input.ReadString(ref result.text_);
               break;
             }
             case 40: {
-              result.hasValid |= input.ReadBool(ref result.valid_);
+              result.hasValid = input.ReadBool(ref result.valid_);
               break;
             }
             case 48: {
-              result.hasNumber |= input.ReadInt64(ref result.number_);
+              result.hasNumber = input.ReadInt64(ref result.number_);
               break;
             }
             case 3211: {
@@ -1465,6 +1525,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestXmlExtension : pb::GeneratedMessage<TestXmlExtension, TestXmlExtension.Builder> {
     private static readonly TestXmlExtension defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _testXmlExtensionFieldNames = new string[] { "number" };
+    private static readonly uint[] _testXmlExtensionFieldTags = new uint[] { 8 };
     public static TestXmlExtension DefaultInstance {
       get { return defaultInstance; }
     }
@@ -1504,8 +1566,9 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _testXmlExtensionFieldNames;
       if (hasNumber) {
-        output.WriteInt32(1, "number", Number);
+        output.WriteInt32(1, field_names[0], Number);
       }
       UnknownFields.WriteTo(output);
     }
@@ -1631,6 +1694,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_testXmlExtensionFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _testXmlExtensionFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1649,7 +1724,7 @@ namespace Google.ProtocolBuffers.TestProtos {
               break;
             }
             case 8: {
-              result.hasNumber |= input.ReadInt32(ref result.number_);
+              result.hasNumber = input.ReadInt32(ref result.number_);
               break;
             }
           }

+ 91 - 31
src/ProtocolBuffers/DescriptorProtos/CSharpOptions.cs

@@ -124,6 +124,8 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class CSharpFileOptions : pb::GeneratedMessage<CSharpFileOptions, CSharpFileOptions.Builder> {
     private static readonly CSharpFileOptions defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _cSharpFileOptionsFieldNames = new string[] { "cls_compliance", "code_contracts", "expand_namespace_directories", "file_extension", "ignore_google_protobuf", "multiple_files", "namespace", "nest_classes", "output_directory", "public_classes", "service_generator_type", "umbrella_classname", "umbrella_namespace" };
+    private static readonly uint[] _cSharpFileOptionsFieldTags = new uint[] { 64, 48, 56, 1770, 1792, 32, 10, 40, 1786, 24, 1800, 18, 1778 };
     public static CSharpFileOptions DefaultInstance {
       get { return defaultInstance; }
     }
@@ -282,44 +284,45 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _cSharpFileOptionsFieldNames;
       if (hasNamespace) {
-        output.WriteString(1, "namespace", Namespace);
+        output.WriteString(1, field_names[6], Namespace);
       }
       if (hasUmbrellaClassname) {
-        output.WriteString(2, "umbrella_classname", UmbrellaClassname);
+        output.WriteString(2, field_names[11], UmbrellaClassname);
       }
       if (hasPublicClasses) {
-        output.WriteBool(3, "public_classes", PublicClasses);
+        output.WriteBool(3, field_names[9], PublicClasses);
       }
       if (hasMultipleFiles) {
-        output.WriteBool(4, "multiple_files", MultipleFiles);
+        output.WriteBool(4, field_names[5], MultipleFiles);
       }
       if (hasNestClasses) {
-        output.WriteBool(5, "nest_classes", NestClasses);
+        output.WriteBool(5, field_names[7], NestClasses);
       }
       if (hasCodeContracts) {
-        output.WriteBool(6, "code_contracts", CodeContracts);
+        output.WriteBool(6, field_names[1], CodeContracts);
       }
       if (hasExpandNamespaceDirectories) {
-        output.WriteBool(7, "expand_namespace_directories", ExpandNamespaceDirectories);
+        output.WriteBool(7, field_names[2], ExpandNamespaceDirectories);
       }
       if (hasClsCompliance) {
-        output.WriteBool(8, "cls_compliance", ClsCompliance);
+        output.WriteBool(8, field_names[0], ClsCompliance);
       }
       if (hasFileExtension) {
-        output.WriteString(221, "file_extension", FileExtension);
+        output.WriteString(221, field_names[3], FileExtension);
       }
       if (hasUmbrellaNamespace) {
-        output.WriteString(222, "umbrella_namespace", UmbrellaNamespace);
+        output.WriteString(222, field_names[12], UmbrellaNamespace);
       }
       if (hasOutputDirectory) {
-        output.WriteString(223, "output_directory", OutputDirectory);
+        output.WriteString(223, field_names[8], OutputDirectory);
       }
       if (hasIgnoreGoogleProtobuf) {
-        output.WriteBool(224, "ignore_google_protobuf", IgnoreGoogleProtobuf);
+        output.WriteBool(224, field_names[4], IgnoreGoogleProtobuf);
       }
       if (hasServiceGeneratorType) {
-        output.WriteEnum(225, "service_generator_type", (int) ServiceGeneratorType, ServiceGeneratorType.ToString());
+        output.WriteEnum(225, field_names[10], (int) ServiceGeneratorType, ServiceGeneratorType.ToString());
       }
       UnknownFields.WriteTo(output);
     }
@@ -517,6 +520,18 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_cSharpFileOptionsFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _cSharpFileOptionsFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -535,51 +550,51 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
               break;
             }
             case 10: {
-              result.hasNamespace |= input.ReadString(ref result.namespace_);
+              result.hasNamespace = input.ReadString(ref result.namespace_);
               break;
             }
             case 18: {
-              result.hasUmbrellaClassname |= input.ReadString(ref result.umbrellaClassname_);
+              result.hasUmbrellaClassname = input.ReadString(ref result.umbrellaClassname_);
               break;
             }
             case 24: {
-              result.hasPublicClasses |= input.ReadBool(ref result.publicClasses_);
+              result.hasPublicClasses = input.ReadBool(ref result.publicClasses_);
               break;
             }
             case 32: {
-              result.hasMultipleFiles |= input.ReadBool(ref result.multipleFiles_);
+              result.hasMultipleFiles = input.ReadBool(ref result.multipleFiles_);
               break;
             }
             case 40: {
-              result.hasNestClasses |= input.ReadBool(ref result.nestClasses_);
+              result.hasNestClasses = input.ReadBool(ref result.nestClasses_);
               break;
             }
             case 48: {
-              result.hasCodeContracts |= input.ReadBool(ref result.codeContracts_);
+              result.hasCodeContracts = input.ReadBool(ref result.codeContracts_);
               break;
             }
             case 56: {
-              result.hasExpandNamespaceDirectories |= input.ReadBool(ref result.expandNamespaceDirectories_);
+              result.hasExpandNamespaceDirectories = input.ReadBool(ref result.expandNamespaceDirectories_);
               break;
             }
             case 64: {
-              result.hasClsCompliance |= input.ReadBool(ref result.clsCompliance_);
+              result.hasClsCompliance = input.ReadBool(ref result.clsCompliance_);
               break;
             }
             case 1770: {
-              result.hasFileExtension |= input.ReadString(ref result.fileExtension_);
+              result.hasFileExtension = input.ReadString(ref result.fileExtension_);
               break;
             }
             case 1778: {
-              result.hasUmbrellaNamespace |= input.ReadString(ref result.umbrellaNamespace_);
+              result.hasUmbrellaNamespace = input.ReadString(ref result.umbrellaNamespace_);
               break;
             }
             case 1786: {
-              result.hasOutputDirectory |= input.ReadString(ref result.outputDirectory_);
+              result.hasOutputDirectory = input.ReadString(ref result.outputDirectory_);
               break;
             }
             case 1792: {
-              result.hasIgnoreGoogleProtobuf |= input.ReadBool(ref result.ignoreGoogleProtobuf_);
+              result.hasIgnoreGoogleProtobuf = input.ReadBool(ref result.ignoreGoogleProtobuf_);
               break;
             }
             case 1800: {
@@ -853,6 +868,8 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class CSharpFieldOptions : pb::GeneratedMessage<CSharpFieldOptions, CSharpFieldOptions.Builder> {
     private static readonly CSharpFieldOptions defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _cSharpFieldOptionsFieldNames = new string[] { "property_name" };
+    private static readonly uint[] _cSharpFieldOptionsFieldTags = new uint[] { 10 };
     public static CSharpFieldOptions DefaultInstance {
       get { return defaultInstance; }
     }
@@ -891,8 +908,9 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _cSharpFieldOptionsFieldNames;
       if (hasPropertyName) {
-        output.WriteString(1, "property_name", PropertyName);
+        output.WriteString(1, field_names[0], PropertyName);
       }
       UnknownFields.WriteTo(output);
     }
@@ -1018,6 +1036,18 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_cSharpFieldOptionsFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _cSharpFieldOptionsFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1036,7 +1066,7 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
               break;
             }
             case 10: {
-              result.hasPropertyName |= input.ReadString(ref result.propertyName_);
+              result.hasPropertyName = input.ReadString(ref result.propertyName_);
               break;
             }
           }
@@ -1078,6 +1108,8 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class CSharpServiceOptions : pb::GeneratedMessage<CSharpServiceOptions, CSharpServiceOptions.Builder> {
     private static readonly CSharpServiceOptions defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _cSharpServiceOptionsFieldNames = new string[] { "interface_id" };
+    private static readonly uint[] _cSharpServiceOptionsFieldTags = new uint[] { 10 };
     public static CSharpServiceOptions DefaultInstance {
       get { return defaultInstance; }
     }
@@ -1116,8 +1148,9 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _cSharpServiceOptionsFieldNames;
       if (hasInterfaceId) {
-        output.WriteString(1, "interface_id", InterfaceId);
+        output.WriteString(1, field_names[0], InterfaceId);
       }
       UnknownFields.WriteTo(output);
     }
@@ -1243,6 +1276,18 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_cSharpServiceOptionsFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _cSharpServiceOptionsFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1261,7 +1306,7 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
               break;
             }
             case 10: {
-              result.hasInterfaceId |= input.ReadString(ref result.interfaceId_);
+              result.hasInterfaceId = input.ReadString(ref result.interfaceId_);
               break;
             }
           }
@@ -1303,6 +1348,8 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class CSharpMethodOptions : pb::GeneratedMessage<CSharpMethodOptions, CSharpMethodOptions.Builder> {
     private static readonly CSharpMethodOptions defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _cSharpMethodOptionsFieldNames = new string[] { "dispatch_id" };
+    private static readonly uint[] _cSharpMethodOptionsFieldTags = new uint[] { 8 };
     public static CSharpMethodOptions DefaultInstance {
       get { return defaultInstance; }
     }
@@ -1341,8 +1388,9 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _cSharpMethodOptionsFieldNames;
       if (hasDispatchId) {
-        output.WriteInt32(1, "dispatch_id", DispatchId);
+        output.WriteInt32(1, field_names[0], DispatchId);
       }
       UnknownFields.WriteTo(output);
     }
@@ -1468,6 +1516,18 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_cSharpMethodOptionsFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _cSharpMethodOptionsFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1486,7 +1546,7 @@ namespace Google.ProtocolBuffers.DescriptorProtos {
               break;
             }
             case 8: {
-              result.hasDispatchId |= input.ReadInt32(ref result.dispatchId_);
+              result.hasDispatchId = input.ReadInt32(ref result.dispatchId_);
               break;
             }
           }

File diff suppressed because it is too large
+ 329 - 87
src/ProtocolBuffers/DescriptorProtos/DescriptorProtoFile.cs


+ 30 - 0
src/ProtocolBuffers/UnknownFieldSet.cs

@@ -607,6 +607,18 @@ namespace Google.ProtocolBuffers
                 string name;
                 while (input.ReadTag(out tag, out name))
                 {
+                    if (tag == 0 && name != null)
+                    {
+                        FieldDescriptor fieldByName = builder.DescriptorForType.FindFieldByName(name);
+                        if (fieldByName != null)
+                            tag = WireFormat.MakeTag(fieldByName);
+                        else
+                        {
+                            ExtensionInfo extension = extensionRegistry.FindByName(builder.DescriptorForType, name);
+                            if (extension != null)
+                                tag = WireFormat.MakeTag(extension.Descriptor);
+                        }
+                    }
                     if (tag == 0)
                     {
                         if (input.SkipField())
@@ -634,6 +646,19 @@ namespace Google.ProtocolBuffers
             internal bool MergeFieldFrom(ICodedInputStream input,
                                          ExtensionRegistry extensionRegistry, IBuilder builder, uint tag, string fieldName)
             {
+                if (tag == 0 && fieldName != null)
+                {
+                    FieldDescriptor fieldByName = builder.DescriptorForType.FindFieldByName(fieldName);
+                    if (fieldByName != null)
+                        tag = WireFormat.MakeTag(fieldByName);
+                    else
+                    {
+                        ExtensionInfo extension = extensionRegistry.FindByName(builder.DescriptorForType, fieldName);
+                        if (extension != null)
+                            tag = WireFormat.MakeTag(extension.Descriptor);
+                    }
+                }
+
                 MessageDescriptor type = builder.DescriptorForType;
                 if (type.Options.MessageSetWireFormat && tag == WireFormat.MessageSetTag.ItemStart)
                 {
@@ -799,6 +824,11 @@ namespace Google.ProtocolBuffers
                 string name;
                 while (input.ReadTag(out tag, out name))
                 {
+                    if (tag == 0 && name != null)
+                    {
+                        if (name == "type_id") tag = WireFormat.MessageSetTag.TypeID;
+                        else if (name == "message") tag = WireFormat.MessageSetTag.Message;
+                    }
                     if (tag == 0)
                     {
                         if (input.SkipField())

+ 87 - 27
src/ProtocolBuffersLite.Test/TestProtos/UnitTestExtrasLiteProtoFile.cs

@@ -58,6 +58,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestRequiredLite : pb::GeneratedMessageLite<TestRequiredLite, TestRequiredLite.Builder> {
     private static readonly TestRequiredLite defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _testRequiredLiteFieldNames = new string[] { "d", "en" };
+    private static readonly uint[] _testRequiredLiteFieldTags = new uint[] { 8, 16 };
     public static TestRequiredLite DefaultInstance {
       get { return defaultInstance; }
     }
@@ -100,11 +102,12 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _testRequiredLiteFieldNames;
       if (hasD) {
-        output.WriteInt32(1, "d", D);
+        output.WriteInt32(1, field_names[0], D);
       }
       if (hasEn) {
-        output.WriteEnum(2, "en", (int) En, En.ToString());
+        output.WriteEnum(2, field_names[1], (int) En, En.ToString());
       }
     }
     
@@ -250,6 +253,15 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_testRequiredLiteFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _testRequiredLiteFieldTags[field_ordinal];
+            else {
+              ParseUnknownField(input, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -262,7 +274,7 @@ namespace Google.ProtocolBuffers.TestProtos {
               break;
             }
             case 8: {
-              result.hasD |= input.ReadInt32(ref result.d_);
+              result.hasD = input.ReadInt32(ref result.d_);
               break;
             }
             case 16: {
@@ -326,6 +338,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestInteropPersonLite : pb::ExtendableMessageLite<TestInteropPersonLite, TestInteropPersonLite.Builder> {
     private static readonly TestInteropPersonLite defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _testInteropPersonLiteFieldNames = new string[] { "addresses", "codes", "email", "id", "name", "phone" };
+    private static readonly uint[] _testInteropPersonLiteFieldTags = new uint[] { 43, 82, 26, 16, 10, 34 };
     public static TestInteropPersonLite DefaultInstance {
       get { return defaultInstance; }
     }
@@ -356,6 +370,8 @@ namespace Google.ProtocolBuffers.TestProtos {
       [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
       public sealed partial class PhoneNumber : pb::GeneratedMessageLite<PhoneNumber, PhoneNumber.Builder> {
         private static readonly PhoneNumber defaultInstance = new Builder().BuildPartial();
+        private static readonly string[] _phoneNumberFieldNames = new string[] { "number", "type" };
+        private static readonly uint[] _phoneNumberFieldTags = new uint[] { 10, 16 };
         public static PhoneNumber DefaultInstance {
           get { return defaultInstance; }
         }
@@ -397,11 +413,12 @@ namespace Google.ProtocolBuffers.TestProtos {
         
         public override void WriteTo(pb::ICodedOutputStream output) {
           int size = SerializedSize;
+          string[] field_names = _phoneNumberFieldNames;
           if (hasNumber) {
-            output.WriteString(1, "number", Number);
+            output.WriteString(1, field_names[0], Number);
           }
           if (hasType) {
-            output.WriteEnum(2, "type", (int) Type, Type.ToString());
+            output.WriteEnum(2, field_names[1], (int) Type, Type.ToString());
           }
         }
         
@@ -547,6 +564,15 @@ namespace Google.ProtocolBuffers.TestProtos {
             uint tag;
             string field_name;
             while (input.ReadTag(out tag, out field_name)) {
+              if(tag == 0 && field_name != null) {
+                int field_ordinal = global::System.Array.BinarySearch(_phoneNumberFieldNames, field_name, global::System.StringComparer.Ordinal);
+                if(field_ordinal >= 0)
+                  tag = _phoneNumberFieldTags[field_ordinal];
+                else {
+                  ParseUnknownField(input, extensionRegistry, tag, field_name);
+                  continue;
+                }
+              }
               switch (tag) {
                 case 0: {
                   throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -559,7 +585,7 @@ namespace Google.ProtocolBuffers.TestProtos {
                   break;
                 }
                 case 10: {
-                  result.hasNumber |= input.ReadString(ref result.number_);
+                  result.hasNumber = input.ReadString(ref result.number_);
                   break;
                 }
                 case 16: {
@@ -624,6 +650,8 @@ namespace Google.ProtocolBuffers.TestProtos {
       [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
       public sealed partial class Addresses : pb::GeneratedMessageLite<Addresses, Addresses.Builder> {
         private static readonly Addresses defaultInstance = new Builder().BuildPartial();
+        private static readonly string[] _addressesFieldNames = new string[] { "address", "address2", "city", "state", "zip" };
+        private static readonly uint[] _addressesFieldTags = new uint[] { 10, 18, 26, 34, 45 };
         public static Addresses DefaultInstance {
           get { return defaultInstance; }
         }
@@ -699,20 +727,21 @@ namespace Google.ProtocolBuffers.TestProtos {
         
         public override void WriteTo(pb::ICodedOutputStream output) {
           int size = SerializedSize;
+          string[] field_names = _addressesFieldNames;
           if (hasAddress) {
-            output.WriteString(1, "address", Address);
+            output.WriteString(1, field_names[0], Address);
           }
           if (hasAddress2) {
-            output.WriteString(2, "address2", Address2);
+            output.WriteString(2, field_names[1], Address2);
           }
           if (hasCity) {
-            output.WriteString(3, "city", City);
+            output.WriteString(3, field_names[2], City);
           }
           if (hasState) {
-            output.WriteString(4, "state", State);
+            output.WriteString(4, field_names[3], State);
           }
           if (hasZip) {
-            output.WriteFixed32(5, "zip", Zip);
+            output.WriteFixed32(5, field_names[4], Zip);
           }
         }
         
@@ -885,6 +914,15 @@ namespace Google.ProtocolBuffers.TestProtos {
             uint tag;
             string field_name;
             while (input.ReadTag(out tag, out field_name)) {
+              if(tag == 0 && field_name != null) {
+                int field_ordinal = global::System.Array.BinarySearch(_addressesFieldNames, field_name, global::System.StringComparer.Ordinal);
+                if(field_ordinal >= 0)
+                  tag = _addressesFieldTags[field_ordinal];
+                else {
+                  ParseUnknownField(input, extensionRegistry, tag, field_name);
+                  continue;
+                }
+              }
               switch (tag) {
                 case 0: {
                   throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -897,23 +935,23 @@ namespace Google.ProtocolBuffers.TestProtos {
                   break;
                 }
                 case 10: {
-                  result.hasAddress |= input.ReadString(ref result.address_);
+                  result.hasAddress = input.ReadString(ref result.address_);
                   break;
                 }
                 case 18: {
-                  result.hasAddress2 |= input.ReadString(ref result.address2_);
+                  result.hasAddress2 = input.ReadString(ref result.address2_);
                   break;
                 }
                 case 26: {
-                  result.hasCity |= input.ReadString(ref result.city_);
+                  result.hasCity = input.ReadString(ref result.city_);
                   break;
                 }
                 case 34: {
-                  result.hasState |= input.ReadString(ref result.state_);
+                  result.hasState = input.ReadString(ref result.state_);
                   break;
                 }
                 case 45: {
-                  result.hasZip |= input.ReadFixed32(ref result.zip_);
+                  result.hasZip = input.ReadFixed32(ref result.zip_);
                   break;
                 }
               }
@@ -1108,24 +1146,25 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _testInteropPersonLiteFieldNames;
       pb::ExtendableMessageLite<TestInteropPersonLite, TestInteropPersonLite.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);
       if (hasName) {
-        output.WriteString(1, "name", Name);
+        output.WriteString(1, field_names[4], Name);
       }
       if (hasId) {
-        output.WriteInt32(2, "id", Id);
+        output.WriteInt32(2, field_names[3], Id);
       }
       if (hasEmail) {
-        output.WriteString(3, "email", Email);
+        output.WriteString(3, field_names[2], Email);
       }
       if (phone_.Count > 0) {
-        output.WriteArray(pbd::FieldType.Message, 4, "phone", phone_);
+        output.WriteArray(pbd::FieldType.Message, 4, field_names[5], phone_);
       }
       if (addresses_.Count > 0) {
-        output.WriteArray(pbd::FieldType.Group, 5, "addresses", addresses_);
+        output.WriteArray(pbd::FieldType.Group, 5, field_names[0], addresses_);
       }
       if (codes_.Count > 0) {
-        output.WritePackedArray(pbd::FieldType.Int32, 10, "codes", codesMemoizedSerializedSize, codes_);
+        output.WritePackedArray(pbd::FieldType.Int32, 10, field_names[1], codesMemoizedSerializedSize, codes_);
       }
       extensionWriter.WriteUntil(200, output);
     }
@@ -1333,6 +1372,15 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_testInteropPersonLiteFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _testInteropPersonLiteFieldTags[field_ordinal];
+            else {
+              ParseUnknownField(input, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1345,15 +1393,15 @@ namespace Google.ProtocolBuffers.TestProtos {
               break;
             }
             case 10: {
-              result.hasName |= input.ReadString(ref result.name_);
+              result.hasName = input.ReadString(ref result.name_);
               break;
             }
             case 16: {
-              result.hasId |= input.ReadInt32(ref result.id_);
+              result.hasId = input.ReadInt32(ref result.id_);
               break;
             }
             case 26: {
-              result.hasEmail |= input.ReadString(ref result.email_);
+              result.hasEmail = input.ReadString(ref result.email_);
               break;
             }
             case 34: {
@@ -1544,6 +1592,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestInteropEmployeeIdLite : pb::GeneratedMessageLite<TestInteropEmployeeIdLite, TestInteropEmployeeIdLite.Builder> {
     private static readonly TestInteropEmployeeIdLite defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _testInteropEmployeeIdLiteFieldNames = new string[] { "number" };
+    private static readonly uint[] _testInteropEmployeeIdLiteFieldTags = new uint[] { 10 };
     public static TestInteropEmployeeIdLite DefaultInstance {
       get { return defaultInstance; }
     }
@@ -1575,8 +1625,9 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _testInteropEmployeeIdLiteFieldNames;
       if (hasNumber) {
-        output.WriteString(1, "number", Number);
+        output.WriteString(1, field_names[0], Number);
       }
     }
     
@@ -1713,6 +1764,15 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_testInteropEmployeeIdLiteFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _testInteropEmployeeIdLiteFieldTags[field_ordinal];
+            else {
+              ParseUnknownField(input, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -1725,7 +1785,7 @@ namespace Google.ProtocolBuffers.TestProtos {
               break;
             }
             case 10: {
-              result.hasNumber |= input.ReadString(ref result.number_);
+              result.hasNumber = input.ReadString(ref result.number_);
               break;
             }
           }

+ 14 - 2
src/ProtocolBuffersLite.Test/TestProtos/UnitTestImportLiteProtoFile.cs

@@ -42,6 +42,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class ImportMessageLite : pb::GeneratedMessageLite<ImportMessageLite, ImportMessageLite.Builder> {
     private static readonly ImportMessageLite defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _importMessageLiteFieldNames = new string[] { "d" };
+    private static readonly uint[] _importMessageLiteFieldTags = new uint[] { 8 };
     public static ImportMessageLite DefaultInstance {
       get { return defaultInstance; }
     }
@@ -72,8 +74,9 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _importMessageLiteFieldNames;
       if (hasD) {
-        output.WriteInt32(1, "d", D);
+        output.WriteInt32(1, field_names[0], D);
       }
     }
     
@@ -210,6 +213,15 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_importMessageLiteFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _importMessageLiteFieldTags[field_ordinal];
+            else {
+              ParseUnknownField(input, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -222,7 +234,7 @@ namespace Google.ProtocolBuffers.TestProtos {
               break;
             }
             case 8: {
-              result.hasD |= input.ReadInt32(ref result.d_);
+              result.hasD = input.ReadInt32(ref result.d_);
               break;
             }
           }

+ 17 - 2
src/ProtocolBuffersLite.Test/TestProtos/UnitTestImportProtoFile.cs

@@ -70,6 +70,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class ImportMessage : pb::GeneratedMessage<ImportMessage, ImportMessage.Builder> {
     private static readonly ImportMessage defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _importMessageFieldNames = new string[] { "d" };
+    private static readonly uint[] _importMessageFieldTags = new uint[] { 8 };
     public static ImportMessage DefaultInstance {
       get { return defaultInstance; }
     }
@@ -108,8 +110,9 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _importMessageFieldNames;
       if (hasD) {
-        output.WriteInt32(1, "d", D);
+        output.WriteInt32(1, field_names[0], D);
       }
       UnknownFields.WriteTo(output);
     }
@@ -235,6 +238,18 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_importMessageFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _importMessageFieldTags[field_ordinal];
+            else {
+              if (unknownFields == null) {
+                unknownFields = pb::UnknownFieldSet.CreateBuilder(this.UnknownFields);
+              }
+              ParseUnknownField(input, unknownFields, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();
@@ -253,7 +268,7 @@ namespace Google.ProtocolBuffers.TestProtos {
               break;
             }
             case 8: {
-              result.hasD |= input.ReadInt32(ref result.d_);
+              result.hasD = input.ReadInt32(ref result.d_);
               break;
             }
           }

+ 13 - 1
src/ProtocolBuffersLite.Test/TestProtos/UnitTestLiteImportNonLiteProtoFile.cs

@@ -31,6 +31,8 @@ namespace Google.ProtocolBuffers.TestProtos {
   [global::System.CodeDom.Compiler.GeneratedCodeAttribute("ProtoGen", "2.3.0.277")]
   public sealed partial class TestLiteImportsNonlite : pb::GeneratedMessageLite<TestLiteImportsNonlite, TestLiteImportsNonlite.Builder> {
     private static readonly TestLiteImportsNonlite defaultInstance = new Builder().BuildPartial();
+    private static readonly string[] _testLiteImportsNonliteFieldNames = new string[] { "message" };
+    private static readonly uint[] _testLiteImportsNonliteFieldTags = new uint[] { 10 };
     public static TestLiteImportsNonlite DefaultInstance {
       get { return defaultInstance; }
     }
@@ -61,8 +63,9 @@ namespace Google.ProtocolBuffers.TestProtos {
     
     public override void WriteTo(pb::ICodedOutputStream output) {
       int size = SerializedSize;
+      string[] field_names = _testLiteImportsNonliteFieldNames;
       if (hasMessage) {
-        output.WriteMessage(1, "message", Message);
+        output.WriteMessage(1, field_names[0], Message);
       }
     }
     
@@ -199,6 +202,15 @@ namespace Google.ProtocolBuffers.TestProtos {
         uint tag;
         string field_name;
         while (input.ReadTag(out tag, out field_name)) {
+          if(tag == 0 && field_name != null) {
+            int field_ordinal = global::System.Array.BinarySearch(_testLiteImportsNonliteFieldNames, field_name, global::System.StringComparer.Ordinal);
+            if(field_ordinal >= 0)
+              tag = _testLiteImportsNonliteFieldTags[field_ordinal];
+            else {
+              ParseUnknownField(input, extensionRegistry, tag, field_name);
+              continue;
+            }
+          }
           switch (tag) {
             case 0: {
               throw pb::InvalidProtocolBufferException.InvalidTag();

File diff suppressed because it is too large
+ 274 - 142
src/ProtocolBuffersLite.Test/TestProtos/UnitTestLiteProtoFile.cs


File diff suppressed because it is too large
+ 302 - 149
src/ProtocolBuffersLite.Test/TestProtos/UnitTestProtoFile.cs


Some files were not shown because too many files changed in this diff