aboutsummaryrefslogtreecommitdiff
path: root/src/ProtoGen/MessageGenerator.cs
diff options
context:
space:
mode:
Diffstat (limited to 'src/ProtoGen/MessageGenerator.cs')
-rw-r--r--src/ProtoGen/MessageGenerator.cs196
1 files changed, 133 insertions, 63 deletions
diff --git a/src/ProtoGen/MessageGenerator.cs b/src/ProtoGen/MessageGenerator.cs
index 3488cdc9..43b8b7eb 100644
--- a/src/ProtoGen/MessageGenerator.cs
+++ b/src/ProtoGen/MessageGenerator.cs
@@ -32,6 +32,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#endregion
+using System;
using System.Collections.Generic;
using Google.ProtocolBuffers.DescriptorProtos;
using Google.ProtocolBuffers.Descriptors;
@@ -69,12 +70,13 @@ namespace Google.ProtocolBuffers.ProtoGen {
string identifier = GetUniqueFileScopeIdentifier(Descriptor);
- // The descriptor for this type.
- string access = Descriptor.File.CSharpOptions.NestClasses ? "private" : "internal";
- writer.WriteLine("{0} static pbd::MessageDescriptor internal__{1}__Descriptor;", access, identifier);
- writer.WriteLine("{0} static pb::FieldAccess.FieldAccessorTable<{1}, {1}.Builder> internal__{2}__FieldAccessorTable;",
- access, FullClassName, identifier);
-
+ if (!UseLiteRuntime) {
+ // The descriptor for this type.
+ string access = Descriptor.File.CSharpOptions.NestClasses ? "private" : "internal";
+ writer.WriteLine("{0} static pbd::MessageDescriptor internal__{1}__Descriptor;", access, identifier);
+ writer.WriteLine("{0} static pb::FieldAccess.FieldAccessorTable<{1}, {1}.Builder> internal__{2}__FieldAccessorTable;",
+ access, FullClassName, identifier);
+ }
// Generate static members for all nested types.
foreach (MessageDescriptor nestedMessage in Descriptor.NestedTypes) {
new MessageGenerator(nestedMessage).GenerateStaticVariables(writer);
@@ -84,21 +86,23 @@ namespace Google.ProtocolBuffers.ProtoGen {
internal void GenerateStaticVariableInitializers(TextGenerator writer) {
string identifier = GetUniqueFileScopeIdentifier(Descriptor);
- writer.Write("internal__{0}__Descriptor = ", identifier);
- if (Descriptor.ContainingType == null) {
- writer.WriteLine("Descriptor.MessageTypes[{0}];", Descriptor.Index);
- } else {
- writer.WriteLine("internal__{0}__Descriptor.NestedTypes[{1}];", GetUniqueFileScopeIdentifier(Descriptor.ContainingType), Descriptor.Index);
- }
+ if (!UseLiteRuntime) {
+ writer.Write("internal__{0}__Descriptor = ", identifier);
+ if (Descriptor.ContainingType == null) {
+ writer.WriteLine("Descriptor.MessageTypes[{0}];", Descriptor.Index);
+ } else {
+ writer.WriteLine("internal__{0}__Descriptor.NestedTypes[{1}];", GetUniqueFileScopeIdentifier(Descriptor.ContainingType), Descriptor.Index);
+ }
- writer.WriteLine("internal__{0}__FieldAccessorTable = ", identifier);
- writer.WriteLine(" new pb::FieldAccess.FieldAccessorTable<{1}, {1}.Builder>(internal__{0}__Descriptor,",
- identifier, FullClassName);
- writer.Print(" new string[] { ");
- foreach (FieldDescriptor field in Descriptor.Fields) {
- writer.Write("\"{0}\", ", field.CSharpOptions.PropertyName);
+ writer.WriteLine("internal__{0}__FieldAccessorTable = ", identifier);
+ writer.WriteLine(" new pb::FieldAccess.FieldAccessorTable<{1}, {1}.Builder>(internal__{0}__Descriptor,",
+ identifier, FullClassName);
+ writer.Print(" new string[] { ");
+ foreach (FieldDescriptor field in Descriptor.Fields) {
+ writer.Write("\"{0}\", ", field.CSharpOptions.PropertyName);
+ }
+ writer.WriteLine("});");
}
- writer.WriteLine("});");
// Generate static member initializers for all nested types.
foreach (MessageDescriptor nestedMessage in Descriptor.NestedTypes) {
@@ -111,8 +115,10 @@ namespace Google.ProtocolBuffers.ProtoGen {
}
public void Generate(TextGenerator writer) {
- writer.WriteLine("{0} sealed partial class {1} : pb::{2}Message<{1}, {1}.Builder> {{",
- ClassAccessLevel, ClassName, Descriptor.Proto.ExtensionRangeCount > 0 ? "Extendable" : "Generated");
+ writer.WriteLine("{0} sealed partial class {1} : pb::{2}Message{3}<{1}, {1}.Builder> {{",
+ ClassAccessLevel, ClassName,
+ Descriptor.Proto.ExtensionRangeCount > 0 ? "Extendable" : "Generated",
+ RuntimeSuffix);
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);
@@ -128,16 +134,18 @@ namespace Google.ProtocolBuffers.ProtoGen {
writer.WriteLine(" get { return this; }");
writer.WriteLine("}");
writer.WriteLine();
- writer.WriteLine("public static pbd::MessageDescriptor Descriptor {");
- writer.WriteLine(" get {{ return {0}.internal__{1}__Descriptor; }}", DescriptorUtil.GetFullUmbrellaClassName(Descriptor),
- GetUniqueFileScopeIdentifier(Descriptor));
- writer.WriteLine("}");
- writer.WriteLine();
- writer.WriteLine("protected override pb::FieldAccess.FieldAccessorTable<{0}, {0}.Builder> InternalFieldAccessors {{", ClassName);
- writer.WriteLine(" get {{ return {0}.internal__{1}__FieldAccessorTable; }}", DescriptorUtil.GetFullUmbrellaClassName(Descriptor),
- GetUniqueFileScopeIdentifier(Descriptor));
- writer.WriteLine("}");
- writer.WriteLine();
+ if (!UseLiteRuntime) {
+ writer.WriteLine("public static pbd::MessageDescriptor Descriptor {");
+ writer.WriteLine(" get {{ return {0}.internal__{1}__Descriptor; }}", DescriptorUtil.GetFullUmbrellaClassName(Descriptor),
+ GetUniqueFileScopeIdentifier(Descriptor));
+ writer.WriteLine("}");
+ writer.WriteLine();
+ writer.WriteLine("protected override pb::FieldAccess.FieldAccessorTable<{0}, {0}.Builder> InternalFieldAccessors {{", ClassName);
+ writer.WriteLine(" get {{ return {0}.internal__{1}__FieldAccessorTable; }}", DescriptorUtil.GetFullUmbrellaClassName(Descriptor),
+ GetUniqueFileScopeIdentifier(Descriptor));
+ writer.WriteLine("}");
+ writer.WriteLine();
+ }
// Extensions don't need to go in an extra nested type
WriteChildren(writer, null, Descriptor.Extensions);
@@ -161,10 +169,13 @@ namespace Google.ProtocolBuffers.ProtoGen {
writer.WriteLine();
}
- if (Descriptor.File.Options.OptimizeFor == FileOptions.Types.OptimizeMode.SPEED) {
+ if (OptimizeSpeed) {
GenerateIsInitialized(writer);
GenerateMessageSerializationMethods(writer);
}
+ if (UseLiteRuntime) {
+ GenerateLiteRuntimeMethods(writer);
+ }
GenerateParseFromMethods(writer);
GenerateBuilder(writer);
@@ -184,6 +195,49 @@ namespace Google.ProtocolBuffers.ProtoGen {
writer.WriteLine();
}
+ private void GenerateLiteRuntimeMethods(TextGenerator writer) {
+
+ bool callbase = Descriptor.Proto.ExtensionRangeCount > 0;
+ writer.WriteLine("#region Lite runtime methods");
+ writer.WriteLine("public override int GetHashCode() {");
+ writer.Indent();
+ writer.WriteLine("int hash = GetType().GetHashCode();");
+ foreach (FieldDescriptor fieldDescriptor in Descriptor.Fields) {
+ SourceGenerators.CreateFieldGenerator(fieldDescriptor).WriteHash(writer);
+ }
+ if (callbase) writer.WriteLine("hash ^= base.GetHashCode();");
+ writer.WriteLine("return hash;");
+ writer.Outdent();
+ writer.WriteLine("}");
+ writer.WriteLine();
+
+ writer.WriteLine("public override bool Equals(object obj) {");
+ writer.Indent();
+ writer.WriteLine("{0} other = obj as {0};", ClassName);
+ writer.WriteLine("if (other == null) return false;");
+ foreach (FieldDescriptor fieldDescriptor in Descriptor.Fields) {
+ SourceGenerators.CreateFieldGenerator(fieldDescriptor).WriteEquals(writer);
+ }
+ if (callbase) writer.WriteLine("if (!base.Equals(other)) return false;");
+ writer.WriteLine("return true;");
+ writer.Outdent();
+ writer.WriteLine("}");
+ writer.WriteLine();
+
+ writer.WriteLine("public override void PrintTo(global::System.IO.TextWriter writer) {");
+ writer.Indent();
+ List<FieldDescriptor> sorted = new List<FieldDescriptor>(Descriptor.Fields);
+ sorted.Sort(new Comparison<FieldDescriptor>(delegate(FieldDescriptor a, FieldDescriptor b) { return a.FieldNumber.CompareTo(b.FieldNumber); }));
+ foreach (FieldDescriptor fieldDescriptor in sorted) {
+ SourceGenerators.CreateFieldGenerator(fieldDescriptor).WriteToString(writer);
+ }
+ if (callbase) writer.WriteLine("base.PrintTo(writer);");
+ writer.Outdent();
+ writer.WriteLine("}");
+ writer.WriteLine("#endregion");
+ writer.WriteLine();
+ }
+
private void GenerateMessageSerializationMethods(TextGenerator writer) {
List<FieldDescriptor> sortedFields = new List<FieldDescriptor>(Descriptor.Fields);
sortedFields.Sort((f1, f2) => f1.FieldNumber.CompareTo(f2.FieldNumber));
@@ -196,8 +250,8 @@ namespace Google.ProtocolBuffers.ProtoGen {
// Make sure we've computed the serialized length, so that packed fields are generated correctly.
writer.WriteLine("int size = SerializedSize;");
if (Descriptor.Proto.ExtensionRangeList.Count > 0) {
- writer.WriteLine("pb::ExtendableMessage<{0}, {0}.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);",
- ClassName);
+ writer.WriteLine("pb::ExtendableMessage{1}<{0}, {0}.Builder>.ExtensionWriter extensionWriter = CreateExtensionWriter(this);",
+ ClassName, RuntimeSuffix);
}
// Merge the fields and the extension ranges, both sorted by field number.
@@ -213,10 +267,12 @@ namespace Google.ProtocolBuffers.ProtoGen {
}
}
- if (Descriptor.Proto.Options.MessageSetWireFormat) {
- writer.WriteLine("UnknownFields.WriteAsMessageSetTo(output);");
- } else {
- writer.WriteLine("UnknownFields.WriteTo(output);");
+ if (!UseLiteRuntime) {
+ if (Descriptor.Proto.Options.MessageSetWireFormat) {
+ writer.WriteLine("UnknownFields.WriteAsMessageSetTo(output);");
+ } else {
+ writer.WriteLine("UnknownFields.WriteTo(output);");
+ }
}
writer.Outdent();
@@ -238,10 +294,12 @@ namespace Google.ProtocolBuffers.ProtoGen {
writer.WriteLine("size += ExtensionsSerializedSize;");
}
- if (Descriptor.Options.MessageSetWireFormat) {
- writer.WriteLine("size += UnknownFields.SerializedSizeAsMessageSet;");
- } else {
- writer.WriteLine("size += UnknownFields.SerializedSize;");
+ if (!UseLiteRuntime) {
+ if (Descriptor.Options.MessageSetWireFormat) {
+ writer.WriteLine("size += UnknownFields.SerializedSizeAsMessageSet;");
+ } else {
+ writer.WriteLine("size += UnknownFields.SerializedSize;");
+ }
}
writer.WriteLine("memoizedSerializedSize = size;");
writer.WriteLine("return size;");
@@ -345,14 +403,14 @@ namespace Google.ProtocolBuffers.ProtoGen {
writer.WriteLine(" return (Builder) new Builder().MergeFrom(prototype);");
writer.WriteLine("}");
writer.WriteLine();
- writer.WriteLine("{0} sealed partial class Builder : pb::{2}Builder<{1}, Builder> {{",
- ClassAccessLevel, ClassName, Descriptor.Proto.ExtensionRangeCount > 0 ? "Extendable" : "Generated");
+ writer.WriteLine("{0} sealed partial class Builder : pb::{2}Builder{3}<{1}, Builder> {{",
+ ClassAccessLevel, ClassName, Descriptor.Proto.ExtensionRangeCount > 0 ? "Extendable" : "Generated", RuntimeSuffix);
writer.Indent();
writer.WriteLine("protected override Builder ThisBuilder {");
writer.WriteLine(" get { return this; }");
writer.WriteLine("}");
GenerateCommonBuilderMethods(writer);
- if (Descriptor.File.Options.OptimizeFor == FileOptions.Types.OptimizeMode.SPEED) {
+ if (OptimizeSpeed) {
GenerateBuilderParsingMethods(writer);
}
foreach (FieldDescriptor field in Descriptor.Fields) {
@@ -382,10 +440,12 @@ namespace Google.ProtocolBuffers.ProtoGen {
writer.WriteLine(" return new Builder().MergeFrom(result);");
writer.WriteLine("}");
writer.WriteLine();
- writer.WriteLine("public override pbd::MessageDescriptor DescriptorForType {");
- writer.WriteLine(" get {{ return {0}.Descriptor; }}", FullClassName);
- writer.WriteLine("}");
- writer.WriteLine();
+ if (!UseLiteRuntime) {
+ writer.WriteLine("public override pbd::MessageDescriptor DescriptorForType {");
+ writer.WriteLine(" get {{ return {0}.Descriptor; }}", FullClassName);
+ writer.WriteLine("}");
+ writer.WriteLine();
+ }
writer.WriteLine("public override {0} DefaultInstanceForType {{", ClassName);
writer.WriteLine(" get {{ return {0}.DefaultInstance; }}", FullClassName);
writer.WriteLine("}");
@@ -406,8 +466,8 @@ namespace Google.ProtocolBuffers.ProtoGen {
writer.WriteLine("}");
writer.WriteLine();
- if (Descriptor.File.Options.OptimizeFor == FileOptions.Types.OptimizeMode.SPEED) {
- writer.WriteLine("public override Builder MergeFrom(pb::IMessage other) {");
+ if (OptimizeSpeed) {
+ writer.WriteLine("public override Builder MergeFrom(pb::IMessage{0} other) {{", RuntimeSuffix);
writer.WriteLine(" if (other is {0}) {{", ClassName);
writer.WriteLine(" return MergeFrom(({0}) other);", ClassName);
writer.WriteLine(" } else {");
@@ -428,7 +488,9 @@ namespace Google.ProtocolBuffers.ProtoGen {
if (Descriptor.Proto.ExtensionRangeCount > 0) {
writer.WriteLine(" this.MergeExtensionFields(other);");
}
- writer.WriteLine("this.MergeUnknownFields(other.UnknownFields);");
+ if (!UseLiteRuntime) {
+ writer.WriteLine("this.MergeUnknownFields(other.UnknownFields);");
+ }
writer.WriteLine("return this;");
writer.Outdent();
writer.WriteLine("}");
@@ -446,29 +508,37 @@ namespace Google.ProtocolBuffers.ProtoGen {
writer.WriteLine();
writer.WriteLine("public override Builder MergeFrom(pb::CodedInputStream input, pb::ExtensionRegistry extensionRegistry) {");
writer.Indent();
- writer.WriteLine("pb::UnknownFieldSet.Builder unknownFields = null;");
+ if (!UseLiteRuntime) {
+ writer.WriteLine("pb::UnknownFieldSet.Builder unknownFields = null;");
+ }
writer.WriteLine("while (true) {");
writer.Indent();
writer.WriteLine("uint tag = input.ReadTag();");
writer.WriteLine("switch (tag) {");
writer.Indent();
writer.WriteLine("case 0: {"); // 0 signals EOF / limit reached
- writer.WriteLine(" if (unknownFields != null) {");
- writer.WriteLine(" this.UnknownFields = unknownFields.Build();");
- writer.WriteLine(" }");
+ if (!UseLiteRuntime) {
+ writer.WriteLine(" if (unknownFields != null) {");
+ writer.WriteLine(" this.UnknownFields = unknownFields.Build();");
+ writer.WriteLine(" }");
+ }
writer.WriteLine(" return this;");
writer.WriteLine("}");
writer.WriteLine("default: {");
writer.WriteLine(" if (pb::WireFormat.IsEndGroupTag(tag)) {");
- writer.WriteLine(" if (unknownFields != null) {");
- writer.WriteLine(" this.UnknownFields = unknownFields.Build();");
- writer.WriteLine(" }");
+ if (!UseLiteRuntime) {
+ writer.WriteLine(" if (unknownFields != null) {");
+ writer.WriteLine(" this.UnknownFields = unknownFields.Build();");
+ writer.WriteLine(" }");
+ }
writer.WriteLine(" return this;"); // it's an endgroup tag
writer.WriteLine(" }");
- 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, unknownFields, extensionRegistry, tag);");
+ 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);", UseLiteRuntime ? "" : "unknownFields, ");
writer.WriteLine(" break;");
writer.WriteLine("}");
foreach (FieldDescriptor field in sortedFields) {