Generator-Server.swift 8.0 KB

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