diff options
author | Jan Tattermusch <jtattermusch@google.com> | 2015-04-16 09:55:22 -0700 |
---|---|---|
committer | Jan Tattermusch <jtattermusch@google.com> | 2015-04-16 09:55:22 -0700 |
commit | 84fa3e2bbc876428efd0c99700f146115a9d5162 (patch) | |
tree | 47baa5dafe3c3ab1c49fe2ca44e9f3ffd0e0b127 /csharp/src/ProtoGen/ServiceGenerator.cs | |
parent | 813d6d652d8091e9365bfbd01efb5f2ee8bdfbce (diff) | |
parent | 836a273544f55c88d8d0988ef0117cb0636707c6 (diff) | |
download | protobuf-84fa3e2bbc876428efd0c99700f146115a9d5162.tar.gz protobuf-84fa3e2bbc876428efd0c99700f146115a9d5162.tar.bz2 protobuf-84fa3e2bbc876428efd0c99700f146115a9d5162.zip |
Imported protobuf-csharp-port into csharp/ tree
Diffstat (limited to 'csharp/src/ProtoGen/ServiceGenerator.cs')
-rw-r--r-- | csharp/src/ProtoGen/ServiceGenerator.cs | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/csharp/src/ProtoGen/ServiceGenerator.cs b/csharp/src/ProtoGen/ServiceGenerator.cs new file mode 100644 index 00000000..a6b9eb28 --- /dev/null +++ b/csharp/src/ProtoGen/ServiceGenerator.cs @@ -0,0 +1,190 @@ +#region Copyright notice and license
+
+// 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.
+
+#endregion
+
+using Google.ProtocolBuffers.Descriptors;
+
+namespace Google.ProtocolBuffers.ProtoGen
+{
+ internal class GenericServiceGenerator : SourceGeneratorBase<ServiceDescriptor>, ISourceGenerator
+ {
+ private enum RequestOrResponse
+ {
+ Request,
+ Response
+ }
+
+ internal GenericServiceGenerator(ServiceDescriptor descriptor)
+ : base(descriptor)
+ {
+ }
+
+ public void Generate(TextGenerator writer)
+ {
+ writer.WriteLine("[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]");
+ WriteGeneratedCodeAttributes(writer);
+ writer.WriteLine("{0} abstract class {1} : pb::IService {{", ClassAccessLevel, Descriptor.Name);
+ writer.Indent();
+
+ foreach (MethodDescriptor method in Descriptor.Methods)
+ {
+ writer.WriteLine("{0} abstract void {1}(", ClassAccessLevel,
+ NameHelpers.UnderscoresToPascalCase(method.Name));
+ writer.WriteLine(" pb::IRpcController controller,");
+ writer.WriteLine(" {0} request,", GetClassName(method.InputType));
+ writer.WriteLine(" global::System.Action<{0}> done);", GetClassName(method.OutputType));
+ }
+
+ // Generate Descriptor and DescriptorForType.
+ writer.WriteLine();
+ writer.WriteLine("{0} static pbd::ServiceDescriptor Descriptor {{", ClassAccessLevel);
+ writer.WriteLine(" get {{ return {0}.Descriptor.Services[{1}]; }}",
+ DescriptorUtil.GetQualifiedUmbrellaClassName(Descriptor.File.CSharpOptions),
+ Descriptor.Index);
+ writer.WriteLine("}");
+ writer.WriteLine("public pbd::ServiceDescriptor DescriptorForType {");
+ writer.WriteLine(" get { return Descriptor; }");
+ writer.WriteLine("}");
+
+ GenerateCallMethod(writer);
+ GenerateGetPrototype(RequestOrResponse.Request, writer);
+ GenerateGetPrototype(RequestOrResponse.Response, writer);
+ GenerateStub(writer);
+
+ writer.Outdent();
+ writer.WriteLine("}");
+ }
+
+ private void GenerateCallMethod(TextGenerator writer)
+ {
+ writer.WriteLine();
+ writer.WriteLine("public void CallMethod(");
+ writer.WriteLine(" pbd::MethodDescriptor method,");
+ writer.WriteLine(" pb::IRpcController controller,");
+ writer.WriteLine(" pb::IMessage request,");
+ writer.WriteLine(" global::System.Action<pb::IMessage> done) {");
+ writer.Indent();
+ writer.WriteLine("if (method.Service != Descriptor) {");
+ writer.WriteLine(" throw new global::System.ArgumentException(");
+ writer.WriteLine(" \"Service.CallMethod() given method descriptor for wrong service type.\");");
+ writer.WriteLine("}");
+ writer.WriteLine("switch(method.Index) {");
+ writer.Indent();
+ foreach (MethodDescriptor method in Descriptor.Methods)
+ {
+ writer.WriteLine("case {0}:", method.Index);
+ writer.WriteLine(" this.{0}(controller, ({1}) request,",
+ NameHelpers.UnderscoresToPascalCase(method.Name), GetClassName(method.InputType));
+ writer.WriteLine(" pb::RpcUtil.SpecializeCallback<{0}>(", GetClassName(method.OutputType));
+ writer.WriteLine(" done));");
+ writer.WriteLine(" return;");
+ }
+ writer.WriteLine("default:");
+ writer.WriteLine(" throw new global::System.InvalidOperationException(\"Can't get here.\");");
+ writer.Outdent();
+ writer.WriteLine("}");
+ writer.Outdent();
+ writer.WriteLine("}");
+ writer.WriteLine();
+ }
+
+ private void GenerateGetPrototype(RequestOrResponse which, TextGenerator writer)
+ {
+ writer.WriteLine("public pb::IMessage Get{0}Prototype(pbd::MethodDescriptor method) {{", which);
+ writer.Indent();
+ writer.WriteLine("if (method.Service != Descriptor) {");
+ writer.WriteLine(" throw new global::System.ArgumentException(");
+ writer.WriteLine(" \"Service.Get{0}Prototype() given method descriptor for wrong service type.\");",
+ which);
+ writer.WriteLine("}");
+ writer.WriteLine("switch(method.Index) {");
+ writer.Indent();
+
+ foreach (MethodDescriptor method in Descriptor.Methods)
+ {
+ writer.WriteLine("case {0}:", method.Index);
+ writer.WriteLine(" return {0}.DefaultInstance;",
+ GetClassName(which == RequestOrResponse.Request ? method.InputType : method.OutputType));
+ }
+ writer.WriteLine("default:");
+ writer.WriteLine(" throw new global::System.InvalidOperationException(\"Can't get here.\");");
+ writer.Outdent();
+ writer.WriteLine("}");
+ writer.Outdent();
+ writer.WriteLine("}");
+ writer.WriteLine();
+ }
+
+ private void GenerateStub(TextGenerator writer)
+ {
+ writer.WriteLine("public static Stub CreateStub(pb::IRpcChannel channel) {");
+ writer.WriteLine(" return new Stub(channel);");
+ writer.WriteLine("}");
+ writer.WriteLine();
+ writer.WriteLine("[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]");
+ WriteGeneratedCodeAttributes(writer);
+ writer.WriteLine("{0} class Stub : {1} {{", ClassAccessLevel, GetClassName(Descriptor));
+ writer.Indent();
+ writer.WriteLine("internal Stub(pb::IRpcChannel channel) {");
+ writer.WriteLine(" this.channel = channel;");
+ writer.WriteLine("}");
+ writer.WriteLine();
+ writer.WriteLine("private readonly pb::IRpcChannel channel;");
+ writer.WriteLine();
+ writer.WriteLine("public pb::IRpcChannel Channel {");
+ writer.WriteLine(" get { return channel; }");
+ writer.WriteLine("}");
+
+ foreach (MethodDescriptor method in Descriptor.Methods)
+ {
+ writer.WriteLine();
+ writer.WriteLine("{0} override void {1}(", ClassAccessLevel,
+ NameHelpers.UnderscoresToPascalCase(method.Name));
+ writer.WriteLine(" pb::IRpcController controller,");
+ writer.WriteLine(" {0} request,", GetClassName(method.InputType));
+ writer.WriteLine(" global::System.Action<{0}> done) {{", GetClassName(method.OutputType));
+ writer.Indent();
+ writer.WriteLine("channel.CallMethod(Descriptor.Methods[{0}],", method.Index);
+ writer.WriteLine(" controller, request, {0}.DefaultInstance,", GetClassName(method.OutputType));
+ writer.WriteLine(" pb::RpcUtil.GeneralizeCallback<{0}, {0}.Builder>(done, {0}.DefaultInstance));",
+ GetClassName(method.OutputType));
+ writer.Outdent();
+ writer.WriteLine("}");
+ }
+ writer.Outdent();
+ writer.WriteLine("}");
+ }
+ }
+}
\ No newline at end of file |