diff --git a/src/AddressBook/AddressBookProtos.cs b/src/AddressBook/AddressBookProtos.cs index bd284771ba..58cba4ad6f 100644 --- a/src/AddressBook/AddressBookProtos.cs +++ b/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 { 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 { 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 { 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(); diff --git a/src/ProtoBench/Program.cs b/src/ProtoBench/Program.cs index 36f7850da6..2be2bf4f41 100644 --- a/src/ProtoBench/Program.cs +++ b/src/ProtoBench/Program.cs @@ -58,6 +58,7 @@ namespace Google.ProtocolBuffers.ProtoBench private static BenchmarkTest RunBenchmark; + [STAThread] public static int Main(string[] args) { List temp = new List(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, diff --git a/src/ProtoGen/EnumFieldGenerator.cs b/src/ProtoGen/EnumFieldGenerator.cs index 763c18ab37..d5e8c6364b 100644 --- a/src/ProtoGen/EnumFieldGenerator.cs +++ b/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("}"); } diff --git a/src/ProtoGen/ExtensionGenerator.cs b/src/ProtoGen/ExtensionGenerator.cs index ce37b2de43..824718bf98 100644 --- a/src/ProtoGen/ExtensionGenerator.cs +++ b/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) { diff --git a/src/ProtoGen/FieldGeneratorBase.cs b/src/ProtoGen/FieldGeneratorBase.cs index 4d2ec43846..77a8765cae 100644 --- a/src/ProtoGen/FieldGeneratorBase.cs +++ b/src/ProtoGen/FieldGeneratorBase.cs @@ -42,15 +42,20 @@ namespace Google.ProtocolBuffers.ProtoGen { internal abstract class FieldGeneratorBase : SourceGeneratorBase { - 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) diff --git a/src/ProtoGen/MessageFieldGenerator.cs b/src/ProtoGen/MessageFieldGenerator.cs index c5b3a6a533..cb3659547e 100644 --- a/src/ProtoGen/MessageFieldGenerator.cs +++ b/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("}"); } diff --git a/src/ProtoGen/MessageGenerator.cs b/src/ProtoGen/MessageGenerator.cs index 65a2d89603..fe30e49ab2 100644 --- a/src/ProtoGen/MessageGenerator.cs +++ b/src/ProtoGen/MessageGenerator.cs @@ -44,6 +44,8 @@ namespace Google.ProtocolBuffers.ProtoGen { internal class MessageGenerator : SourceGeneratorBase, 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 names = new List(); + 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 tags = new List(); + 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("}"); diff --git a/src/ProtoGen/PrimitiveFieldGenerator.cs b/src/ProtoGen/PrimitiveFieldGenerator.cs index 7fc583c357..6296cdc7fd 100644 --- a/src/ProtoGen/PrimitiveFieldGenerator.cs +++ b/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("}"); } diff --git a/src/ProtoGen/ProtoGen.csproj b/src/ProtoGen/ProtoGen.csproj index b865a53aa6..fa93aa7813 100644 --- a/src/ProtoGen/ProtoGen.csproj +++ b/src/ProtoGen/ProtoGen.csproj @@ -56,10 +56,6 @@ AllRules.ruleset - - False - ..\..\build\2.3.0.304\Google.ProtocolBuffers.dll - @@ -113,6 +109,12 @@ true + + + {6908BDCE-D925-43F3-94AC-A531E6DF2591} + ProtocolBuffers + +