Free cookie consent management tool by TermsFeed Policy Generator

source: tags/3.3.4/HeuristicLab.ExtLibs/HeuristicLab.ProtobufCS/0.9.1/ProtobufCS/src/ProtoGen/ServiceGenerator.cs @ 6120

Last change on this file since 6120 was 3857, checked in by abeham, 14 years ago

#866

  • Added protobuf-csharp-port project source to ExtLibs
File size: 7.9 KB
Line 
1#region Copyright notice and license
2// Protocol Buffers - Google's data interchange format
3// Copyright 2008 Google Inc.  All rights reserved.
4// http://github.com/jskeet/dotnet-protobufs/
5// Original C++/Java/Python code:
6// http://code.google.com/p/protobuf/
7//
8// Redistribution and use in source and binary forms, with or without
9// modification, are permitted provided that the following conditions are
10// met:
11//
12//     * Redistributions of source code must retain the above copyright
13// notice, this list of conditions and the following disclaimer.
14//     * Redistributions in binary form must reproduce the above
15// copyright notice, this list of conditions and the following disclaimer
16// in the documentation and/or other materials provided with the
17// distribution.
18//     * Neither the name of Google Inc. nor the names of its
19// contributors may be used to endorse or promote products derived from
20// this software without specific prior written permission.
21//
22// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33#endregion
34
35using Google.ProtocolBuffers.Descriptors;
36
37namespace Google.ProtocolBuffers.ProtoGen {
38  internal class ServiceGenerator : SourceGeneratorBase<ServiceDescriptor>, ISourceGenerator {
39
40    private enum RequestOrResponse {
41      Request,
42      Response
43    }
44
45    internal ServiceGenerator(ServiceDescriptor descriptor)
46      : base(descriptor) {
47    }
48
49    public void Generate(TextGenerator writer) {
50      writer.WriteLine("{0} abstract class {1} : pb::IService {{", ClassAccessLevel, Descriptor.Name);
51      writer.Indent();
52
53      foreach (MethodDescriptor method in Descriptor.Methods) {
54        writer.WriteLine("{0} abstract void {1}(", ClassAccessLevel, NameHelpers.UnderscoresToPascalCase(method.Name));
55        writer.WriteLine("    pb::IRpcController controller,");
56        writer.WriteLine("    {0} request,", GetClassName(method.InputType));
57        writer.WriteLine("    global::System.Action<{0}> done);", GetClassName(method.OutputType));
58      }
59
60      // Generate Descriptor and DescriptorForType.
61      writer.WriteLine();
62      writer.WriteLine("{0} static pbd::ServiceDescriptor Descriptor {{", ClassAccessLevel);
63      writer.WriteLine("  get {{ return {0}.Descriptor.Services[{1}]; }}",
64        Descriptor.File.CSharpOptions.UmbrellaClassname, Descriptor.Index);
65      writer.WriteLine("}");
66      writer.WriteLine("{0} pbd::ServiceDescriptor DescriptorForType {{", ClassAccessLevel);
67      writer.WriteLine("  get { return Descriptor; }");
68      writer.WriteLine("}");
69
70      GenerateCallMethod(writer);
71      GenerateGetPrototype(RequestOrResponse.Request, writer);
72      GenerateGetPrototype(RequestOrResponse.Response, writer);
73      GenerateStub(writer);
74
75      writer.Outdent();
76      writer.WriteLine("}");
77    }
78
79    private void GenerateCallMethod(TextGenerator writer) {
80      writer.WriteLine();
81      writer.WriteLine("public void CallMethod(", ClassAccessLevel);
82      writer.WriteLine("    pbd::MethodDescriptor method,");
83      writer.WriteLine("    pb::IRpcController controller,");
84      writer.WriteLine("    pb::IMessage request,");
85      writer.WriteLine("    global::System.Action<pb::IMessage> done) {");
86      writer.Indent();
87      writer.WriteLine("if (method.Service != Descriptor) {");
88      writer.WriteLine("  throw new global::System.ArgumentException(");
89      writer.WriteLine("      \"Service.CallMethod() given method descriptor for wrong service type.\");");
90      writer.WriteLine("}");
91      writer.WriteLine("switch(method.Index) {");
92      writer.Indent();
93      foreach (MethodDescriptor method in Descriptor.Methods) {
94        writer.WriteLine("case {0}:", method.Index);
95        writer.WriteLine("  this.{0}(controller, ({1}) request,",
96            NameHelpers.UnderscoresToPascalCase(method.Name), GetClassName(method.InputType));
97        writer.WriteLine("      pb::RpcUtil.SpecializeCallback<{0}>(", GetClassName(method.OutputType));
98        writer.WriteLine("      done));");
99        writer.WriteLine("  return;");
100      }
101      writer.WriteLine("default:");
102      writer.WriteLine("  throw new global::System.InvalidOperationException(\"Can't get here.\");");
103      writer.Outdent();
104      writer.WriteLine("}");
105      writer.Outdent();
106      writer.WriteLine("}");
107      writer.WriteLine();
108    }
109
110    private void GenerateGetPrototype(RequestOrResponse which, TextGenerator writer) {
111      writer.WriteLine("public pb::IMessage Get{0}Prototype(pbd::MethodDescriptor method) {{", which);
112      writer.Indent();
113      writer.WriteLine("if (method.Service != Descriptor) {");
114      writer.WriteLine("  throw new global::System.ArgumentException(");
115      writer.WriteLine("      \"Service.Get{0}Prototype() given method descriptor for wrong service type.\");", which);
116      writer.WriteLine("}");
117      writer.WriteLine("switch(method.Index) {");
118      writer.Indent();
119
120      foreach (MethodDescriptor method in Descriptor.Methods) {
121        writer.WriteLine("case {0}:", method.Index);
122        writer.WriteLine("  return {0}.DefaultInstance;",
123          GetClassName(which == RequestOrResponse.Request ? method.InputType : method.OutputType));
124      }
125      writer.WriteLine("default:");
126      writer.WriteLine("  throw new global::System.InvalidOperationException(\"Can't get here.\");");
127      writer.Outdent();
128      writer.WriteLine("}");
129      writer.Outdent();
130      writer.WriteLine("}");
131      writer.WriteLine();
132    }
133
134    private void GenerateStub(TextGenerator writer) {
135      writer.WriteLine("public static Stub CreateStub(pb::IRpcChannel channel) {");
136      writer.WriteLine("  return new Stub(channel);");
137      writer.WriteLine("}");
138      writer.WriteLine();
139      writer.WriteLine("{0} class Stub : {1} {{", ClassAccessLevel, GetClassName(Descriptor));
140      writer.Indent();
141      writer.WriteLine("internal Stub(pb::IRpcChannel channel) {");
142      writer.WriteLine("  this.channel = channel;");
143      writer.WriteLine("}");
144      writer.WriteLine();
145      writer.WriteLine("private readonly pb::IRpcChannel channel;");
146      writer.WriteLine();
147      writer.WriteLine("public pb::IRpcChannel Channel {");
148      writer.WriteLine("  get { return channel; }");
149      writer.WriteLine("}");
150
151      foreach (MethodDescriptor method in Descriptor.Methods) {
152        writer.WriteLine();
153        writer.WriteLine("public override void {0}(", NameHelpers.UnderscoresToPascalCase(method.Name));
154        writer.WriteLine("    pb::IRpcController controller,");
155        writer.WriteLine("    {0} request,", GetClassName(method.InputType));
156        writer.WriteLine("    global::System.Action<{0}> done) {{", GetClassName(method.OutputType));
157        writer.Indent();
158        writer.WriteLine("channel.CallMethod(Descriptor.Methods[{0}],", method.Index);
159        writer.WriteLine("    controller, request, {0}.DefaultInstance,", GetClassName(method.OutputType));
160        writer.WriteLine("    pb::RpcUtil.GeneralizeCallback<{0}, {0}.Builder>(done, {0}.DefaultInstance));",
161            GetClassName(method.OutputType));
162        writer.Outdent();
163        writer.WriteLine("}");
164      }
165      writer.Outdent();
166      writer.WriteLine("}");
167    }
168  }
169}
Note: See TracBrowser for help on using the repository browser.