| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- /*
- * Copyright 2021, gRPC Authors All rights reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- import SwiftProtobuf
- import SwiftProtobufPluginLibrary
- // MARK: - Protocol
- extension Generator {
- internal func printServerProtocolAsyncAwait() {
- let sourceComments = self.service.protoSourceComments()
- if !sourceComments.isEmpty {
- // Source comments already have the leading '///'
- self.println(sourceComments, newline: false)
- self.println("///")
- }
- self.println("/// To implement a server, implement an object which conforms to this protocol.")
- self.printAvailabilityForAsyncAwait()
- self.withIndentation(
- "\(self.access) protocol \(self.asyncProviderName): CallHandlerProvider",
- braces: .curly
- ) {
- self.println("static var serviceDescriptor: GRPCServiceDescriptor { get }")
- self.println("var interceptors: \(self.serverInterceptorProtocolName)? { get }")
- for method in service.methods {
- self.method = method
- self.println()
- self.printRPCProtocolRequirement()
- }
- }
- }
- private func printRPCProtocolRequirement() {
- // Print any comments; skip the newline as source comments include them already.
- self.println(self.method.protoSourceComments(), newline: false)
- let arguments: [String]
- let returnType: String?
- switch streamingType(self.method) {
- case .unary:
- arguments = [
- "request: \(self.methodInputName)",
- "context: \(Types.serverContext)",
- ]
- returnType = self.methodOutputName
- case .clientStreaming:
- arguments = [
- "requestStream: \(Types.requestStream(of: self.methodInputName))",
- "context: \(Types.serverContext)",
- ]
- returnType = self.methodOutputName
- case .serverStreaming:
- arguments = [
- "request: \(self.methodInputName)",
- "responseStream: \(Types.responseStreamWriter(of: self.methodOutputName))",
- "context: \(Types.serverContext)",
- ]
- returnType = nil
- case .bidirectionalStreaming:
- arguments = [
- "requestStream: \(Types.requestStream(of: self.methodInputName))",
- "responseStream: \(Types.responseStreamWriter(of: self.methodOutputName))",
- "context: \(Types.serverContext)",
- ]
- returnType = nil
- }
- self.printFunction(
- name: self.methodFunctionName,
- arguments: arguments,
- returnType: returnType,
- sendable: true,
- async: true,
- throws: true,
- bodyBuilder: nil
- )
- }
- }
- // MARK: - Protocol Extension; RPC handling
- extension Generator {
- internal func printServerProtocolExtensionAsyncAwait() {
- // Default extension to provide the service name and routing for methods.
- self.printAvailabilityForAsyncAwait()
- self.withIndentation("extension \(self.asyncProviderName)", braces: .curly) {
- self.withIndentation(
- "\(self.access) static var serviceDescriptor: GRPCServiceDescriptor",
- braces: .curly
- ) {
- self.println("return \(self.serviceServerMetadata).serviceDescriptor")
- }
- self.println()
- // This fulfils a requirement from 'CallHandlerProvider'
- self.withIndentation("\(self.access) var serviceName: Substring", braces: .curly) {
- /// This API returns a Substring (hence the '[...]')
- self.println("return \(self.serviceServerMetadata).serviceDescriptor.fullName[...]")
- }
- self.println()
- // Default nil interceptor factory.
- self.withIndentation(
- "\(self.access) var interceptors: \(self.serverInterceptorProtocolName)?",
- braces: .curly
- ) {
- self.println("return nil")
- }
- self.println()
- self.printFunction(
- name: "handle",
- arguments: [
- "method name: Substring",
- "context: CallHandlerContext",
- ],
- returnType: "GRPCServerHandlerProtocol?",
- access: self.access
- ) {
- self.println("switch name {")
- for method in self.service.methods {
- self.method = method
- let requestType = self.methodInputName
- let responseType = self.methodOutputName
- let interceptorFactory = self.methodInterceptorFactoryName
- let functionName = self.methodFunctionName
- self.withIndentation("case \"\(self.method.name)\":", braces: .none) {
- self.withIndentation("return \(Types.serverHandler)", braces: .round) {
- self.println("context: context,")
- self.println("requestDeserializer: \(Types.deserializer(for: requestType))(),")
- self.println("responseSerializer: \(Types.serializer(for: responseType))(),")
- self.println("interceptors: self.interceptors?.\(interceptorFactory)() ?? [],")
- switch streamingType(self.method) {
- case .unary:
- self.println("wrapping: self.\(functionName)(request:context:)")
- case .clientStreaming:
- self.println("wrapping: self.\(functionName)(requestStream:context:)")
- case .serverStreaming:
- self.println("wrapping: self.\(functionName)(request:responseStream:context:)")
- case .bidirectionalStreaming:
- self.println(
- "wrapping: self.\(functionName)(requestStream:responseStream:context:)"
- )
- }
- }
- }
- }
- // Default case.
- self.println("default:")
- self.withIndentation {
- self.println("return nil")
- }
- self.println("}") // switch
- }
- }
- }
- }
|