Browse Source

Fully-templatized code generation for clients and servers.

Tim Burks 9 years ago
parent
commit
97efdbad11

+ 1 - 8
Examples/Echo/Swift/Echo/echo.server.pb.swift

@@ -52,7 +52,6 @@ public protocol Echo_EchoProvider {
   func collect(session : Echo_EchoCollectSession) throws
   func update(session : Echo_EchoUpdateSession) throws
 }
-
 // unary
 public class Echo_EchoGetSession {
   var handler : gRPC.Handler
@@ -81,7 +80,6 @@ public class Echo_EchoGetSession {
     }
   }
 }
-
 // server streaming
 public class Echo_EchoExpandSession {
   var handler : gRPC.Handler
@@ -117,7 +115,6 @@ public class Echo_EchoExpandSession {
     }
   }
 }
-
 // client streaming
 public class Echo_EchoCollectSession {
   var handler : gRPC.Handler
@@ -157,7 +154,6 @@ public class Echo_EchoCollectSession {
 
   fileprivate func run(queue:DispatchQueue) {
     do {
-      print("EchoCollectSession run")
       try self.handler.sendMetadata(initialMetadata:Metadata()) {
         queue.async {
           try! self.provider.collect(session:self)
@@ -168,7 +164,6 @@ public class Echo_EchoCollectSession {
     }
   }
 }
-
 // fully streaming
 public class Echo_EchoUpdateSession {
   var handler : gRPC.Handler
@@ -229,7 +224,6 @@ public class Echo_EchoUpdateSession {
     }
   }
 }
-
 //
 // main server for generated service
 //
@@ -285,5 +279,4 @@ public class Echo_EchoServer {
       }
     }
   }
-}
-
+}

+ 93 - 119
Plugin/Sources/main.swift

@@ -29,6 +29,78 @@ func protoMessageName(_ name :String?) -> String {
   }
 }
 
+func pathName(_ arguments: [Any?]) throws -> String {
+  if arguments.count != 3 {
+    throw TemplateSyntaxError("path expects 3 arguments")
+  }
+  guard let protoFile = arguments[0] as? Google_Protobuf_FileDescriptorProto
+    else {
+      throw TemplateSyntaxError("tag must be called with a " +
+        "Google_Protobuf_FileDescriptorProto" +
+        " argument, received \(arguments[0])")
+  }
+  guard let service = arguments[1] as? Google_Protobuf_ServiceDescriptorProto
+    else {
+      throw TemplateSyntaxError("tag must be called with a " +
+        "Google_Protobuf_ServiceDescriptorProto" +
+        " argument, received \(arguments[1])")
+  }
+  guard let method = arguments[2] as? Google_Protobuf_MethodDescriptorProto
+    else {
+      throw TemplateSyntaxError("tag must be called with a " +
+        "Google_Protobuf_MethodDescriptorProto" +
+        " argument, received \(arguments[2])")
+  }
+  return "/" + protoFile.package! + "." + service.name! + "/" + method.name!
+}
+
+func packageServiceMethodName(_ arguments: [Any?]) throws -> String {
+  if arguments.count != 3 {
+    throw TemplateSyntaxError("tag expects 3 arguments")
+  }
+  guard let protoFile = arguments[0] as? Google_Protobuf_FileDescriptorProto
+    else {
+      throw TemplateSyntaxError("tag must be called with a " +
+        "Google_Protobuf_FileDescriptorProto" +
+        " argument, received \(arguments[0])")
+  }
+  guard let service = arguments[1] as? Google_Protobuf_ServiceDescriptorProto
+    else {
+      throw TemplateSyntaxError("tag must be called with a " +
+        "Google_Protobuf_ServiceDescriptorProto" +
+        " argument, received \(arguments[1])")
+  }
+  guard let method = arguments[2] as? Google_Protobuf_MethodDescriptorProto
+    else {
+      throw TemplateSyntaxError("tag must be called with a " +
+        "Google_Protobuf_MethodDescriptorProto" +
+        " argument, received \(arguments[2])")
+  }
+  return protoFile.package!.capitalized + "_" + service.name! + method.name!
+}
+
+func packageServiceName(_ arguments: [Any?]) throws -> String {
+  if arguments.count != 2 {
+    throw TemplateSyntaxError("tag expects 2 arguments")
+  }
+  guard let protoFile = arguments[0] as? Google_Protobuf_FileDescriptorProto
+    else {
+      throw TemplateSyntaxError("tag must be called with a " +
+        "Google_Protobuf_FileDescriptorProto" +
+        " argument, received \(arguments[0])")
+  }
+  guard let service = arguments[1] as? Google_Protobuf_ServiceDescriptorProto
+    else {
+      throw TemplateSyntaxError("tag must be called with a " +
+        "Google_Protobuf_ServiceDescriptorProto" +
+        " argument, received \(arguments[1])")
+  }
+  return protoFile.package!.capitalized + "_" + service.name!
+}
+
+// Code templates use "//-" prefixes to comment-out template operators
+// to keep them from interfering with Swift code formatting tools.
+// Use this to remove them after templates have been expanded.
 func stripMarkers(_ code:String) -> String {
   let inputLines = code.components(separatedBy:"\n")
 
@@ -48,138 +120,42 @@ func stripMarkers(_ code:String) -> String {
 
 func main() throws {
 
-  // initialize template engine
+  // initialize template engine and add custom filters
   let fileSystemLoader = FileSystemLoader(paths: ["templates/"])
   let ext = Extension()
-
-  ext.registerFilter("callname") { (value: Any?, arguments: [Any?]) in
-    if arguments.count != 3 {
-      throw TemplateSyntaxError("expects 3 arguments")
-    }
-    guard let protoFile = arguments[0] as? Google_Protobuf_FileDescriptorProto
-      else {
-        throw TemplateSyntaxError("tag must be called with a " +
-          "Google_Protobuf_FileDescriptorProto" +
-          " argument, received \(arguments[0])")
-    }
-    guard let service = arguments[1] as? Google_Protobuf_ServiceDescriptorProto
-      else {
-        throw TemplateSyntaxError("tag must be called with a " +
-          "Google_Protobuf_ServiceDescriptorProto" +
-          " argument, received \(arguments[1])")
-    }
-    guard let method = arguments[2] as? Google_Protobuf_MethodDescriptorProto
-      else {
-        throw TemplateSyntaxError("tag must be called with a " +
-          "Google_Protobuf_MethodDescriptorProto" +
-          " argument, received \(arguments[2])")
-    }
-    return protoFile.package!.capitalized + "_" + service.name! + method.name! + "Call"
+  ext.registerFilter("call") { (value: Any?, arguments: [Any?]) in
+    return try packageServiceMethodName(arguments) + "Call"
   }
-
-  ext.registerFilter("callpath") { (value: Any?, arguments: [Any?]) in
-    if arguments.count != 3 {
-      throw TemplateSyntaxError("expects 3 arguments")
-    }
-    guard let protoFile = arguments[0] as? Google_Protobuf_FileDescriptorProto
-      else {
-        throw TemplateSyntaxError("tag must be called with a " +
-          "Google_Protobuf_FileDescriptorProto" +
-          " argument, received \(arguments[0])")
-    }
-    guard let service = arguments[1] as? Google_Protobuf_ServiceDescriptorProto
-      else {
-        throw TemplateSyntaxError("tag must be called with a " +
-          "Google_Protobuf_ServiceDescriptorProto" +
-          " argument, received \(arguments[1])")
-    }
-    guard let method = arguments[2] as? Google_Protobuf_MethodDescriptorProto
-      else {
-        throw TemplateSyntaxError("tag must be called with a " +
-          "Google_Protobuf_MethodDescriptorProto" +
-          " argument, received \(arguments[2])")
-    }
-    return "/" + protoFile.package! + "." + service.name! + "/" + method.name!
+  ext.registerFilter("session") { (value: Any?, arguments: [Any?]) in
+    return try packageServiceMethodName(arguments) + "Session"
   }
-
-  ext.registerFilter("sessionname") { (value: Any?, arguments: [Any?]) in
-    if arguments.count != 3 {
-      throw TemplateSyntaxError("expects 3 arguments")
-    }
-    guard let protoFile = arguments[0] as? Google_Protobuf_FileDescriptorProto
-      else {
-        throw TemplateSyntaxError("tag must be called with a " +
-          "Google_Protobuf_FileDescriptorProto" +
-          " argument, received \(arguments[0])")
-    }
-    guard let service = arguments[1] as? Google_Protobuf_ServiceDescriptorProto
-      else {
-        throw TemplateSyntaxError("tag must be called with a " +
-          "Google_Protobuf_ServiceDescriptorProto" +
-          " argument, received \(arguments[1])")
-    }
-    guard let method = arguments[2] as? Google_Protobuf_MethodDescriptorProto
-      else {
-        throw TemplateSyntaxError("tag must be called with a " +
-          "Google_Protobuf_MethodDescriptorProto" +
-          " argument, received \(arguments[2])")
-    }
-    return protoFile.package!.capitalized + "_" + service.name! + method.name! + "Session"
+  ext.registerFilter("path") { (value: Any?, arguments: [Any?]) in
+    return try pathName(arguments)
   }
-
-  ext.registerFilter("errorname") { (value: Any?, arguments: [Any?]) in
-    if arguments.count != 2 {
-      throw TemplateSyntaxError("expects 2 arguments")
-    }
-    guard let protoFile = arguments[0] as? Google_Protobuf_FileDescriptorProto
-      else {
-        throw TemplateSyntaxError("tag must be called with a " +
-          "Google_Protobuf_FileDescriptorProto" +
-          " argument, received \(arguments[0])")
-    }
-    guard let service = arguments[1] as? Google_Protobuf_ServiceDescriptorProto
-      else {
-        throw TemplateSyntaxError("tag must be called with a " +
-          "Google_Protobuf_ServiceDescriptorProto" +
-          " argument, received \(arguments[1])")
-    }
-    return protoFile.package!.capitalized + "_" + service.name! + "ClientError"
+  ext.registerFilter("provider") { (value: Any?, arguments: [Any?]) in
+    return try packageServiceName(arguments) + "Provider"
   }
-
-  ext.registerFilter("inputType") { (value: Any?) in
+  ext.registerFilter("clienterror") { (value: Any?, arguments: [Any?]) in
+    return try packageServiceName(arguments) + "ClientError"
+  }
+  ext.registerFilter("servererror") { (value: Any?, arguments: [Any?]) in
+    return try packageServiceName(arguments) + "ServerError"
+  }
+  ext.registerFilter("server") { (value: Any?, arguments: [Any?]) in
+    return try packageServiceName(arguments) + "Server"
+  }
+  ext.registerFilter("input") { (value: Any?) in
     if let value = value as? Google_Protobuf_MethodDescriptorProto {
       return protoMessageName(value.inputType)
     }
     throw TemplateSyntaxError("message: invalid argument \(value)")
   }
-
-  ext.registerFilter("outputType") { (value: Any?) in
+  ext.registerFilter("output") { (value: Any?) in
     if let value = value as? Google_Protobuf_MethodDescriptorProto {
       return protoMessageName(value.outputType)
     }
     throw TemplateSyntaxError("message: invalid argument \(value)")
   }
-
-  ext.registerFilter("servererrorname") { (value: Any?, arguments: [Any?]) in
-    if arguments.count != 2 {
-      throw TemplateSyntaxError("expects 2 arguments")
-    }
-    guard let protoFile = arguments[0] as? Google_Protobuf_FileDescriptorProto
-      else {
-        throw TemplateSyntaxError("tag must be called with a " +
-          "Google_Protobuf_FileDescriptorProto" +
-          " argument, received \(arguments[0])")
-    }
-    guard let service = arguments[1] as? Google_Protobuf_ServiceDescriptorProto
-      else {
-        throw TemplateSyntaxError("tag must be called with a " +
-          "Google_Protobuf_ServiceDescriptorProto" +
-          " argument, received \(arguments[1])")
-    }
-    return protoFile.package!.capitalized + "_" + service.name! + "ServerError"
-  }
-
-
   let templateEnvironment = Environment(loader: fileSystemLoader,
                                         extensions:[ext])
 
@@ -196,7 +172,7 @@ func main() throws {
 
     // a package declaration is required
     guard let package = protoFile.package else {
-      print("ERROR: no package")
+      print("ERROR: no package for \(protoFile.name)")
       continue
     }
 
@@ -236,8 +212,6 @@ func main() throws {
     }
   }
 
-  // log the entire request proto
-  log += "\n\n\n\(request)"
   // add the logfile to the code generation response
   var logfile = Google_Protobuf_Compiler_CodeGeneratorResponse.File()
   logfile.name = "swiftgrpc.log"

+ 12 - 12
Plugin/templates/client-call-bidistreaming.swift

@@ -1,22 +1,22 @@
 //
 // {{ method.name }} (Bidirectional streaming)
 //
-public class {{ .|callname:protoFile,service,method }} {
+public class {{ .|call:protoFile,service,method }} {
   var call : Call
 
   fileprivate init(_ channel: Channel) {
-    self.call = channel.makeCall("{{ .|callpath:protoFile,service,method }}")
+    self.call = channel.makeCall("{{ .|path:protoFile,service,method }}")
   }
 
-  fileprivate func run(metadata:Metadata) throws -> {{ .|callname:protoFile,service,method }} {
+  fileprivate func run(metadata:Metadata) throws -> {{ .|call:protoFile,service,method }} {
     try self.call.start(metadata: metadata, completion:{})
     return self
   }
 
-  fileprivate func receiveMessage(callback:@escaping ({{ method|outputType }}?) throws -> Void) throws {
+  fileprivate func receiveMessage(callback:@escaping ({{ method|output }}?) throws -> Void) throws {
     try call.receiveMessage() {(data) in
       if let data = data {
-        if let responseMessage = try? {{ method|outputType }}(protobuf:data) {
+        if let responseMessage = try? {{ method|output }}(protobuf:data) {
           try callback(responseMessage)
         } else {
           try callback(nil) // error, bad data
@@ -27,19 +27,19 @@ public class {{ .|callname:protoFile,service,method }} {
     }
   }
 
-  public func Receive() throws -> {{ method|outputType }} {
-    var returnError : {{ .|errorname:protoFile,service }}?
-    var returnMessage : {{ method|outputType }}!
+  public func Receive() throws -> {{ method|output }} {
+    var returnError : {{ .|clienterror:protoFile,service }}?
+    var returnMessage : {{ method|output }}!
     let done = NSCondition()
     do {
       try call.receiveMessage() {(data) in
         if let data = data {
-          returnMessage = try? {{ method|outputType }}(protobuf:data)
+          returnMessage = try? {{ method|output }}(protobuf:data)
           if returnMessage == nil {
-            returnError = {{ .|errorname:protoFile,service }}.invalidMessageReceived
+            returnError = {{ .|clienterror:protoFile,service }}.invalidMessageReceived
           }
         } else {
-          returnError = {{ .|errorname:protoFile,service }}.endOfStream
+          returnError = {{ .|clienterror:protoFile,service }}.endOfStream
         }
         done.lock()
         done.signal()
@@ -55,7 +55,7 @@ public class {{ .|callname:protoFile,service,method }} {
     return returnMessage
   }
 
-  public func Send(_ message:{{ method|inputType }}) {
+  public func Send(_ message:{{ method|input }}) {
     let messageData = try! message.serializeProtobuf()
     _ = call.sendMessage(data:messageData)
   }

+ 10 - 10
Plugin/templates/client-call-clientstreaming.swift

@@ -1,29 +1,29 @@
 //
 // {{ method.name }} (Client streaming)
 //
-public class {{ .|callname:protoFile,service,method }} {
+public class {{ .|call:protoFile,service,method }} {
   var call : Call
 
   fileprivate init(_ channel: Channel) {
-    self.call = channel.makeCall("{{ .|callpath:protoFile,service,method }}")
+    self.call = channel.makeCall("{{ .|path:protoFile,service,method }}")
   }
 
   // Call this to start a call.
-  fileprivate func run(metadata:Metadata) throws -> {{ .|callname:protoFile,service,method }} {
+  fileprivate func run(metadata:Metadata) throws -> {{ .|call:protoFile,service,method }} {
     try self.call.start(metadata: metadata, completion:{})
     return self
   }
 
   // Call this to send each message in the request stream.
-  public func Send(_ message: {{ method|inputType }}) {
+  public func Send(_ message: {{ method|input }}) {
     let messageData = try! message.serializeProtobuf()
     _ = call.sendMessage(data:messageData)
   }
 
   // Call this to close the connection and wait for a response. Blocks.
-  public func CloseAndReceive() throws -> {{ method|outputType }} {
-    var returnError : {{ .|errorname:protoFile,service }}?
-    var returnMessage : {{ method|outputType }}!
+  public func CloseAndReceive() throws -> {{ method|output }} {
+    var returnError : {{ .|clienterror:protoFile,service }}?
+    var returnMessage : {{ method|output }}!
     let done = NSCondition()
 
     do {
@@ -31,7 +31,7 @@ public class {{ .|callname:protoFile,service,method }} {
         if let responseMessage = responseMessage {
           returnMessage = responseMessage
         } else {
-          returnError = {{ .|errorname:protoFile,service }}.invalidMessageReceived
+          returnError = {{ .|clienterror:protoFile,service }}.invalidMessageReceived
         }
         done.lock()
         done.signal()
@@ -56,7 +56,7 @@ public class {{ .|callname:protoFile,service,method }} {
   // Call this to receive a message.
   // The callback will be called when a message is received.
   // call this again from the callback to wait for another message.
-  fileprivate func receiveMessage(callback:@escaping ({{ method|outputType }}?) throws -> Void)
+  fileprivate func receiveMessage(callback:@escaping ({{ method|output }}?) throws -> Void)
     throws {
       try call.receiveMessage() {(data) in
         guard let data = data else {
@@ -64,7 +64,7 @@ public class {{ .|callname:protoFile,service,method }} {
           return
         }
         guard
-          let responseMessage = try? {{ method|outputType }}(protobuf:data)
+          let responseMessage = try? {{ method|output }}(protobuf:data)
           else {
             return
         }

+ 9 - 9
Plugin/templates/client-call-serverstreaming.swift

@@ -1,15 +1,15 @@
 //
 // {{ method.name }} (Server streaming)
 //
-public class {{ .|callname:protoFile,service,method }} {
+public class {{ .|call:protoFile,service,method }} {
   var call : Call
 
   fileprivate init(_ channel: Channel) {
-    self.call = channel.makeCall("{{ .|callpath:protoFile,service,method }}")
+    self.call = channel.makeCall("{{ .|path:protoFile,service,method }}")
   }
 
   // Call this once with the message to send.
-  fileprivate func run(request: {{ method|inputType }}, metadata: Metadata) throws -> {{ .|callname:protoFile,service,method }} {
+  fileprivate func run(request: {{ method|input }}, metadata: Metadata) throws -> {{ .|call:protoFile,service,method }} {
     let requestMessageData = try! request.serializeProtobuf()
     try! call.startServerStreaming(message: requestMessageData,
                                    metadata: metadata,
@@ -18,19 +18,19 @@ public class {{ .|callname:protoFile,service,method }} {
   }
 
   // Call this to wait for a result. Blocks.
-  public func Receive() throws -> {{ method|outputType }} {
-    var returnError : {{ .|errorname:protoFile,service }}?
-    var returnMessage : {{ method|outputType }}!
+  public func Receive() throws -> {{ method|output }} {
+    var returnError : {{ .|clienterror:protoFile,service }}?
+    var returnMessage : {{ method|output }}!
     let done = NSCondition()
     do {
       try call.receiveMessage() {(data) in
         if let data = data {
-          returnMessage = try? {{ method|outputType }}(protobuf:data)
+          returnMessage = try? {{ method|output }}(protobuf:data)
           if returnMessage == nil {
-            returnError = {{ .|errorname:protoFile,service }}.invalidMessageReceived
+            returnError = {{ .|clienterror:protoFile,service }}.invalidMessageReceived
           }
         } else {
-          returnError = {{ .|errorname:protoFile,service }}.endOfStream
+          returnError = {{ .|clienterror:protoFile,service }}.endOfStream
         }
         done.lock()
         done.signal()

+ 7 - 7
Plugin/templates/client-call-unary.swift

@@ -1,25 +1,25 @@
 //
 // {{ method.name }} (Unary)
 //
-public class {{ .|callname:protoFile,service,method }} {
+public class {{ .|call:protoFile,service,method }} {
   var call : Call
 
   fileprivate init(_ channel: Channel) {
-    self.call = channel.makeCall("{{ .|callpath:protoFile,service,method }}")
+    self.call = channel.makeCall("{{ .|path:protoFile,service,method }}")
   }
 
-  fileprivate func run(request: {{ method|inputType }},
-                       metadata: Metadata) throws -> {{ method|outputType }} {
+  fileprivate func run(request: {{ method|input }},
+                       metadata: Metadata) throws -> {{ method|output }} {
     let done = NSCondition()
     var callResult : CallResult!
-    var responseMessage : {{ method|outputType }}?
+    var responseMessage : {{ method|output }}?
     let requestMessageData = try! request.serializeProtobuf()
     try! call.perform(message: requestMessageData,
                       metadata: metadata)
     {(_callResult) in
       callResult = _callResult
       if let messageData = callResult.resultData {
-        responseMessage = try? {{ method|outputType }}(protobuf:messageData)
+        responseMessage = try? {{ method|output }}(protobuf:messageData)
       }
       done.lock()
       done.signal()
@@ -31,7 +31,7 @@ public class {{ .|callname:protoFile,service,method }} {
     if let responseMessage = responseMessage {
       return responseMessage
     } else {
-      throw {{ .|errorname:protoFile,service }}.error(c: callResult)
+      throw {{ .|clienterror:protoFile,service }}.error(c: callResult)
     }
   }
 }

+ 10 - 10
Plugin/templates/client.pb.swift

@@ -41,9 +41,9 @@
 
 import Foundation
 import gRPC
-
 //-{% for service in protoFile.service %}
-public enum {{ .|errorname:protoFile,service }} : Error {
+
+public enum {{ .|clienterror:protoFile,service }} : Error {
   case endOfStream
   case invalidMessageReceived
   case error(c: CallResult)
@@ -93,32 +93,32 @@ public class {{ protoFile.package|capitalize }}_{{ service.name }}Service {
   //-{% for method in service.method %}
   //-{% if not method.clientStreaming and not method.serverStreaming %}
   // Synchronous. Unary.
-  public func {{ method.name|lowercase }}(_ request: {{ method|inputType }}) throws -> {{ method|outputType }} {
-    return try {{ .|callname:protoFile,service,method }}(channel).run(request:request, metadata:metadata)
+  public func {{ method.name|lowercase }}(_ request: {{ method|input }}) throws -> {{ method|output }} {
+    return try {{ .|call:protoFile,service,method }}(channel).run(request:request, metadata:metadata)
   }
   //-{% endif %}
   //-{% if not method.clientStreaming and method.serverStreaming %}
   // Asynchronous. Server-streaming.
   // Send the initial message.
   // Use methods on the returned object to get streamed responses.
-  public func {{ method.name|lowercase }}(_ request: {{ method|inputType }}) throws -> {{ .|callname:protoFile,service,method }} {
-    return try {{ .|callname:protoFile,service,method }}(channel).run(request:request, metadata:metadata)
+  public func {{ method.name|lowercase }}(_ request: {{ method|input }}) throws -> {{ .|call:protoFile,service,method }} {
+    return try {{ .|call:protoFile,service,method }}(channel).run(request:request, metadata:metadata)
   }
   //-{% endif %}
   //-{% if method.clientStreaming and not method.serverStreaming %}
   // Asynchronous. Client-streaming.
   // Use methods on the returned object to stream messages and
   // to close the connection and wait for a final response.
-  public func {{ method.name|lowercase }}() throws -> {{ .|callname:protoFile,service,method }} {
-    return try {{ .|callname:protoFile,service,method }}(channel).run(metadata:metadata)
+  public func {{ method.name|lowercase }}() throws -> {{ .|call:protoFile,service,method }} {
+    return try {{ .|call:protoFile,service,method }}(channel).run(metadata:metadata)
   }
   //-{% endif %}
   //-{% if method.clientStreaming and method.serverStreaming %}
   // Asynchronous. Bidirectional-streaming.
   // Use methods on the returned object to stream messages,
   // to wait for replies, and to close the connection.
-  public func {{ method.name|lowercase }}() throws -> {{ .|callname:protoFile,service,method }} {
-    return try {{ .|callname:protoFile,service,method }}(channel).run(metadata:metadata)
+  public func {{ method.name|lowercase }}() throws -> {{ .|call:protoFile,service,method }} {
+    return try {{ .|call:protoFile,service,method }}(channel).run(metadata:metadata)
   }
   //-{% endif %}
   //-{% endfor %}

+ 8 - 8
Plugin/templates/server-session-bidistreaming.swift

@@ -1,19 +1,19 @@
 // fully streaming
-public class Echo_EchoUpdateSession {
+public class {{ .|session:protoFile,service,method }} {
   var handler : gRPC.Handler
-  var provider : Echo_EchoProvider
+  var provider : {{ .|provider:protoFile,service }}
 
-  fileprivate init(handler:gRPC.Handler, provider: Echo_EchoProvider) {
+  fileprivate init(handler:gRPC.Handler, provider: {{ .|provider:protoFile,service }}) {
     self.handler = handler
     self.provider = provider
   }
 
-  public func Receive() throws -> Echo_EchoRequest {
+  public func Receive() throws -> {{ method|input }} {
     let done = NSCondition()
-    var requestMessage : Echo_EchoRequest?
+    var requestMessage : {{ method|input }}?
     try self.handler.receiveMessage() {(requestData) in
       if let requestData = requestData {
-        requestMessage = try! Echo_EchoRequest(protobuf:requestData)
+        requestMessage = try! {{ method|input }}(protobuf:requestData)
       }
       done.lock()
       done.signal()
@@ -23,12 +23,12 @@ public class Echo_EchoUpdateSession {
     done.wait()
     done.unlock()
     if requestMessage == nil {
-      throw Echo_EchoServerError.endOfStream
+      throw {{ .|servererror:protoFile,service }}.endOfStream
     }
     return requestMessage!
   }
 
-  public func Send(_ response: Echo_EchoResponse) throws {
+  public func Send(_ response: {{ method|output }}) throws {
     try handler.sendResponse(message:response.serializeProtobuf()) {}
   }
 

+ 8 - 9
Plugin/templates/server-session-clientstreaming.swift

@@ -1,19 +1,19 @@
 // client streaming
-public class Echo_EchoCollectSession {
+public class {{ .|session:protoFile,service,method }} {
   var handler : gRPC.Handler
-  var provider : Echo_EchoProvider
+  var provider : {{ .|provider:protoFile,service }}
 
-  fileprivate init(handler:gRPC.Handler, provider: Echo_EchoProvider) {
+  fileprivate init(handler:gRPC.Handler, provider: {{ .|provider:protoFile,service }}) {
     self.handler = handler
     self.provider = provider
   }
 
-  public func Receive() throws -> Echo_EchoRequest {
+  public func Receive() throws -> {{ method|input }} {
     let done = NSCondition()
-    var requestMessage : Echo_EchoRequest?
+    var requestMessage : {{ method|input }}?
     try self.handler.receiveMessage() {(requestData) in
       if let requestData = requestData {
-        requestMessage = try! Echo_EchoRequest(protobuf:requestData)
+        requestMessage = try! {{ method|input }}(protobuf:requestData)
       }
       done.lock()
       done.signal()
@@ -23,12 +23,12 @@ public class Echo_EchoCollectSession {
     done.wait()
     done.unlock()
     if requestMessage == nil {
-      throw Echo_EchoServerError.endOfStream
+      throw {{ .|servererror:protoFile,service }}.endOfStream
     }
     return requestMessage!
   }
 
-  public func SendAndClose(_ response: Echo_EchoResponse) throws {
+  public func SendAndClose(_ response: {{ method|output }}) throws {
     try! self.handler.sendResponse(message:response.serializeProtobuf(),
                                    statusCode: 0,
                                    statusMessage: "OK",
@@ -37,7 +37,6 @@ public class Echo_EchoCollectSession {
 
   fileprivate func run(queue:DispatchQueue) {
     do {
-      print("EchoCollectSession run")
       try self.handler.sendMetadata(initialMetadata:Metadata()) {
         queue.async {
           try! self.provider.collect(session:self)

+ 5 - 5
Plugin/templates/server-session-serverstreaming.swift

@@ -1,14 +1,14 @@
 // server streaming
-public class Echo_EchoExpandSession {
+public class {{ .|session:protoFile,service,method }} {
   var handler : gRPC.Handler
-  var provider : Echo_EchoProvider
+  var provider : {{ .|provider:protoFile,service }}
 
-  fileprivate init(handler:gRPC.Handler, provider: Echo_EchoProvider) {
+  fileprivate init(handler:gRPC.Handler, provider: {{ .|provider:protoFile,service }}) {
     self.handler = handler
     self.provider = provider
   }
 
-  public func Send(_ response: Echo_EchoResponse) throws {
+  public func Send(_ response: {{ method|output }}) throws {
     try! handler.sendResponse(message:response.serializeProtobuf()) {}
   }
 
@@ -16,7 +16,7 @@ public class Echo_EchoExpandSession {
     do {
       try self.handler.receiveMessage(initialMetadata:Metadata()) {(requestData) in
         if let requestData = requestData {
-          let requestMessage = try! Echo_EchoRequest(protobuf:requestData)
+          let requestMessage = try! {{ method|input }}(protobuf:requestData)
           // to keep providers from blocking the server thread,
           // we dispatch them to another queue.
           queue.async {

+ 4 - 4
Plugin/templates/server-session-unary.swift

@@ -1,9 +1,9 @@
 // unary
-public class Echo_EchoGetSession {
+public class {{ .|session:protoFile,service,method }} {
   var handler : gRPC.Handler
-  var provider : Echo_EchoProvider
+  var provider : {{ .|provider:protoFile,service }}
 
-  fileprivate init(handler:gRPC.Handler, provider: Echo_EchoProvider) {
+  fileprivate init(handler:gRPC.Handler, provider: {{ .|provider:protoFile,service }}) {
     self.handler = handler
     self.provider = provider
   }
@@ -12,7 +12,7 @@ public class Echo_EchoGetSession {
     do {
       try handler.receiveMessage(initialMetadata:Metadata()) {(requestData) in
         if let requestData = requestData {
-          let requestMessage = try! Echo_EchoRequest(protobuf:requestData)
+          let requestMessage = try! {{ method|input }}(protobuf:requestData)
           let replyMessage = try! self.provider.get(request:requestMessage)
           try self.handler.sendResponse(message:replyMessage.serializeProtobuf(),
                                         statusCode: 0,

+ 13 - 15
Plugin/templates/server.pb.swift

@@ -41,29 +41,28 @@
 
 import Foundation
 import gRPC
-
 //-{% for service in protoFile.service %}
-public enum {{ .|servererrorname:protoFile,service }} : Error {
+
+public enum {{ .|servererror:protoFile,service }} : Error {
   case endOfStream
 }
 
-public protocol Echo_EchoProvider {
+public protocol {{ .|provider:protoFile,service }} {
   //-{% for method in service.method %}
   //-{% if not method.clientStreaming and not method.serverStreaming %}
-  func {{ method.name|lowercase }}(request : {{ method|inputType }}) throws -> {{ method|outputType }}
+  func {{ method.name|lowercase }}(request : {{ method|input }}) throws -> {{ method|output }}
   //-{% endif %}
   //-{% if not method.clientStreaming and method.serverStreaming %}
-  func {{ method.name|lowercase }}(request : {{ method|inputType }}, session : {{ .|sessionname:protoFile,service,method }}) throws
+  func {{ method.name|lowercase }}(request : {{ method|input }}, session : {{ .|session:protoFile,service,method }}) throws
   //-{% endif %}
   //-{% if method.clientStreaming and not method.serverStreaming %}
-  func {{ method.name|lowercase }}(session : {{ .|sessionname:protoFile,service,method }}) throws
+  func {{ method.name|lowercase }}(session : {{ .|session:protoFile,service,method }}) throws
   //-{% endif %}
   //-{% if method.clientStreaming and method.serverStreaming %}
-  func {{ method.name|lowercase }}(session : {{ .|sessionname:protoFile,service,method }}) throws
+  func {{ method.name|lowercase }}(session : {{ .|session:protoFile,service,method }}) throws
   //-{% endif %}
   //-{% endfor %}
 }
-
 //-{% for method in service.method %}
 //-{% if not method.clientStreaming and not method.serverStreaming %}
 //-{% include "server-session-unary.swift" %}
@@ -78,17 +77,16 @@ public protocol Echo_EchoProvider {
 //-{% include "server-session-bidistreaming.swift" %}
 //-{% endif %}
 //-{% endfor %}
-
 //
 // main server for generated service
 //
-public class Echo_EchoServer {
+public class {{ .|server:protoFile,service }} {
   private var address: String
   private var server: gRPC.Server
-  public var provider: Echo_EchoProvider?
+  public var provider: {{ .|provider:protoFile,service }}?
 
   public init(address:String,
-              provider:Echo_EchoProvider) {
+              provider:{{ .|provider:protoFile,service }}) {
     gRPC.initialize()
     self.address = address
     self.provider = provider
@@ -98,7 +96,7 @@ public class Echo_EchoServer {
   public init?(address:String,
                certificateURL:URL,
                keyURL:URL,
-               provider:Echo_EchoProvider) {
+               provider:{{ .|provider:protoFile,service }}) {
     gRPC.initialize()
     self.address = address
     self.provider = provider
@@ -122,8 +120,8 @@ public class Echo_EchoServer {
 
       switch handler.method {
 	  //-{% for method in service.method %}
-      case "{{ .|callpath:protoFile,service,method }}":
-        {{ .|sessionname:protoFile,service,method }}(handler:handler, provider:provider).run(queue:queue)
+      case "{{ .|path:protoFile,service,method }}":
+        {{ .|session:protoFile,service,method }}(handler:handler, provider:provider).run(queue:queue)
 	  //-{% endfor %}
       default:
         break // handle unknown requests