aboutsummaryrefslogtreecommitdiff
path: root/csharp/ProtoGen/ServiceGenerator.cs
diff options
context:
space:
mode:
authorJon Skeet <skeet@pobox.com>2008-10-22 07:11:17 +0100
committerJon Skeet <skeet@pobox.com>2008-10-22 07:11:17 +0100
commite60ce8bfafca616ed4fd430ae4f82360de165e80 (patch)
treecb1a82655772f4995c02debb31cfeb208960acf1 /csharp/ProtoGen/ServiceGenerator.cs
parent7f90d8ee57d4af4215bc31dbb07726c023c5e047 (diff)
downloadprotobuf-e60ce8bfafca616ed4fd430ae4f82360de165e80.tar.gz
protobuf-e60ce8bfafca616ed4fd430ae4f82360de165e80.tar.bz2
protobuf-e60ce8bfafca616ed4fd430ae4f82360de165e80.zip
Final commit before changing layout
Diffstat (limited to 'csharp/ProtoGen/ServiceGenerator.cs')
-rw-r--r--csharp/ProtoGen/ServiceGenerator.cs138
1 files changed, 138 insertions, 0 deletions
diff --git a/csharp/ProtoGen/ServiceGenerator.cs b/csharp/ProtoGen/ServiceGenerator.cs
new file mode 100644
index 00000000..9b642b74
--- /dev/null
+++ b/csharp/ProtoGen/ServiceGenerator.cs
@@ -0,0 +1,138 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Google.ProtocolBuffers.Descriptors;
+
+namespace Google.ProtocolBuffers.ProtoGen {
+ internal class ServiceGenerator : SourceGeneratorBase<ServiceDescriptor>, ISourceGenerator {
+
+ private enum RequestOrResponse {
+ Request,
+ Response
+ }
+
+ internal ServiceGenerator(ServiceDescriptor descriptor)
+ : base(descriptor) {
+ }
+
+ public void Generate(TextGenerator 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, Helpers.UnderscoresToPascalCase(method.Name));
+ writer.WriteLine(" pb::IRpcController controller,");
+ writer.WriteLine(" {0} request,", DescriptorUtil.GetClassName(method.InputType));
+ writer.WriteLine(" global::System.Action<{0}> done);", DescriptorUtil.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.GetUmbrellaClassName(Descriptor.File), Descriptor.Index);
+ writer.WriteLine("}");
+ writer.WriteLine("{0} pbd::ServiceDescriptor DescriptorForType {{", ClassAccessLevel);
+ 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(", ClassAccessLevel);
+ 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, ({0}) request,",
+ Helpers.UnderscoresToPascalCase(method.Name), DescriptorUtil.GetClassName(method.InputType));
+ writer.WriteLine(" pb::RpcUtil.SpecializeCallback<{0}>(", DescriptorUtil.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;",
+ DescriptorUtil.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("{0} class Stub : {1} {{", ClassAccessLevel, DescriptorUtil.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("public override void {0}(", Helpers.UnderscoresToPascalCase(method.Name));
+ writer.WriteLine(" pb::IRpcController controller,");
+ writer.WriteLine(" {0} request,", DescriptorUtil.GetClassName(method.InputType));
+ writer.WriteLine(" global::System.Action<{0}> done) {{", DescriptorUtil.GetClassName(method.OutputType));
+ writer.Indent();
+ writer.WriteLine("channel.CallMethod(Descriptor.Methods[{0}],", method.Index);
+ writer.WriteLine(" controller, request, {0}.DefaultInstance,", DescriptorUtil.GetClassName(method.OutputType));
+ writer.WriteLine(" pb::RpcUtil.GeneralizeCallback<{0}, {0}.Builder>(done, {0}.DefaultInstance));",
+ DescriptorUtil.GetClassName(method.OutputType));
+ writer.Outdent();
+ writer.WriteLine("}");
+ }
+ writer.Outdent();
+ writer.WriteLine("}");
+ }
+ }
+}