diff options
author | csharptest <roger@csharptest.net> | 2011-08-13 18:25:26 -0500 |
---|---|---|
committer | rogerk <devnull@localhost> | 2011-08-13 18:25:26 -0500 |
commit | c58cb635038d055188b468d1ef2cfa9ca5ab5f39 (patch) | |
tree | 334196cbf982e5806539f93aea27112876335418 | |
parent | fad894b7c3d8f00ff8214b3305bf7a9178992ecf (diff) | |
parent | 1313cbdf0e6f9e08afd2546cf76c087e352de0fa (diff) | |
download | protobuf-c58cb635038d055188b468d1ef2cfa9ca5ab5f39.tar.gz protobuf-c58cb635038d055188b468d1ef2cfa9ca5ab5f39.tar.bz2 protobuf-c58cb635038d055188b468d1ef2cfa9ca5ab5f39.zip |
Merged branch for issue 16
-rw-r--r-- | src/ProtoGen/UmbrellaClassGenerator.cs | 587 |
1 files changed, 293 insertions, 294 deletions
diff --git a/src/ProtoGen/UmbrellaClassGenerator.cs b/src/ProtoGen/UmbrellaClassGenerator.cs index e3896a29..57a7844b 100644 --- a/src/ProtoGen/UmbrellaClassGenerator.cs +++ b/src/ProtoGen/UmbrellaClassGenerator.cs @@ -1,295 +1,294 @@ -// Protocol Buffers - Google's data interchange format
-// Copyright 2008 Google Inc. All rights reserved.
-// http://github.com/jskeet/dotnet-protobufs/
-// Original C++/Java/Python code:
-// http://code.google.com/p/protobuf/
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using Google.ProtocolBuffers.Descriptors;
-
-namespace Google.ProtocolBuffers.ProtoGen
-{
- /// <summary>
- /// Generator for the class describing the .proto file in general,
- /// containing things like the message descriptor.
- /// </summary>
- internal sealed class UmbrellaClassGenerator : SourceGeneratorBase<FileDescriptor>, ISourceGenerator
- {
- internal UmbrellaClassGenerator(FileDescriptor descriptor)
- : base(descriptor)
- {
- }
-
- // Recursively searches the given message to see if it contains any extensions.
- private static bool UsesExtensions(IMessage message)
- {
- // We conservatively assume that unknown fields are extensions.
- if (message.UnknownFields.FieldDictionary.Count > 0)
- {
- return true;
- }
-
- foreach (KeyValuePair<FieldDescriptor, object> keyValue in message.AllFields)
- {
- FieldDescriptor field = keyValue.Key;
- if (field.IsExtension)
- {
- return true;
- }
- if (field.MappedType == MappedType.Message)
- {
- if (field.IsRepeated)
- {
- foreach (IMessage subMessage in (IEnumerable) keyValue.Value)
- {
- if (UsesExtensions(subMessage))
- {
- return true;
- }
- }
- }
- else
- {
- if (UsesExtensions((IMessage) keyValue.Value))
- {
- return true;
- }
- }
- }
- }
- return false;
- }
-
- public void Generate(TextGenerator writer)
- {
- WriteIntroduction(writer);
- WriteExtensionRegistration(writer);
- WriteChildren(writer, "Extensions", Descriptor.Extensions);
- writer.WriteLine("#region Static variables");
- foreach (MessageDescriptor message in Descriptor.MessageTypes)
- {
- new MessageGenerator(message).GenerateStaticVariables(writer);
- }
- writer.WriteLine("#endregion");
- if (!UseLiteRuntime)
- {
- WriteDescriptor(writer);
- }
- else
- {
- WriteLiteExtensions(writer);
- }
- // The class declaration either gets closed before or after the children are written.
- if (!Descriptor.CSharpOptions.NestClasses)
- {
- writer.Outdent();
- writer.WriteLine("}");
-
- // Close the namespace around the umbrella class if defined
- if (!Descriptor.CSharpOptions.NestClasses && Descriptor.CSharpOptions.UmbrellaNamespace != "")
- {
- writer.Outdent();
- writer.WriteLine("}");
- }
- }
- WriteChildren(writer, "Enums", Descriptor.EnumTypes);
- WriteChildren(writer, "Messages", Descriptor.MessageTypes);
- WriteChildren(writer, "Services", Descriptor.Services);
- if (Descriptor.CSharpOptions.NestClasses)
- {
- writer.Outdent();
- writer.WriteLine("}");
- }
- if (Descriptor.CSharpOptions.Namespace != "")
- {
- writer.Outdent();
- writer.WriteLine("}");
- }
- writer.WriteLine();
- writer.WriteLine("#endregion Designer generated code");
- }
-
- private void WriteIntroduction(TextGenerator writer)
- {
- //writer.WriteLine("// <auto-generated />");
- writer.WriteLine("// Generated by {0}. DO NOT EDIT!", this.GetType().Assembly.FullName);
- writer.WriteLine("#pragma warning disable 1591");
- writer.WriteLine("#region Designer generated code");
-
- writer.WriteLine();
- writer.WriteLine("using pb = global::Google.ProtocolBuffers;");
- writer.WriteLine("using pbc = global::Google.ProtocolBuffers.Collections;");
- writer.WriteLine("using pbd = global::Google.ProtocolBuffers.Descriptors;");
- writer.WriteLine("using scg = global::System.Collections.Generic;");
-
- if (Descriptor.CSharpOptions.Namespace != "")
- {
- writer.WriteLine("namespace {0} {{", Descriptor.CSharpOptions.Namespace);
- writer.Indent();
- writer.WriteLine();
- }
- // Add the namespace around the umbrella class if defined
- if (!Descriptor.CSharpOptions.NestClasses && Descriptor.CSharpOptions.UmbrellaNamespace != "")
- {
- writer.WriteLine("namespace {0} {{", Descriptor.CSharpOptions.UmbrellaNamespace);
- writer.Indent();
- writer.WriteLine();
- }
-
- if (Descriptor.CSharpOptions.CodeContracts)
- {
- writer.WriteLine("[global::System.Diagnostics.Contracts.ContractVerificationAttribute(false)]");
- }
- writer.WriteLine("[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]");
- writer.WriteLine("[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]");
- writer.WriteLine("[global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"{0}\", \"{1}\")]",
- GetType().Assembly.GetName().Name, GetType().Assembly.GetName().Version);
- writer.WriteLine("{0} static partial class {1} {{", ClassAccessLevel,
- Descriptor.CSharpOptions.UmbrellaClassname);
- writer.WriteLine();
- writer.Indent();
- }
-
- private void WriteExtensionRegistration(TextGenerator writer)
- {
- writer.WriteLine("#region Extension registration");
- writer.WriteLine("public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {");
- writer.Indent();
- foreach (FieldDescriptor extension in Descriptor.Extensions)
- {
- new ExtensionGenerator(extension).GenerateExtensionRegistrationCode(writer);
- }
- foreach (MessageDescriptor message in Descriptor.MessageTypes)
- {
- new MessageGenerator(message).GenerateExtensionRegistrationCode(writer);
- }
- writer.Outdent();
- writer.WriteLine("}");
- writer.WriteLine("#endregion");
- }
-
- private void WriteDescriptor(TextGenerator writer)
- {
- writer.WriteLine("#region Descriptor");
-
- writer.WriteLine("public static pbd::FileDescriptor Descriptor {");
- writer.WriteLine(" get { return descriptor; }");
- writer.WriteLine("}");
- writer.WriteLine("private static pbd::FileDescriptor descriptor;");
- writer.WriteLine();
- writer.WriteLine("static {0}() {{", Descriptor.CSharpOptions.UmbrellaClassname);
- writer.Indent();
- writer.WriteLine("byte[] descriptorData = global::System.Convert.FromBase64String(");
- writer.Indent();
- writer.Indent();
-
- // TODO(jonskeet): Consider a C#-escaping format here instead of just Base64.
- byte[] bytes = Descriptor.Proto.ToByteArray();
- string base64 = Convert.ToBase64String(bytes);
-
- while (base64.Length > 60)
- {
- writer.WriteLine("\"{0}\" + ", base64.Substring(0, 60));
- base64 = base64.Substring(60);
- }
- writer.WriteLine("\"{0}\");", base64);
- writer.Outdent();
- writer.Outdent();
- writer.WriteLine(
- "pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {");
- writer.Indent();
- writer.WriteLine("descriptor = root;");
- foreach (MessageDescriptor message in Descriptor.MessageTypes)
- {
- new MessageGenerator(message).GenerateStaticVariableInitializers(writer);
- }
- foreach (FieldDescriptor extension in Descriptor.Extensions)
- {
- new ExtensionGenerator(extension).GenerateStaticVariableInitializers(writer);
- }
-
- if (UsesExtensions(Descriptor.Proto))
- {
- // Must construct an ExtensionRegistry containing all possible extensions
- // and return it.
- writer.WriteLine("pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();");
- writer.WriteLine("RegisterAllExtensions(registry);");
- foreach (FileDescriptor dependency in Descriptor.Dependencies)
- {
- writer.WriteLine("{0}.RegisterAllExtensions(registry);",
- DescriptorUtil.GetFullUmbrellaClassName(dependency));
- }
- writer.WriteLine("return registry;");
- }
- else
- {
- writer.WriteLine("return null;");
- }
- writer.Outdent();
- writer.WriteLine("};");
-
- // -----------------------------------------------------------------
- // Invoke internalBuildGeneratedFileFrom() to build the file.
- writer.WriteLine("pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,");
- writer.WriteLine(" new pbd::FileDescriptor[] {");
- foreach (FileDescriptor dependency in Descriptor.Dependencies)
- {
- writer.WriteLine(" {0}.Descriptor, ", DescriptorUtil.GetFullUmbrellaClassName(dependency));
- }
- writer.WriteLine(" }, assigner);");
- writer.Outdent();
- writer.WriteLine("}");
- writer.WriteLine("#endregion");
- writer.WriteLine();
- }
-
- private void WriteLiteExtensions(TextGenerator writer)
- {
- writer.WriteLine("#region Extensions");
- writer.WriteLine("internal static readonly object Descriptor;");
- writer.WriteLine("static {0}() {{", Descriptor.CSharpOptions.UmbrellaClassname);
- writer.Indent();
- writer.WriteLine("Descriptor = null;");
-
- foreach (MessageDescriptor message in Descriptor.MessageTypes)
- {
- new MessageGenerator(message).GenerateStaticVariableInitializers(writer);
- }
- foreach (FieldDescriptor extension in Descriptor.Extensions)
- {
- new ExtensionGenerator(extension).GenerateStaticVariableInitializers(writer);
- }
- writer.Outdent();
- writer.WriteLine("}");
- writer.WriteLine("#endregion");
- writer.WriteLine();
- }
- }
+// Protocol Buffers - Google's data interchange format +// Copyright 2008 Google Inc. All rights reserved. +// http://github.com/jskeet/dotnet-protobufs/ +// Original C++/Java/Python code: +// http://code.google.com/p/protobuf/ +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following disclaimer +// in the documentation and/or other materials provided with the +// distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived from +// this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +using System; +using System.Collections; +using System.Collections.Generic; +using Google.ProtocolBuffers.Descriptors; + +namespace Google.ProtocolBuffers.ProtoGen +{ + /// <summary> + /// Generator for the class describing the .proto file in general, + /// containing things like the message descriptor. + /// </summary> + internal sealed class UmbrellaClassGenerator : SourceGeneratorBase<FileDescriptor>, ISourceGenerator + { + internal UmbrellaClassGenerator(FileDescriptor descriptor) + : base(descriptor) + { + } + + // Recursively searches the given message to see if it contains any extensions. + private static bool UsesExtensions(IMessage message) + { + // We conservatively assume that unknown fields are extensions. + if (message.UnknownFields.FieldDictionary.Count > 0) + { + return true; + } + + foreach (KeyValuePair<FieldDescriptor, object> keyValue in message.AllFields) + { + FieldDescriptor field = keyValue.Key; + if (field.IsExtension) + { + return true; + } + if (field.MappedType == MappedType.Message) + { + if (field.IsRepeated) + { + foreach (IMessage subMessage in (IEnumerable) keyValue.Value) + { + if (UsesExtensions(subMessage)) + { + return true; + } + } + } + else + { + if (UsesExtensions((IMessage) keyValue.Value)) + { + return true; + } + } + } + } + return false; + } + + public void Generate(TextGenerator writer) + { + WriteIntroduction(writer); + WriteExtensionRegistration(writer); + WriteChildren(writer, "Extensions", Descriptor.Extensions); + writer.WriteLine("#region Static variables"); + foreach (MessageDescriptor message in Descriptor.MessageTypes) + { + new MessageGenerator(message).GenerateStaticVariables(writer); + } + writer.WriteLine("#endregion"); + if (!UseLiteRuntime) + { + WriteDescriptor(writer); + } + else + { + WriteLiteExtensions(writer); + } + // The class declaration either gets closed before or after the children are written. + if (!Descriptor.CSharpOptions.NestClasses) + { + writer.Outdent(); + writer.WriteLine("}"); + + // Close the namespace around the umbrella class if defined + if (!Descriptor.CSharpOptions.NestClasses && Descriptor.CSharpOptions.UmbrellaNamespace != "") + { + writer.Outdent(); + writer.WriteLine("}"); + } + } + WriteChildren(writer, "Enums", Descriptor.EnumTypes); + WriteChildren(writer, "Messages", Descriptor.MessageTypes); + WriteChildren(writer, "Services", Descriptor.Services); + if (Descriptor.CSharpOptions.NestClasses) + { + writer.Outdent(); + writer.WriteLine("}"); + } + if (Descriptor.CSharpOptions.Namespace != "") + { + writer.Outdent(); + writer.WriteLine("}"); + } + writer.WriteLine(); + writer.WriteLine("#endregion Designer generated code"); + } + + private void WriteIntroduction(TextGenerator writer) + { + writer.WriteLine("// Generated by {0}. DO NOT EDIT!", this.GetType().Assembly.FullName); + writer.WriteLine("#pragma warning disable 1591"); + writer.WriteLine("#region Designer generated code"); + + writer.WriteLine(); + writer.WriteLine("using pb = global::Google.ProtocolBuffers;"); + writer.WriteLine("using pbc = global::Google.ProtocolBuffers.Collections;"); + writer.WriteLine("using pbd = global::Google.ProtocolBuffers.Descriptors;"); + writer.WriteLine("using scg = global::System.Collections.Generic;"); + + if (Descriptor.CSharpOptions.Namespace != "") + { + writer.WriteLine("namespace {0} {{", Descriptor.CSharpOptions.Namespace); + writer.Indent(); + writer.WriteLine(); + } + // Add the namespace around the umbrella class if defined + if (!Descriptor.CSharpOptions.NestClasses && Descriptor.CSharpOptions.UmbrellaNamespace != "") + { + writer.WriteLine("namespace {0} {{", Descriptor.CSharpOptions.UmbrellaNamespace); + writer.Indent(); + writer.WriteLine(); + } + + if (Descriptor.CSharpOptions.CodeContracts) + { + writer.WriteLine("[global::System.Diagnostics.Contracts.ContractVerificationAttribute(false)]"); + } + writer.WriteLine("[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]"); + writer.WriteLine("[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]"); + writer.WriteLine("[global::System.CodeDom.Compiler.GeneratedCodeAttribute(\"{0}\", \"{1}\")]", + GetType().Assembly.GetName().Name, GetType().Assembly.GetName().Version); + writer.WriteLine("{0} static partial class {1} {{", ClassAccessLevel, + Descriptor.CSharpOptions.UmbrellaClassname); + writer.WriteLine(); + writer.Indent(); + } + + private void WriteExtensionRegistration(TextGenerator writer) + { + writer.WriteLine("#region Extension registration"); + writer.WriteLine("public static void RegisterAllExtensions(pb::ExtensionRegistry registry) {"); + writer.Indent(); + foreach (FieldDescriptor extension in Descriptor.Extensions) + { + new ExtensionGenerator(extension).GenerateExtensionRegistrationCode(writer); + } + foreach (MessageDescriptor message in Descriptor.MessageTypes) + { + new MessageGenerator(message).GenerateExtensionRegistrationCode(writer); + } + writer.Outdent(); + writer.WriteLine("}"); + writer.WriteLine("#endregion"); + } + + private void WriteDescriptor(TextGenerator writer) + { + writer.WriteLine("#region Descriptor"); + + writer.WriteLine("public static pbd::FileDescriptor Descriptor {"); + writer.WriteLine(" get { return descriptor; }"); + writer.WriteLine("}"); + writer.WriteLine("private static pbd::FileDescriptor descriptor;"); + writer.WriteLine(); + writer.WriteLine("static {0}() {{", Descriptor.CSharpOptions.UmbrellaClassname); + writer.Indent(); + writer.WriteLine("byte[] descriptorData = global::System.Convert.FromBase64String("); + writer.Indent(); + writer.Indent(); + + // TODO(jonskeet): Consider a C#-escaping format here instead of just Base64. + byte[] bytes = Descriptor.Proto.ToByteArray(); + string base64 = Convert.ToBase64String(bytes); + + while (base64.Length > 60) + { + writer.WriteLine("\"{0}\" + ", base64.Substring(0, 60)); + base64 = base64.Substring(60); + } + writer.WriteLine("\"{0}\");", base64); + writer.Outdent(); + writer.Outdent(); + writer.WriteLine( + "pbd::FileDescriptor.InternalDescriptorAssigner assigner = delegate(pbd::FileDescriptor root) {"); + writer.Indent(); + writer.WriteLine("descriptor = root;"); + foreach (MessageDescriptor message in Descriptor.MessageTypes) + { + new MessageGenerator(message).GenerateStaticVariableInitializers(writer); + } + foreach (FieldDescriptor extension in Descriptor.Extensions) + { + new ExtensionGenerator(extension).GenerateStaticVariableInitializers(writer); + } + + if (UsesExtensions(Descriptor.Proto)) + { + // Must construct an ExtensionRegistry containing all possible extensions + // and return it. + writer.WriteLine("pb::ExtensionRegistry registry = pb::ExtensionRegistry.CreateInstance();"); + writer.WriteLine("RegisterAllExtensions(registry);"); + foreach (FileDescriptor dependency in Descriptor.Dependencies) + { + writer.WriteLine("{0}.RegisterAllExtensions(registry);", + DescriptorUtil.GetFullUmbrellaClassName(dependency)); + } + writer.WriteLine("return registry;"); + } + else + { + writer.WriteLine("return null;"); + } + writer.Outdent(); + writer.WriteLine("};"); + + // ----------------------------------------------------------------- + // Invoke internalBuildGeneratedFileFrom() to build the file. + writer.WriteLine("pbd::FileDescriptor.InternalBuildGeneratedFileFrom(descriptorData,"); + writer.WriteLine(" new pbd::FileDescriptor[] {"); + foreach (FileDescriptor dependency in Descriptor.Dependencies) + { + writer.WriteLine(" {0}.Descriptor, ", DescriptorUtil.GetFullUmbrellaClassName(dependency)); + } + writer.WriteLine(" }, assigner);"); + writer.Outdent(); + writer.WriteLine("}"); + writer.WriteLine("#endregion"); + writer.WriteLine(); + } + + private void WriteLiteExtensions(TextGenerator writer) + { + writer.WriteLine("#region Extensions"); + writer.WriteLine("internal static readonly object Descriptor;"); + writer.WriteLine("static {0}() {{", Descriptor.CSharpOptions.UmbrellaClassname); + writer.Indent(); + writer.WriteLine("Descriptor = null;"); + + foreach (MessageDescriptor message in Descriptor.MessageTypes) + { + new MessageGenerator(message).GenerateStaticVariableInitializers(writer); + } + foreach (FieldDescriptor extension in Descriptor.Extensions) + { + new ExtensionGenerator(extension).GenerateStaticVariableInitializers(writer); + } + writer.Outdent(); + writer.WriteLine("}"); + writer.WriteLine("#endregion"); + writer.WriteLine(); + } + } }
\ No newline at end of file |