2
0

Generator-Client.swift 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  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. printStreamReceiveMethods(receivedType: methodOutputName)
  57. outdent()
  58. println("}")
  59. println()
  60. println("fileprivate final class \(callName)Base: ClientCallServerStreamingBase<\(methodInputName), \(methodOutputName)>, \(callName) {")
  61. indent()
  62. println("override class var method: String { return \(methodPath) }")
  63. outdent()
  64. println("}")
  65. if options.generateTestStubs {
  66. println()
  67. println("class \(callName)TestStub: ClientCallServerStreamingTestStub<\(methodOutputName)>, \(callName) {")
  68. indent()
  69. println("override class var method: String { return \(methodPath) }")
  70. outdent()
  71. println("}")
  72. }
  73. println()
  74. }
  75. private func printServiceClientMethodCallClientStreaming() {
  76. println("\(options.visibility.sourceSnippet) protocol \(callName): ClientCallClientStreaming {")
  77. indent()
  78. printStreamSendMethods(sentType: methodInputName)
  79. println()
  80. println("/// Call this to close the connection and wait for a response. Blocking.")
  81. println("func closeAndReceive() throws -> \(methodOutputName)")
  82. println("/// Call this to close the connection and wait for a response. Nonblocking.")
  83. println("func closeAndReceive(completion: @escaping (ResultOrRPCError<\(methodOutputName)>) -> Void) throws")
  84. outdent()
  85. println("}")
  86. println()
  87. println("fileprivate final class \(callName)Base: ClientCallClientStreamingBase<\(methodInputName), \(methodOutputName)>, \(callName) {")
  88. indent()
  89. println("override class var method: String { return \(methodPath) }")
  90. outdent()
  91. println("}")
  92. if options.generateTestStubs {
  93. println()
  94. println("/// Simple fake implementation of \(callName)")
  95. println("/// stores sent values for later verification and finall returns a previously-defined result.")
  96. println("class \(callName)TestStub: ClientCallClientStreamingTestStub<\(methodInputName), \(methodOutputName)>, \(callName) {")
  97. indent()
  98. println("override class var method: String { return \(methodPath) }")
  99. outdent()
  100. println("}")
  101. }
  102. println()
  103. }
  104. private func printServiceClientMethodCallBidiStreaming() {
  105. println("\(access) protocol \(callName): ClientCallBidirectionalStreaming {")
  106. indent()
  107. printStreamReceiveMethods(receivedType: methodOutputName)
  108. println()
  109. printStreamSendMethods(sentType: methodInputName)
  110. println()
  111. println("/// Call this to close the sending connection. Blocking.")
  112. println("func closeSend() throws")
  113. println("/// Call this to close the sending connection. Nonblocking.")
  114. println("func closeSend(completion: (() -> Void)?) throws")
  115. outdent()
  116. println("}")
  117. println()
  118. println("fileprivate final class \(callName)Base: ClientCallBidirectionalStreamingBase<\(methodInputName), \(methodOutputName)>, \(callName) {")
  119. indent()
  120. println("override class var method: String { return \(methodPath) }")
  121. outdent()
  122. println("}")
  123. if options.generateTestStubs {
  124. println()
  125. println("class \(callName)TestStub: ClientCallBidirectionalStreamingTestStub<\(methodInputName), \(methodOutputName)>, \(callName) {")
  126. indent()
  127. println("override class var method: String { return \(methodPath) }")
  128. outdent()
  129. println("}")
  130. }
  131. println()
  132. }
  133. private func printServiceClientProtocol() {
  134. println("/// Instantiate \(serviceClassName)Client, then call methods of this protocol to make API calls.")
  135. println("\(options.visibility.sourceSnippet) protocol \(serviceClassName): ServiceClient {")
  136. indent()
  137. for method in service.methods {
  138. self.method = method
  139. switch streamingType(method) {
  140. case .unary:
  141. println("/// Synchronous. Unary.")
  142. println("func \(methodFunctionName)(_ request: \(methodInputName)) throws -> \(methodOutputName)")
  143. println("/// Asynchronous. Unary.")
  144. println("func \(methodFunctionName)(_ request: \(methodInputName), completion: @escaping (\(methodOutputName)?, CallResult) -> Void) throws -> \(callName)")
  145. case .serverStreaming:
  146. println("/// Asynchronous. Server-streaming.")
  147. println("/// Send the initial message.")
  148. println("/// Use methods on the returned object to get streamed responses.")
  149. println("func \(methodFunctionName)(_ request: \(methodInputName), completion: ((CallResult) -> Void)?) throws -> \(callName)")
  150. case .clientStreaming:
  151. println("/// Asynchronous. Client-streaming.")
  152. println("/// Use methods on the returned object to stream messages and")
  153. println("/// to close the connection and wait for a final response.")
  154. println("func \(methodFunctionName)(completion: ((CallResult) -> Void)?) throws -> \(callName)")
  155. case .bidirectionalStreaming:
  156. println("/// Asynchronous. Bidirectional-streaming.")
  157. println("/// Use methods on the returned object to stream messages,")
  158. println("/// to wait for replies, and to close the connection.")
  159. println("func \(methodFunctionName)(completion: ((CallResult) -> Void)?) throws -> \(callName)")
  160. }
  161. println()
  162. }
  163. outdent()
  164. println("}")
  165. }
  166. private func printServiceClientImplementation() {
  167. println("\(access) final class \(serviceClassName)Client: ServiceClientBase, \(serviceClassName) {")
  168. indent()
  169. for method in service.methods {
  170. self.method = method
  171. switch streamingType(method) {
  172. case .unary:
  173. println("/// Synchronous. Unary.")
  174. println("\(access) func \(methodFunctionName)(_ request: \(methodInputName)) throws -> \(methodOutputName) {")
  175. indent()
  176. println("return try \(callName)Base(channel)")
  177. indent()
  178. println(".run(request: request, metadata: metadata)")
  179. outdent()
  180. outdent()
  181. println("}")
  182. println("/// Asynchronous. Unary.")
  183. println("\(access) func \(methodFunctionName)(_ request: \(methodInputName), completion: @escaping (\(methodOutputName)?, CallResult) -> Void) throws -> \(callName) {")
  184. indent()
  185. println("return try \(callName)Base(channel)")
  186. indent()
  187. println(".start(request: request, metadata: metadata, completion: completion)")
  188. outdent()
  189. outdent()
  190. println("}")
  191. case .serverStreaming:
  192. println("/// Asynchronous. Server-streaming.")
  193. println("/// Send the initial message.")
  194. println("/// Use methods on the returned object to get streamed responses.")
  195. println("\(access) func \(methodFunctionName)(_ request: \(methodInputName), completion: ((CallResult) -> Void)?) throws -> \(callName) {")
  196. indent()
  197. println("return try \(callName)Base(channel)")
  198. indent()
  199. println(".start(request: request, metadata: metadata, completion: completion)")
  200. outdent()
  201. outdent()
  202. println("}")
  203. case .clientStreaming:
  204. println("/// Asynchronous. Client-streaming.")
  205. println("/// Use methods on the returned object to stream messages and")
  206. println("/// to close the connection and wait for a final response.")
  207. println("\(access) func \(methodFunctionName)(completion: ((CallResult) -> Void)?) throws -> \(callName) {")
  208. indent()
  209. println("return try \(callName)Base(channel)")
  210. indent()
  211. println(".start(metadata: metadata, completion: completion)")
  212. outdent()
  213. outdent()
  214. println("}")
  215. case .bidirectionalStreaming:
  216. println("/// Asynchronous. Bidirectional-streaming.")
  217. println("/// Use methods on the returned object to stream messages,")
  218. println("/// to wait for replies, and to close the connection.")
  219. println("\(access) func \(methodFunctionName)(completion: ((CallResult) -> Void)?) throws -> \(callName) {")
  220. indent()
  221. println("return try \(callName)Base(channel)")
  222. indent()
  223. println(".start(metadata: metadata, completion: completion)")
  224. outdent()
  225. outdent()
  226. println("}")
  227. }
  228. println()
  229. }
  230. outdent()
  231. println("}")
  232. }
  233. private func printServiceClientTestStubs() {
  234. println("class \(serviceClassName)TestStub: ServiceClientTestStubBase, \(serviceClassName) {")
  235. indent()
  236. for method in service.methods {
  237. self.method = method
  238. switch streamingType(method) {
  239. case .unary:
  240. println("var \(methodFunctionName)Requests: [\(methodInputName)] = []")
  241. println("var \(methodFunctionName)Responses: [\(methodOutputName)] = []")
  242. println("func \(methodFunctionName)(_ request: \(methodInputName)) throws -> \(methodOutputName) {")
  243. indent()
  244. println("\(methodFunctionName)Requests.append(request)")
  245. println("defer { \(methodFunctionName)Responses.removeFirst() }")
  246. println("return \(methodFunctionName)Responses.first!")
  247. outdent()
  248. println("}")
  249. println("func \(methodFunctionName)(_ request: \(methodInputName), completion: @escaping (\(methodOutputName)?, CallResult) -> Void) throws -> \(callName) {")
  250. indent()
  251. println("fatalError(\"not implemented\")")
  252. outdent()
  253. println("}")
  254. case .serverStreaming:
  255. println("var \(methodFunctionName)Requests: [\(methodInputName)] = []")
  256. println("var \(methodFunctionName)Calls: [\(callName)] = []")
  257. println("func \(methodFunctionName)(_ request: \(methodInputName), completion: ((CallResult) -> Void)?) throws -> \(callName) {")
  258. indent()
  259. println("\(methodFunctionName)Requests.append(request)")
  260. println("defer { \(methodFunctionName)Calls.removeFirst() }")
  261. println("return \(methodFunctionName)Calls.first!")
  262. outdent()
  263. println("}")
  264. case .clientStreaming:
  265. println("var \(methodFunctionName)Calls: [\(callName)] = []")
  266. println("func \(methodFunctionName)(completion: ((CallResult) -> Void)?) throws -> \(callName) {")
  267. indent()
  268. println("defer { \(methodFunctionName)Calls.removeFirst() }")
  269. println("return \(methodFunctionName)Calls.first!")
  270. outdent()
  271. println("}")
  272. case .bidirectionalStreaming:
  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. }
  281. println()
  282. }
  283. outdent()
  284. println("}")
  285. }
  286. }