Generator-Server.swift 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  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 printServer() {
  21. printServerProtocol()
  22. for method in service.methods {
  23. self.method = method
  24. switch streamingType(method) {
  25. case .unary:
  26. printServerMethodUnary()
  27. case .clientStreaming:
  28. printServerMethodClientStreaming()
  29. case .serverStreaming:
  30. printServerMethodServerStreaming()
  31. case .bidirectionalStreaming:
  32. printServerMethodBidirectional()
  33. }
  34. println()
  35. }
  36. println()
  37. printServerMainClass()
  38. }
  39. private func printServerProtocol() {
  40. println("/// To build a server, implement a class that conforms to this protocol.")
  41. println("/// If one of the methods returning `ServerStatus?` returns nil,")
  42. println("/// it is expected that you have already returned a status to the client by means of `session.close`.")
  43. println("\(access) protocol \(providerName) {")
  44. indent()
  45. for method in service.methods {
  46. self.method = method
  47. switch streamingType(method) {
  48. case .unary:
  49. println("func \(methodFunctionName)(request: \(methodInputName), session: \(methodSessionName)) throws -> \(methodOutputName)")
  50. case .serverStreaming:
  51. println("func \(methodFunctionName)(request: \(methodInputName), session: \(methodSessionName)) throws -> ServerStatus?")
  52. case .clientStreaming:
  53. println("func \(methodFunctionName)(session: \(methodSessionName)) throws -> \(methodOutputName)?")
  54. case .bidirectionalStreaming:
  55. println("func \(methodFunctionName)(session: \(methodSessionName)) throws -> ServerStatus?")
  56. }
  57. }
  58. outdent()
  59. println("}")
  60. println()
  61. }
  62. private func printServerMainClass() {
  63. println("/// Main server for generated service")
  64. println("\(access) final class \(serverName): ServiceServer {")
  65. indent()
  66. println("private let provider: \(providerName)")
  67. println()
  68. println("\(access) init(address: String, provider: \(providerName)) {")
  69. indent()
  70. println("self.provider = provider")
  71. println("super.init(address: address)")
  72. outdent()
  73. println("}")
  74. println()
  75. println("\(access) init?(address: String, certificateURL: URL, keyURL: URL, rootCertsURL: URL? = nil, provider: \(providerName)) {")
  76. indent()
  77. println("self.provider = provider")
  78. println("super.init(address: address, certificateURL: certificateURL, keyURL: keyURL, rootCertsURL: rootCertsURL)")
  79. outdent()
  80. println("}")
  81. println()
  82. println("\(access) init?(address: String, certificateString: String, keyString: String, rootCerts: String? = nil, provider: \(providerName)) {")
  83. indent()
  84. println("self.provider = provider")
  85. println("super.init(address: address, certificateString: certificateString, keyString: keyString, rootCerts: rootCerts)")
  86. outdent()
  87. println("}")
  88. println()
  89. println("/// Determines and calls the appropriate request handler, depending on the request's method.")
  90. println("/// Throws `HandleMethodError.unknownMethod` for methods not handled by this service.")
  91. println("\(access) override func handleMethod(_ method: String, handler: Handler) throws -> ServerStatus? {")
  92. indent()
  93. println("let provider = self.provider")
  94. println("switch method {")
  95. for method in service.methods {
  96. self.method = method
  97. println("case \(methodPath):")
  98. indent()
  99. switch streamingType(method) {
  100. case .unary, .serverStreaming:
  101. println("return try \(methodSessionName)Base(")
  102. indent()
  103. println("handler: handler,")
  104. println("providerBlock: { try provider.\(methodFunctionName)(request: $0, session: $1 as! \(methodSessionName)Base) })")
  105. indent()
  106. println(".run()")
  107. outdent()
  108. outdent()
  109. default:
  110. println("return try \(methodSessionName)Base(")
  111. indent()
  112. println("handler: handler,")
  113. println("providerBlock: { try provider.\(methodFunctionName)(session: $0 as! \(methodSessionName)Base) })")
  114. indent()
  115. println(".run()")
  116. outdent()
  117. outdent()
  118. }
  119. outdent()
  120. }
  121. println("default:")
  122. indent()
  123. println("throw HandleMethodError.unknownMethod")
  124. outdent()
  125. println("}")
  126. outdent()
  127. println("}")
  128. outdent()
  129. println("}")
  130. println()
  131. }
  132. private func printServerMethodUnary() {
  133. println("\(access) protocol \(methodSessionName): ServerSessionUnary {}")
  134. println()
  135. println("fileprivate final class \(methodSessionName)Base: ServerSessionUnaryBase<\(methodInputName), \(methodOutputName)>, \(methodSessionName) {}")
  136. if options.generateTestStubs {
  137. println()
  138. println("class \(methodSessionName)TestStub: ServerSessionUnaryTestStub, \(methodSessionName) {}")
  139. }
  140. }
  141. private func printServerMethodSendAndClose(sentType: String) {
  142. println("/// Exactly one of these two methods should be called if and only if your request handler returns nil;")
  143. println("/// otherwise SwiftGRPC will take care of sending the response and status for you.")
  144. println("/// Close the connection and send a single result. Non-blocking.")
  145. println("func sendAndClose(response: \(sentType), status: ServerStatus, completion: (() -> Void)?) throws")
  146. println("/// Close the connection and send an error. Non-blocking.")
  147. println("/// Use this method if you encountered an error that makes it impossible to send a response.")
  148. println("/// Accordingly, it does not make sense to call this method with a status of `.ok`.")
  149. println("func sendErrorAndClose(status: ServerStatus, completion: (() -> Void)?) throws")
  150. }
  151. private func printServerMethodClientStreaming() {
  152. println("\(access) protocol \(methodSessionName): ServerSessionClientStreaming {")
  153. indent()
  154. printStreamReceiveMethods(receivedType: methodInputName)
  155. println()
  156. printServerMethodSendAndClose(sentType: methodOutputName)
  157. outdent()
  158. println("}")
  159. println()
  160. printStreamReceiveExtension(extendedType: methodSessionName, receivedType: methodInputName)
  161. println()
  162. println("fileprivate final class \(methodSessionName)Base: ServerSessionClientStreamingBase<\(methodInputName), \(methodOutputName)>, \(methodSessionName) {}")
  163. if options.generateTestStubs {
  164. println()
  165. println("class \(methodSessionName)TestStub: ServerSessionClientStreamingTestStub<\(methodInputName), \(methodOutputName)>, \(methodSessionName) {}")
  166. }
  167. }
  168. private func printServerMethodClose() {
  169. println("/// Close the connection and send the status. Non-blocking.")
  170. println("/// This method should be called if and only if your request handler returns a nil value instead of a server status;")
  171. println("/// otherwise SwiftGRPC will take care of sending the status for you.")
  172. println("func close(withStatus status: ServerStatus, completion: (() -> Void)?) throws")
  173. }
  174. private func printServerMethodServerStreaming() {
  175. println("\(access) protocol \(methodSessionName): ServerSessionServerStreaming {")
  176. indent()
  177. printStreamSendMethods(sentType: methodOutputName)
  178. println()
  179. printServerMethodClose()
  180. outdent()
  181. println("}")
  182. println()
  183. printStreamSendExtension(extendedType: methodSessionName, sentType: methodOutputName)
  184. println()
  185. println("fileprivate final class \(methodSessionName)Base: ServerSessionServerStreamingBase<\(methodInputName), \(methodOutputName)>, \(methodSessionName) {}")
  186. if options.generateTestStubs {
  187. println()
  188. println("class \(methodSessionName)TestStub: ServerSessionServerStreamingTestStub<\(methodOutputName)>, \(methodSessionName) {}")
  189. }
  190. }
  191. private func printServerMethodBidirectional() {
  192. println("\(access) protocol \(methodSessionName): ServerSessionBidirectionalStreaming {")
  193. indent()
  194. printStreamReceiveMethods(receivedType: methodInputName)
  195. println()
  196. printStreamSendMethods(sentType: methodOutputName)
  197. println()
  198. printServerMethodClose()
  199. outdent()
  200. println("}")
  201. println()
  202. printStreamReceiveExtension(extendedType: methodSessionName, receivedType: methodInputName)
  203. println()
  204. printStreamSendExtension(extendedType: methodSessionName, sentType: methodOutputName)
  205. println()
  206. println("fileprivate final class \(methodSessionName)Base: ServerSessionBidirectionalStreamingBase<\(methodInputName), \(methodOutputName)>, \(methodSessionName) {}")
  207. if options.generateTestStubs {
  208. println()
  209. println("class \(methodSessionName)TestStub: ServerSessionBidirectionalStreamingTestStub<\(methodInputName), \(methodOutputName)>, \(methodSessionName) {}")
  210. }
  211. }
  212. }