Generator-Server+AsyncAwait.swift 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. /*
  2. * Copyright 2021, 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 SwiftProtobuf
  17. import SwiftProtobufPluginLibrary
  18. // MARK: - Protocol
  19. extension Generator {
  20. internal func printServerProtocolAsyncAwait() {
  21. let sourceComments = self.service.protoSourceComments()
  22. if !sourceComments.isEmpty {
  23. // Source comments already have the leading '///'
  24. self.println(sourceComments, newline: false)
  25. self.println("///")
  26. }
  27. self.println("/// To implement a server, implement an object which conforms to this protocol.")
  28. self.printAvailabilityForAsyncAwait()
  29. self.withIndentation(
  30. "\(self.access) protocol \(self.asyncProviderName): CallHandlerProvider",
  31. braces: .curly
  32. ) {
  33. self.println("var interceptors: \(self.serverInterceptorProtocolName)? { get }")
  34. for method in service.methods {
  35. self.method = method
  36. self.println()
  37. self.printRPCProtocolRequirement()
  38. }
  39. }
  40. }
  41. fileprivate func printRPCProtocolRequirement() {
  42. // Print any comments; skip the newline as source comments include them already.
  43. self.println(self.method.protoSourceComments(), newline: false)
  44. let arguments: [String]
  45. let returnType: String?
  46. switch streamingType(self.method) {
  47. case .unary:
  48. arguments = [
  49. "request: \(self.methodInputName)",
  50. "context: \(Types.serverContext)",
  51. ]
  52. returnType = self.methodOutputName
  53. case .clientStreaming:
  54. arguments = [
  55. "requests: \(Types.requestStream(of: self.methodInputName))",
  56. "context: \(Types.serverContext)",
  57. ]
  58. returnType = self.methodOutputName
  59. case .serverStreaming:
  60. arguments = [
  61. "request: \(self.methodInputName)",
  62. "responseStream: \(Types.responseStreamWriter(of: self.methodOutputName))",
  63. "context: \(Types.serverContext)",
  64. ]
  65. returnType = nil
  66. case .bidirectionalStreaming:
  67. arguments = [
  68. "requests: \(Types.requestStream(of: self.methodInputName))",
  69. "responseStream: \(Types.responseStreamWriter(of: self.methodOutputName))",
  70. "context: \(Types.serverContext)",
  71. ]
  72. returnType = nil
  73. }
  74. self.printFunction(
  75. name: self.methodFunctionName,
  76. arguments: arguments,
  77. returnType: returnType,
  78. sendable: true,
  79. async: true,
  80. throws: true,
  81. bodyBuilder: nil
  82. )
  83. }
  84. }
  85. // MARK: - Protocol Extension; RPC handling
  86. extension Generator {
  87. internal func printServerProtocolExtensionAsyncAwait() {
  88. // Default extension to provide the service name and routing for methods.
  89. self.printAvailabilityForAsyncAwait()
  90. self.withIndentation("extension \(self.asyncProviderName)", braces: .curly) {
  91. self.withIndentation("\(self.access) var serviceName: Substring", braces: .curly) {
  92. self.println("return \"\(self.servicePath)\"")
  93. }
  94. self.println()
  95. // Default nil interceptor factory.
  96. self.withIndentation(
  97. "\(self.access) var interceptors: \(self.serverInterceptorProtocolName)?",
  98. braces: .curly
  99. ) {
  100. self.println("return nil")
  101. }
  102. self.println()
  103. self.printFunction(
  104. name: "handle",
  105. arguments: [
  106. "method name: Substring",
  107. "context: CallHandlerContext",
  108. ],
  109. returnType: "GRPCServerHandlerProtocol?",
  110. access: self.access
  111. ) {
  112. self.println("switch name {")
  113. for method in self.service.methods {
  114. self.method = method
  115. let requestType = self.methodInputName
  116. let responseType = self.methodOutputName
  117. let interceptorFactory = self.methodInterceptorFactoryName
  118. let functionName = self.methodFunctionName
  119. self.withIndentation("case \"\(self.method.name)\":", braces: .none) {
  120. self.withIndentation("return \(Types.serverHandler)", braces: .round) {
  121. self.println("context: context,")
  122. self.println("requestDeserializer: \(Types.deserializer(for: requestType))(),")
  123. self.println("responseSerializer: \(Types.serializer(for: responseType))(),")
  124. self.println("interceptors: self.interceptors?.\(interceptorFactory)() ?? [],")
  125. switch streamingType(self.method) {
  126. case .unary:
  127. self.println("wrapping: self.\(functionName)(request:context:)")
  128. case .clientStreaming:
  129. self.println("wrapping: self.\(functionName)(requests:context:)")
  130. case .serverStreaming:
  131. self.println("wrapping: self.\(functionName)(request:responseStream:context:)")
  132. case .bidirectionalStreaming:
  133. self.println("wrapping: self.\(functionName)(requests:responseStream:context:)")
  134. }
  135. }
  136. }
  137. }
  138. // Default case.
  139. self.println("default:")
  140. self.withIndentation {
  141. self.println("return nil")
  142. }
  143. self.println("}") // switch
  144. }
  145. }
  146. }
  147. }