Browse Source

Finished adding find tag by name

csharptest 14 năm trước cách đây
mục cha
commit
920b09a3b0
33 tập tin đã thay đổi với 2549 bổ sung1135 xóa
  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();

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 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;
             }
           }

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 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;
             }
           }

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 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();

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 274 - 142
src/ProtocolBuffersLite.Test/TestProtos/UnitTestLiteProtoFile.cs


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 302 - 149
src/ProtocolBuffersLite.Test/TestProtos/UnitTestProtoFile.cs


Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác