2
0

Generator-Client.swift 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. /*
  2. * Copyright 2018, gRPC Authors All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. import Foundation
  17. import SwiftProtobuf
  18. import SwiftProtobufPluginLibrary
  19. extension Generator {
  20. internal func printClient() {
  21. for method in service.methods {
  22. self.method = method
  23. switch streamingType(method) {
  24. case .unary:
  25. printServiceClientMethodCallUnary()
  26. case .serverStreaming:
  27. printServiceClientMethodCallServerStreaming()
  28. case .clientStreaming:
  29. printServiceClientMethodCallClientStreaming()
  30. case .bidirectionalStreaming:
  31. printServiceClientMethodCallBidiStreaming()
  32. }
  33. }
  34. println()
  35. printServiceClientProtocol()
  36. println()
  37. printServiceClientImplementation()
  38. if options.generateTestStubs {
  39. println()
  40. printServiceClientTestStubs()
  41. }
  42. }
  43. private func printServiceClientMethodCallUnary() {
  44. println("\(access) protocol \(callName): ClientCallUnary {}")
  45. println()
  46. println("fileprivate final class \(callName)Base: ClientCallUnaryBase<\(methodInputName), \(methodOutputName)>, \(callName) {")
  47. indent()
  48. println("override class var method: String { return \(methodPath) }")
  49. outdent()
  50. println("}")
  51. println()
  52. }
  53. private func printServiceClientMethodCallServerStreaming() {
  54. println("\(access) protocol \(callName): ClientCallServerStreaming {")
  55. indent()
  56. println("/// Call this to wait for a result. Blocking.")
  57. println("func receive() throws -> \(methodOutputName)")
  58. println("/// Call this to wait for a result. Nonblocking.")
  59. println("func receive(completion: @escaping (\(methodOutputName)?, ClientError?) -> Void) throws")
  60. outdent()
  61. println("}")
  62. println()
  63. println("fileprivate final class \(callName)Base: ClientCallServerStreamingBase<\(methodInputName), \(methodOutputName)>, \(callName) {")
  64. indent()
  65. println("override class var method: String { return \(methodPath) }")
  66. outdent()
  67. println("}")
  68. if options.generateTestStubs {
  69. println()
  70. println("class \(callName)TestStub: ClientCallServerStreamingTestStub<\(methodOutputName)>, \(callName) {")
  71. indent()
  72. println("override class var method: String { return \(methodPath) }")
  73. outdent()
  74. println("}")
  75. }
  76. println()
  77. }
  78. private func printServiceClientMethodCallClientStreaming() {
  79. println("\(options.visibility.sourceSnippet) protocol \(callName): ClientCallClientStreaming {")
  80. indent()
  81. println("/// Call this to send each message in the request stream. Nonblocking.")
  82. println("func send(_ message: \(methodInputName), completion: @escaping (Error?) -> Void) throws")
  83. println()
  84. println("/// Call this to close the connection and wait for a response. Blocking.")
  85. println("func closeAndReceive() throws -> \(methodOutputName)")
  86. println("/// Call this to close the connection and wait for a response. Nonblocking.")
  87. println("func closeAndReceive(completion: @escaping (\(methodOutputName)?, ClientError?) -> Void) throws")
  88. outdent()
  89. println("}")
  90. println()
  91. println("fileprivate final class \(callName)Base: ClientCallClientStreamingBase<\(methodInputName), \(methodOutputName)>, \(callName) {")
  92. indent()
  93. println("override class var method: String { return \(methodPath) }")
  94. outdent()
  95. println("}")
  96. if options.generateTestStubs {
  97. println()
  98. println("/// Simple fake implementation of \(callName)")
  99. println("/// stores sent values for later verification and finall returns a previously-defined result.")
  100. println("class \(callName)TestStub: ClientCallClientStreamingTestStub<\(methodInputName), \(methodOutputName)>, \(callName) {")
  101. indent()
  102. println("override class var method: String { return \(methodPath) }")
  103. outdent()
  104. println("}")
  105. }
  106. println()
  107. }
  108. private func printServiceClientMethodCallBidiStreaming() {
  109. println("\(access) protocol \(callName): ClientCallBidirectionalStreaming {")
  110. indent()
  111. println("/// Call this to wait for a result. Blocking.")
  112. println("func receive() throws -> \(methodOutputName)")
  113. println("/// Call this to wait for a result. Nonblocking.")
  114. println("func receive(completion: @escaping (\(methodOutputName)?, ClientError?) -> Void) throws")
  115. println()
  116. println("/// Call this to send each message in the request stream.")
  117. println("func send(_ message: \(methodInputName), completion: @escaping (Error?) -> Void) throws")
  118. println()
  119. println("/// Call this to close the sending connection. Blocking.")
  120. println("func closeSend() throws")
  121. println("/// Call this to close the sending connection. Nonblocking.")
  122. println("func closeSend(completion: (() -> Void)?) throws")
  123. outdent()
  124. println("}")
  125. println()
  126. println("fileprivate final class \(callName)Base: ClientCallBidirectionalStreamingBase<\(methodInputName), \(methodOutputName)>, \(callName) {")
  127. indent()
  128. println("override class var method: String { return \(methodPath) }")
  129. outdent()
  130. println("}")
  131. if options.generateTestStubs {
  132. println()
  133. println("class \(callName)TestStub: ClientCallBidirectionalStreamingTestStub<\(methodInputName), \(methodOutputName)>, \(callName) {")
  134. indent()
  135. println("override class var method: String { return \(methodPath) }")
  136. outdent()
  137. println("}")
  138. }
  139. println()
  140. }
  141. private func printServiceClientProtocol() {
  142. println("/// Instantiate \(serviceClassName)Client, then call methods of this protocol to make API calls.")
  143. println("\(options.visibility.sourceSnippet) protocol \(serviceClassName): ServiceClient {")
  144. indent()
  145. for method in service.methods {
  146. self.method = method
  147. switch streamingType(method) {
  148. case .unary:
  149. println("/// Synchronous. Unary.")
  150. println("func \(methodFunctionName)(_ request: \(methodInputName)) throws -> \(methodOutputName)")
  151. println("/// Asynchronous. Unary.")
  152. println("func \(methodFunctionName)(_ request: \(methodInputName), completion: @escaping (\(methodOutputName)?, CallResult) -> Void) throws -> \(callName)")
  153. case .serverStreaming:
  154. println("/// Asynchronous. Server-streaming.")
  155. println("/// Send the initial message.")
  156. println("/// Use methods on the returned object to get streamed responses.")
  157. println("func \(methodFunctionName)(_ request: \(methodInputName), completion: ((CallResult) -> Void)?) throws -> \(callName)")
  158. case .clientStreaming:
  159. println("/// Asynchronous. Client-streaming.")
  160. println("/// Use methods on the returned object to stream messages and")
  161. println("/// to close the connection and wait for a final response.")
  162. println("func \(methodFunctionName)(completion: ((CallResult) -> Void)?) throws -> \(callName)")
  163. case .bidirectionalStreaming:
  164. println("/// Asynchronous. Bidirectional-streaming.")
  165. println("/// Use methods on the returned object to stream messages,")
  166. println("/// to wait for replies, and to close the connection.")
  167. println("func \(methodFunctionName)(completion: ((CallResult) -> Void)?) throws -> \(callName)")
  168. }
  169. println()
  170. }
  171. outdent()
  172. println("}")
  173. }
  174. private func printServiceClientImplementation() {
  175. println("\(access) final class \(serviceClassName)Client: ServiceClientBase, \(serviceClassName) {")
  176. indent()
  177. for method in service.methods {
  178. self.method = method
  179. switch streamingType(method) {
  180. case .unary:
  181. println("/// Synchronous. Unary.")
  182. println("\(access) func \(methodFunctionName)(_ request: \(methodInputName)) throws -> \(methodOutputName) {")
  183. indent()
  184. println("return try \(callName)Base(channel)")
  185. indent()
  186. println(".run(request: request, metadata: metadata)")
  187. outdent()
  188. outdent()
  189. println("}")
  190. println("/// Asynchronous. Unary.")
  191. println("\(access) func \(methodFunctionName)(_ request: \(methodInputName), completion: @escaping (\(methodOutputName)?, CallResult) -> Void) throws -> \(callName) {")
  192. indent()
  193. println("return try \(callName)Base(channel)")
  194. indent()
  195. println(".start(request: request, metadata: metadata, completion: completion)")
  196. outdent()
  197. outdent()
  198. println("}")
  199. case .serverStreaming:
  200. println("/// Asynchronous. Server-streaming.")
  201. println("/// Send the initial message.")
  202. println("/// Use methods on the returned object to get streamed responses.")
  203. println("\(access) func \(methodFunctionName)(_ request: \(methodInputName), completion: ((CallResult) -> Void)?) throws -> \(callName) {")
  204. indent()
  205. println("return try \(callName)Base(channel)")
  206. indent()
  207. println(".start(request: request, metadata: metadata, completion: completion)")
  208. outdent()
  209. outdent()
  210. println("}")
  211. case .clientStreaming:
  212. println("/// Asynchronous. Client-streaming.")
  213. println("/// Use methods on the returned object to stream messages and")
  214. println("/// to close the connection and wait for a final response.")
  215. println("\(access) func \(methodFunctionName)(completion: ((CallResult) -> Void)?) throws -> \(callName) {")
  216. indent()
  217. println("return try \(callName)Base(channel)")
  218. indent()
  219. println(".start(metadata: metadata, completion: completion)")
  220. outdent()
  221. outdent()
  222. println("}")
  223. case .bidirectionalStreaming:
  224. println("/// Asynchronous. Bidirectional-streaming.")
  225. println("/// Use methods on the returned object to stream messages,")
  226. println("/// to wait for replies, and to close the connection.")
  227. println("\(access) func \(methodFunctionName)(completion: ((CallResult) -> Void)?) throws -> \(callName) {")
  228. indent()
  229. println("return try \(callName)Base(channel)")
  230. indent()
  231. println(".start(metadata: metadata, completion: completion)")
  232. outdent()
  233. outdent()
  234. println("}")
  235. }
  236. println()
  237. }
  238. outdent()
  239. println("}")
  240. }
  241. private func printServiceClientTestStubs() {
  242. println("class \(serviceClassName)TestStub: ServiceClientTestStubBase, \(serviceClassName) {")
  243. indent()
  244. for method in service.methods {
  245. self.method = method
  246. switch streamingType(method) {
  247. case .unary:
  248. println("var \(methodFunctionName)Requests: [\(methodInputName)] = []")
  249. println("var \(methodFunctionName)Responses: [\(methodOutputName)] = []")
  250. println("func \(methodFunctionName)(_ request: \(methodInputName)) throws -> \(methodOutputName) {")
  251. indent()
  252. println("\(methodFunctionName)Requests.append(request)")
  253. println("defer { \(methodFunctionName)Responses.removeFirst() }")
  254. println("return \(methodFunctionName)Responses.first!")
  255. outdent()
  256. println("}")
  257. println("func \(methodFunctionName)(_ request: \(methodInputName), completion: @escaping (\(methodOutputName)?, CallResult) -> Void) throws -> \(callName) {")
  258. indent()
  259. println("fatalError(\"not implemented\")")
  260. outdent()
  261. println("}")
  262. case .serverStreaming:
  263. println("var \(methodFunctionName)Requests: [\(methodInputName)] = []")
  264. println("var \(methodFunctionName)Calls: [\(callName)] = []")
  265. println("func \(methodFunctionName)(_ request: \(methodInputName), completion: ((CallResult) -> Void)?) throws -> \(callName) {")
  266. indent()
  267. println("\(methodFunctionName)Requests.append(request)")
  268. println("defer { \(methodFunctionName)Calls.removeFirst() }")
  269. println("return \(methodFunctionName)Calls.first!")
  270. outdent()
  271. println("}")
  272. case .clientStreaming:
  273. println("var \(methodFunctionName)Calls: [\(callName)] = []")
  274. println("func \(methodFunctionName)(completion: ((CallResult) -> Void)?) throws -> \(callName) {")
  275. indent()
  276. println("defer { \(methodFunctionName)Calls.removeFirst() }")
  277. println("return \(methodFunctionName)Calls.first!")
  278. outdent()
  279. println("}")
  280. case .bidirectionalStreaming:
  281. println("var \(methodFunctionName)Calls: [\(callName)] = []")
  282. println("func \(methodFunctionName)(completion: ((CallResult) -> Void)?) throws -> \(callName) {")
  283. indent()
  284. println("defer { \(methodFunctionName)Calls.removeFirst() }")
  285. println("return \(methodFunctionName)Calls.first!")
  286. outdent()
  287. println("}")
  288. }
  289. println()
  290. }
  291. outdent()
  292. println("}")
  293. }
  294. }