Browse Source

fully-templatized client code generation.

Tim Burks 9 years ago
parent
commit
e8ee5d280c

+ 5 - 12
Examples/Echo/Swift/Echo/echo.client.pb.swift

@@ -47,9 +47,8 @@ public enum Echo_EchoClientError : Error {
   case invalidMessageReceived
   case error(c: CallResult)
 }
-
 //
-// Unary GET
+// Get (Unary)
 //
 public class Echo_EchoGetCall {
   var call : Call
@@ -85,9 +84,8 @@ public class Echo_EchoGetCall {
     }
   }
 }
-
 //
-// Server-streaming EXPAND
+// Expand (Server streaming)
 //
 public class Echo_EchoExpandCall {
   var call : Call
@@ -134,9 +132,8 @@ public class Echo_EchoExpandCall {
     return returnMessage
   }
 }
-
 //
-// Client-streaming COLLECT
+// Collect (Client streaming)
 //
 public class Echo_EchoCollectCall {
   var call : Call
@@ -210,9 +207,8 @@ public class Echo_EchoCollectCall {
   }
 
 }
-
 //
-// Bidirectional-streaming UPDATE
+// Update (Bidirectional streaming)
 //
 public class Echo_EchoUpdateCall {
   var call : Call
@@ -317,25 +313,22 @@ public class Echo_EchoService {
   public func get(_ request: Echo_EchoRequest) throws -> Echo_EchoResponse {
     return try Echo_EchoGetCall(channel).run(request:request, metadata:metadata)
   }
-
   // Asynchronous. Server-streaming.
   // Send the initial message.
   // Use methods on the returned object to get streamed responses.
   public func expand(_ request: Echo_EchoRequest) throws -> Echo_EchoExpandCall {
     return try Echo_EchoExpandCall(channel).run(request:request, metadata:metadata)
   }
-
   // 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 collect() throws -> Echo_EchoCollectCall {
     return try Echo_EchoCollectCall(channel).run(metadata:metadata)
   }
-
   // Asynchronous. Bidirectional-streaming.
   // Use methods on the returned object to stream messages,
   // to wait for replies, and to close the connection.
   public func update() throws -> Echo_EchoUpdateCall {
     return try Echo_EchoUpdateCall(channel).run(metadata:metadata)
   }
-}
+}

+ 19 - 12
Plugin/Sources/main.swift

@@ -29,6 +29,24 @@ func protoMessageName(_ name :String?) -> String {
   }
 }
 
+func stripMarkers(_ code:String) -> String {
+  let inputLines = code.components(separatedBy:"\n")
+
+  var outputLines : [String] = []
+  for line in inputLines {
+    if line.contains("//-") {
+      let removed = line.replacingOccurrences(of:"//-", with:"")
+      if (removed.trimmingCharacters(in:CharacterSet.whitespaces) != "") {
+        outputLines.append(removed)
+      }
+    } else {
+      outputLines.append(line)
+    }
+  }
+  return outputLines.joined(separator:"\n")
+}
+
+
 
 func main() throws {
 
@@ -36,16 +54,6 @@ func main() throws {
   let fileSystemLoader = FileSystemLoader(paths: ["templates/"])
   let ext = Extension()
 
-  ext.registerFilter("message") { (value: Any?) in
-    if let value = value as? String {
-      let parts = value.components(separatedBy:".")
-      if parts.count == 3 {
-        return parts[1].capitalized + "_" + parts[2]
-      }
-    }
-    throw TemplateSyntaxError("message: invalid argument \(value)")
-  }
-
   ext.registerFilter("callname") { (value: Any?, arguments: [Any?]) in
     if arguments.count != 3 {
       throw TemplateSyntaxError("expects 3 arguments")
@@ -129,7 +137,6 @@ func main() throws {
     throw TemplateSyntaxError("message: invalid argument \(value)")
   }
 
-
   let templateEnvironment = Environment(loader: fileSystemLoader,
                                         extensions:[ext])
 
@@ -172,7 +179,7 @@ func main() throws {
                                                               context: context)
       var clientfile = Google_Protobuf_Compiler_CodeGeneratorResponse.File()
       clientfile.name = package + ".client.pb.swift"
-      clientfile.content = clientcode
+      clientfile.content = stripMarkers(clientcode)
       response.file.append(clientfile)
 
       let servercode = try templateEnvironment.renderTemplate(name:"server.pb.swift",

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

@@ -8,15 +8,15 @@ public class {{ .|callname:protoFile,service,method }} {
     self.call = channel.makeCall("{{ .|callpath:protoFile,service,method }}")
   }
 
-  fileprivate func run(metadata:Metadata) throws -> Echo_EchoUpdateCall {
+  fileprivate func run(metadata:Metadata) throws -> {{ .|callname:protoFile,service,method }} {
     try self.call.start(metadata: metadata, completion:{})
     return self
   }
 
-  fileprivate func receiveMessage(callback:@escaping (Echo_EchoResponse?) throws -> Void) throws {
+  fileprivate func receiveMessage(callback:@escaping ({{ method|outputType }}?) throws -> Void) throws {
     try call.receiveMessage() {(data) in
       if let data = data {
-        if let responseMessage = try? Echo_EchoResponse(protobuf:data) {
+        if let responseMessage = try? {{ method|outputType }}(protobuf:data) {
           try callback(responseMessage)
         } else {
           try callback(nil) // error, bad data
@@ -27,14 +27,14 @@ public class {{ .|callname:protoFile,service,method }} {
     }
   }
 
-  public func Receive() throws -> Echo_EchoResponse {
+  public func Receive() throws -> {{ method|outputType }} {
     var returnError : {{ .|errorname:protoFile,service }}?
-    var returnMessage : Echo_EchoResponse!
+    var returnMessage : {{ method|outputType }}!
     let done = NSCondition()
     do {
       try call.receiveMessage() {(data) in
         if let data = data {
-          returnMessage = try? Echo_EchoResponse(protobuf:data)
+          returnMessage = try? {{ method|outputType }}(protobuf:data)
           if returnMessage == nil {
             returnError = {{ .|errorname:protoFile,service }}.invalidMessageReceived
           }
@@ -55,7 +55,7 @@ public class {{ .|callname:protoFile,service,method }} {
     return returnMessage
   }
 
-  public func Send(_ message:Echo_EchoRequest) {
+  public func Send(_ message:{{ method|inputType }}) {
     let messageData = try! message.serializeProtobuf()
     _ = call.sendMessage(data:messageData)
   }
@@ -71,4 +71,4 @@ public class {{ .|callname:protoFile,service,method }} {
     done.wait()
     done.unlock()
   }
-}
+}

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

@@ -9,21 +9,21 @@ public class {{ .|callname:protoFile,service,method }} {
   }
 
   // Call this to start a call.
-  fileprivate func run(metadata:Metadata) throws -> Echo_EchoCollectCall {
+  fileprivate func run(metadata:Metadata) throws -> {{ .|callname: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: Echo_EchoRequest) {
+  public func Send(_ message: {{ method|inputType }}) {
     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 -> Echo_EchoResponse {
+  public func CloseAndReceive() throws -> {{ method|outputType }} {
     var returnError : {{ .|errorname:protoFile,service }}?
-    var returnMessage : Echo_EchoResponse!
+    var returnMessage : {{ method|outputType }}!
     let done = NSCondition()
 
     do {
@@ -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 (Echo_EchoResponse?) throws -> Void)
+  fileprivate func receiveMessage(callback:@escaping ({{ method|outputType }}?) 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? Echo_EchoResponse(protobuf:data)
+          let responseMessage = try? {{ method|outputType }}(protobuf:data)
           else {
             return
         }
@@ -72,4 +72,4 @@ public class {{ .|callname:protoFile,service,method }} {
       }
   }
 
-}
+}

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

@@ -9,7 +9,7 @@ public class {{ .|callname:protoFile,service,method }} {
   }
 
   // Call this once with the message to send.
-  fileprivate func run(request: Echo_EchoRequest, metadata: Metadata) throws -> Echo_EchoExpandCall {
+  fileprivate func run(request: {{ method|inputType }}, metadata: Metadata) throws -> {{ .|callname:protoFile,service,method }} {
     let requestMessageData = try! request.serializeProtobuf()
     try! call.startServerStreaming(message: requestMessageData,
                                    metadata: metadata,
@@ -18,14 +18,14 @@ public class {{ .|callname:protoFile,service,method }} {
   }
 
   // Call this to wait for a result. Blocks.
-  public func Receive() throws -> Echo_EchoResponse {
+  public func Receive() throws -> {{ method|outputType }} {
     var returnError : {{ .|errorname:protoFile,service }}?
-    var returnMessage : Echo_EchoResponse!
+    var returnMessage : {{ method|outputType }}!
     let done = NSCondition()
     do {
       try call.receiveMessage() {(data) in
         if let data = data {
-          returnMessage = try? Echo_EchoResponse(protobuf:data)
+          returnMessage = try? {{ method|outputType }}(protobuf:data)
           if returnMessage == nil {
             returnError = {{ .|errorname:protoFile,service }}.invalidMessageReceived
           }
@@ -45,4 +45,4 @@ public class {{ .|callname:protoFile,service,method }} {
     }
     return returnMessage
   }
-}
+}

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

@@ -42,26 +42,26 @@
 import Foundation
 import gRPC
 
-//{% for service in protoFile.service %}
+//-{% for service in protoFile.service %}
 public enum {{ .|errorname:protoFile,service }} : Error {
   case endOfStream
   case invalidMessageReceived
   case error(c: CallResult)
 }
-//{% for method in service.method %}
-//{% if not method.clientStreaming and not method.serverStreaming %}
-//{% include "client-call-unary.swift" %}
-//{% endif %}
-//{% if not method.clientStreaming and method.serverStreaming %}
-//{% include "client-call-serverstreaming.swift" %}
-//{% endif %}
-//{% if method.clientStreaming and not method.serverStreaming %}
-//{% include "client-call-clientstreaming.swift" %}
-//{% endif %}
-//{% if method.clientStreaming and method.serverStreaming %}
-//{% include "client-call-bidistreaming.swift" %}
-//{% endif %}
-//{% endfor %}
+//-{% for method in service.method %}
+//-{% if not method.clientStreaming and not method.serverStreaming %}
+//-{% include "client-call-unary.swift" %}
+//-{% endif %}
+//-{% if not method.clientStreaming and method.serverStreaming %}
+//-{% include "client-call-serverstreaming.swift" %}
+//-{% endif %}
+//-{% if method.clientStreaming and not method.serverStreaming %}
+//-{% include "client-call-clientstreaming.swift" %}
+//-{% endif %}
+//-{% if method.clientStreaming and method.serverStreaming %}
+//-{% include "client-call-bidistreaming.swift" %}
+//-{% endif %}
+//-{% endfor %}
 
 // Call methods of this class to make API calls.
 public class {{ protoFile.package|capitalize }}_{{ service.name }}Service {
@@ -90,37 +90,37 @@ public class {{ protoFile.package|capitalize }}_{{ service.name }}Service {
     metadata = Metadata()
   }
 
-  //{% for method in service.method %}
-  //{% if not method.clientStreaming and not method.serverStreaming %}
+  //-{% for method in service.method %}
+  //-{% if not method.clientStreaming and not method.serverStreaming %}
   // Synchronous. Unary.
-  public func {{ method.name|lowercase }}(_ request: {{ method.inputType|message }}) throws -> {{ method.outputType|message }} {
+  public func {{ method.name|lowercase }}(_ request: {{ method|inputType }}) throws -> {{ method|outputType }} {
     return try {{ .|callname:protoFile,service,method }}(channel).run(request:request, metadata:metadata)
   }
-  //{% endif %}
-  //{% if not method.clientStreaming and method.serverStreaming %}
+  //-{% 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|message }}) throws -> {{ .|callname:protoFile,service,method }} {
+  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)
   }
-  //{% endif %}
-  //{% if method.clientStreaming and not method.serverStreaming %}
+  //-{% 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)
   }
-  //{% endif %}
-  //{% if method.clientStreaming and method.serverStreaming %}
+  //-{% 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)
   }
-  //{% endif %}
-  //{% endfor %}
+  //-{% endif %}
+  //-{% endfor %}
 }
-//{% endfor %}
+//-{% endfor %}