Generator-Server.swift 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  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("\(access) protocol \(providerName) {")
  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")
  50. case .clientStreaming:
  51. println("func \(methodFunctionName)(session: \(methodSessionName)) throws")
  52. case .bidirectionalStreaming:
  53. println("func \(methodFunctionName)(session: \(methodSessionName)) throws")
  54. }
  55. }
  56. outdent()
  57. println("}")
  58. println()
  59. }
  60. private func printServerMainClass() {
  61. println("/// Main server for generated service")
  62. println("\(access) final class \(serverName): ServiceServer {")
  63. indent()
  64. println("private let provider: \(providerName)")
  65. println()
  66. println("\(access) init(address: String, provider: \(providerName)) {")
  67. indent()
  68. println("self.provider = provider")
  69. println("super.init(address: address)")
  70. outdent()
  71. println("}")
  72. println()
  73. println("\(access) init?(address: String, certificateURL: URL, keyURL: URL, provider: \(providerName)) {")
  74. indent()
  75. println("self.provider = provider")
  76. println("super.init(address: address, certificateURL: certificateURL, keyURL: keyURL)")
  77. outdent()
  78. println("}")
  79. println()
  80. println("\(access) init?(address: String, certificateString: String, keyString: String, provider: \(providerName)) {")
  81. indent()
  82. println("self.provider = provider")
  83. println("super.init(address: address, certificateString: certificateString, keyString: keyString)")
  84. outdent()
  85. println("}")
  86. println()
  87. println("/// Start the server.")
  88. println("\(access) override func handleMethod(_ method: String, handler: Handler, queue: DispatchQueue) throws -> Bool {")
  89. indent()
  90. println("let provider = self.provider")
  91. println("switch method {")
  92. for method in service.methods {
  93. self.method = method
  94. println("case \(methodPath):")
  95. indent()
  96. switch streamingType(method) {
  97. case .unary, .serverStreaming:
  98. println("try \(methodSessionName)Base(")
  99. indent()
  100. println("handler: handler,")
  101. println("providerBlock: { try provider.\(methodFunctionName)(request: $0, session: $1 as! \(methodSessionName)Base) })")
  102. indent()
  103. println(".run(queue: queue)")
  104. outdent()
  105. outdent()
  106. default:
  107. println("try \(methodSessionName)Base(")
  108. indent()
  109. println("handler: handler,")
  110. println("providerBlock: { try provider.\(methodFunctionName)(session: $0 as! \(methodSessionName)Base) })")
  111. indent()
  112. println(".run(queue: queue)")
  113. outdent()
  114. outdent()
  115. }
  116. println("return true")
  117. outdent()
  118. }
  119. println("default:")
  120. indent()
  121. println("return false")
  122. outdent()
  123. println("}")
  124. outdent()
  125. println("}")
  126. outdent()
  127. println("}")
  128. println()
  129. }
  130. private func printServerMethodUnary() {
  131. println("\(access) protocol \(methodSessionName): ServerSessionUnary {}")
  132. println()
  133. println("fileprivate final class \(methodSessionName)Base: ServerSessionUnaryBase<\(methodInputName), \(methodOutputName)>, \(methodSessionName) {}")
  134. if options.generateTestStubs {
  135. println()
  136. println("class \(methodSessionName)TestStub: ServerSessionUnaryTestStub, \(methodSessionName) {}")
  137. }
  138. }
  139. private func printServerMethodClientStreaming() {
  140. println("\(access) protocol \(methodSessionName): ServerSessionClientStreaming {")
  141. indent()
  142. println("/// Receive a message. Blocks until a message is received or the client closes the connection.")
  143. println("func receive() throws -> \(methodInputName)")
  144. println()
  145. println("/// Send a response and close the connection.")
  146. println("func sendAndClose(_ response: \(methodOutputName)) throws")
  147. outdent()
  148. println("}")
  149. println()
  150. println("fileprivate final class \(methodSessionName)Base: ServerSessionClientStreamingBase<\(methodInputName), \(methodOutputName)>, \(methodSessionName) {}")
  151. if options.generateTestStubs {
  152. println()
  153. println("class \(methodSessionName)TestStub: ServerSessionClientStreamingTestStub<\(methodInputName), \(methodOutputName)>, \(methodSessionName) {}")
  154. }
  155. }
  156. private func printServerMethodServerStreaming() {
  157. println("\(access) protocol \(methodSessionName): ServerSessionServerStreaming {")
  158. indent()
  159. println("/// Send a message. Nonblocking.")
  160. println("func send(_ response: \(methodOutputName), completion: ((Bool) -> Void)?) throws")
  161. outdent()
  162. println("}")
  163. println()
  164. println("fileprivate final class \(methodSessionName)Base: ServerSessionServerStreamingBase<\(methodInputName), \(methodOutputName)>, \(methodSessionName) {}")
  165. if options.generateTestStubs {
  166. println()
  167. println("class \(methodSessionName)TestStub: ServerSessionServerStreamingTestStub<\(methodOutputName)>, \(methodSessionName) {}")
  168. }
  169. }
  170. private func printServerMethodBidirectional() {
  171. println("\(access) protocol \(methodSessionName): ServerSessionBidirectionalStreaming {")
  172. indent()
  173. println("/// Receive a message. Blocks until a message is received or the client closes the connection.")
  174. println("func receive() throws -> \(methodInputName)")
  175. println()
  176. println("/// Send a message. Nonblocking.")
  177. println("func send(_ response: \(methodOutputName), completion: ((Bool) -> Void)?) throws")
  178. println()
  179. println("/// Close a connection. Blocks until the connection is closed.")
  180. println("func close() throws")
  181. outdent()
  182. println("}")
  183. println()
  184. println("fileprivate final class \(methodSessionName)Base: ServerSessionBidirectionalStreamingBase<\(methodInputName), \(methodOutputName)>, \(methodSessionName) {}")
  185. if options.generateTestStubs {
  186. println()
  187. println("class \(methodSessionName)TestStub: ServerSessionBidirectionalStreamingTestStub<\(methodInputName), \(methodOutputName)>, \(methodSessionName) {}")
  188. }
  189. }
  190. }