From d22b5962e329b0d3573a085362a6040e779e02f4 Mon Sep 17 00:00:00 2001 From: Mustii <26250654+mustiikhalil@users.noreply.github.com> Date: Wed, 25 Mar 2026 22:03:52 +0100 Subject: [PATCH 1/2] Migrate to swift 6.0 & swift-gRPC 2.0 The following migrates to swift 6.0, and also migrate to swift-grpc 2.0 that uses swift-nio under the hood to provide nicer API and async await Adds sendable to enum & update @_implementationOnly imports to use internal imports --- .github/workflows/build.yml | 2 +- Package.swift | 32 +- grpc/examples/greeter_v2.fbs | 16 + grpc/examples/swift/Greeter/Package.swift | 54 +- .../Greeter/Sources/Commands/Commands.swift | 28 + .../Commands/Services/GreeterService.swift | 121 ++ .../Commands/Subcommands/ClientCommand.swift | 140 +++ .../Commands/Subcommands/ServerCommand.swift | 39 + .../Greeter/Sources/Model/greeter.grpc.swift | 147 --- .../Sources/Models/greeter_v2.grpc.swift | 572 +++++++++ .../greeter_v2_generated.swift} | 18 +- .../swift/Greeter/Sources/client/main.swift | 108 -- .../swift/Greeter/Sources/server/main.swift | 97 -- grpc/src/compiler/swift_generator.cc | 1114 ++++++++++++----- samples/monster_generated.swift | 4 +- scripts/generate_grpc_examples.py | 5 +- src/idl_gen_swift.cpp | 7 +- swift/Sources/FlatBuffers/ByteBuffer.swift | 4 +- swift/Sources/FlatBuffers/Enum.swift | 2 +- .../FlatBuffers/FlatBufferBuilder.swift | 4 +- .../FlatBuffers/FlatBufferObject.swift | 4 + swift/Sources/FlatBuffers/Message.swift | 91 +- swift/Sources/FlatBuffers/TableVerifier.swift | 2 +- .../Vectors/FlatbufferVector.swift | 2 +- .../Vectors/UnionFlatbufferVector.swift | 4 +- .../FlatBuffers/_InternalByteBuffer.swift | 2 +- swift/Sources/FlexBuffers/ByteBuffer.swift | 2 +- .../Sources/FlexBuffers/FlexBufferType.swift | 2 +- .../Sources/FlexBuffers/Utils/BitWidth.swift | 2 +- swift/Sources/FlexBuffers/Utils/Value.swift | 4 +- .../Writer/FlexBuffersWriter.swift | 3 + .../Tests/Flatbuffers/ByteBufferTests.swift | 6 +- .../Flatbuffers/FlatBuffersArraysTests.swift | 2 +- .../FlatBuffersMonsterWriterTests.swift | 6 +- .../Flatbuffers/MutatingBool_generated.swift | 2 +- .../Flatbuffers/arrays_test_generated.swift | 2 +- .../Flatbuffers/empty_vtable_generated.swift | 2 +- .../Tests/Flatbuffers/monster_test.grpc.swift | 690 +++++++--- .../Flatbuffers/monster_test_generated.swift | 14 +- .../Flatbuffers/more_defaults_generated.swift | 2 +- .../Flatbuffers/nan_inf_test_generated.swift | 2 +- .../optional_scalars_generated.swift | 2 +- .../Flatbuffers/union_vector_generated.swift | 6 +- .../vector_has_test_generated.swift | 2 +- .../Flexbuffers/FlexBuffersReaderTests.swift | 3 +- .../monster_test_generated.swift | 14 +- .../test_import_generated.swift | 6 +- .../test_no_include_generated.swift | 4 +- 48 files changed, 2464 insertions(+), 933 deletions(-) create mode 100644 grpc/examples/greeter_v2.fbs create mode 100644 grpc/examples/swift/Greeter/Sources/Commands/Commands.swift create mode 100644 grpc/examples/swift/Greeter/Sources/Commands/Services/GreeterService.swift create mode 100644 grpc/examples/swift/Greeter/Sources/Commands/Subcommands/ClientCommand.swift create mode 100644 grpc/examples/swift/Greeter/Sources/Commands/Subcommands/ServerCommand.swift delete mode 100644 grpc/examples/swift/Greeter/Sources/Model/greeter.grpc.swift create mode 100644 grpc/examples/swift/Greeter/Sources/Models/greeter_v2.grpc.swift rename grpc/examples/swift/Greeter/Sources/{Model/greeter_generated.swift => Models/greeter_v2_generated.swift} (81%) delete mode 100644 grpc/examples/swift/Greeter/Sources/client/main.swift delete mode 100644 grpc/examples/swift/Greeter/Sources/server/main.swift diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c7cae714c7..a5a6bab3d8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -495,7 +495,7 @@ jobs: name: Test Swift Linux strategy: matrix: - swift: ["5.10", "6.1", "6.2"] + swift: ["6.0", "6.1", "6.2"] runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v6 diff --git a/Package.swift b/Package.swift index 4f60a8c745..413990384f 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.10 +// swift-tools-version:6.0 /* * Copyright 2020 Google Inc. All rights reserved. * @@ -36,14 +36,17 @@ let package = Package( .target( name: "FlatBuffers", dependencies: ["Common"], - path: "swift/Sources/FlatBuffers"), + path: "swift/Sources/FlatBuffers", + swiftSettings: .settings), .target( name: "FlexBuffers", dependencies: ["Common"], - path: "swift/Sources/FlexBuffers"), + path: "swift/Sources/FlexBuffers", + swiftSettings: .settings), .target( name: "Common", - path: "swift/Sources/Common"), + path: "swift/Sources/Common", + swiftSettings: .settings), .testTarget( name: "FlatbuffersTests", dependencies: .dependencies, @@ -52,7 +55,14 @@ let package = Package( name: "FlexbuffersTests", dependencies: ["FlexBuffers"], path: "tests/swift/Tests/Flexbuffers"), - ]) + ], + swiftLanguageModes: [.v6]) + +extension Array where Element == SwiftSetting { + static var settings: [SwiftSetting] { + [.enableUpcomingFeature("ExistentialAny")] + } +} extension Array where Element == Package.Dependency { static var dependencies: [Package.Dependency] { @@ -60,7 +70,12 @@ extension Array where Element == Package.Dependency { [] #else // Test only Dependency - [.package(url: "https://github.com/grpc/grpc-swift.git", from: "1.4.1")] + [ + .package(url: "https://github.com/grpc/grpc-swift-2.git", from: "2.0.0"), + .package( + url: "https://github.com/grpc/grpc-swift-nio-transport.git", + from: "2.0.0"), + ] #endif } } @@ -72,7 +87,10 @@ extension Array where Element == PackageDescription.Target.Dependency { #else // Test only Dependency [ - .product(name: "GRPC", package: "grpc-swift"), + .product(name: "GRPCCore", package: "grpc-swift-2"), + .product( + name: "GRPCNIOTransportHTTP2", + package: "grpc-swift-nio-transport"), "FlatBuffers", ] #endif diff --git a/grpc/examples/greeter_v2.fbs b/grpc/examples/greeter_v2.fbs new file mode 100644 index 0000000000..483abcc49f --- /dev/null +++ b/grpc/examples/greeter_v2.fbs @@ -0,0 +1,16 @@ +namespace models; + +table HelloResponse { + message:string; +} + +table HelloRequest { + name:string; +} + +rpc_service Greeter { + Get(HelloRequest):HelloResponse; + Collect(HelloRequest):HelloResponse (streaming: "client"); + Expand(HelloRequest):HelloResponse (streaming: "server"); + Update(HelloRequest):HelloResponse (streaming: "bidi"); +} diff --git a/grpc/examples/swift/Greeter/Package.swift b/grpc/examples/swift/Greeter/Package.swift index 664f2a0cd2..3fc96adc79 100644 --- a/grpc/examples/swift/Greeter/Package.swift +++ b/grpc/examples/swift/Greeter/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:5.10 +// swift-tools-version:6.2 /* * Copyright 2020 Google Inc. All rights reserved. * @@ -20,39 +20,43 @@ import PackageDescription let package = Package( name: "Greeter", platforms: [ - .iOS(.v12), - .macOS(.v10_14), + .iOS(.v18), + .macOS(.v15), ], dependencies: [ - .package(path: "../../../../swift"), - .package(url: "https://github.com/grpc/grpc-swift.git", from: "1.0.0"), + .package(path: "../../../.."), + .package(url: "https://github.com/grpc/grpc-swift-2.git", from: "2.0.0"), + .package( + url: "https://github.com/grpc/grpc-swift-nio-transport.git", + from: "2.0.0"), + .package( + url: "https://github.com/apple/swift-argument-parser.git", + from: "1.5.0"), ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. // Targets can depend on other targets in this package, and on products in packages which this package depends on. .target( - name: "Model", + name: "Models", dependencies: [ - "GRPC", - "FlatBuffers", - ], - path: "Sources/Model"), + .product(name: "FlatBuffers", package: "flatbuffers"), + .product(name: "GRPCCore", package: "grpc-swift-2"), + .product( + name: "GRPCNIOTransportHTTP2", + package: "grpc-swift-nio-transport"), + ]), // Client for the Greeter example - .target( - name: "Client", - dependencies: [ - "GRPC", - "Model", - ], - path: "Sources/client"), - - // Server for the Greeter example - .target( - name: "Server", + .executableTarget( + name: "Commands", dependencies: [ - "GRPC", - "Model", - ], - path: "Sources/server"), + .product(name: "GRPCCore", package: "grpc-swift-2"), + .product( + name: "GRPCNIOTransportHTTP2", + package: "grpc-swift-nio-transport"), + .product( + name: "ArgumentParser", + package: "swift-argument-parser"), + "Models", + ]), ]) diff --git a/grpc/examples/swift/Greeter/Sources/Commands/Commands.swift b/grpc/examples/swift/Greeter/Sources/Commands/Commands.swift new file mode 100644 index 0000000000..50315b4e2e --- /dev/null +++ b/grpc/examples/swift/Greeter/Sources/Commands/Commands.swift @@ -0,0 +1,28 @@ +/* + * Copyright 2024 Google Inc. 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 ArgumentParser + +let port = 3000 + +@main +struct GreeterCommand: AsyncParsableCommand { + static let configuration = CommandConfiguration( + commandName: "greeter", + abstract: "A multi-tool to run an echo server and execute RPCs against it.", + subcommands: [ServerCommand.self, ClientCommand.self]) +} + diff --git a/grpc/examples/swift/Greeter/Sources/Commands/Services/GreeterService.swift b/grpc/examples/swift/Greeter/Sources/Commands/Services/GreeterService.swift new file mode 100644 index 0000000000..74b57c7377 --- /dev/null +++ b/grpc/examples/swift/Greeter/Sources/Commands/Services/GreeterService.swift @@ -0,0 +1,121 @@ +/* + * Copyright 2024 Google Inc. 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 FlatBuffers +import GRPCCore +import Models + +struct GreeterService: models_Greeter.SimpleServiceProtocol { + func Get( + request: GRPCMessage, + context: GRPCCore + .ServerContext) async throws -> GRPCMessage + { + let model = try request.decode() + print("## GreeterService.Get: \(model.message)") + + var builder = FlatBufferBuilder(initialSize: 128) + let off = builder.create(string: "Hello \(model.message ?? "Unknown")") + let root = models_HelloResponse.createHelloResponse( + &builder, + messageOffset: off) + builder.finish(offset: root) + return try GRPCMessage(builder: &builder) + } + + func Collect( + request: GRPCCore.RPCAsyncSequence< + GRPCMessage, + any Swift.Error + >, + context: GRPCCore + .ServerContext) async throws -> GRPCMessage + { + let messages: [String] = try await request + .reduce(into: []) { array, message in + let model = try message.decode() + return array.append(model.message ?? "Unknown") + } + + let joined = messages.joined(separator: ", ") + print("## GreeterService.Collect: \(joined)") + + var builder = FlatBufferBuilder(initialSize: 128) + let off = builder.create(string: "Hello \(joined)") + let root = models_HelloResponse.createHelloResponse( + &builder, + messageOffset: off) + builder.finish(offset: root) + return try GRPCMessage(builder: &builder) + } + + func Expand( + request: GRPCMessage, + response: GRPCCore.RPCWriter>, + context: GRPCCore.ServerContext) async throws + { + + let model = try request.decode() + print("## GreeterService.Expand: \(model.message)") + + let message = model.message ?? "Unknown" + let stream = AsyncThrowingStream< + GRPCMessage, + Error + > { continuation in + var builder = FlatBufferBuilder(initialSize: 128) + for char in message { + let off = builder.create(string: "\(char)") + let root = models_HelloResponse.createHelloResponse( + &builder, + messageOffset: off) + builder.finish(offset: root) + + do { + continuation + .yield(try GRPCMessage(builder: &builder)) + } catch { + continuation.finish(throwing: error) + } + } + + continuation.finish() + } + try await response.write(contentsOf: stream) + } + + func Update( + request: GRPCCore.RPCAsyncSequence< + GRPCMessage, + any Swift.Error + >, + response: GRPCCore.RPCWriter>, + context: GRPCCore.ServerContext) async throws + { + for try await message in request { + let model = try message.decode() + print("## GreeterService.Update: \(model.message)") + var builder = FlatBufferBuilder(initialSize: 128) + let off = builder.create(string: "Hello \(model.message ?? "Unknown")") + let root = models_HelloResponse.createHelloResponse( + &builder, + messageOffset: off) + builder.finish(offset: root) + try await response + .write(try GRPCMessage(builder: &builder)) + } + } +} diff --git a/grpc/examples/swift/Greeter/Sources/Commands/Subcommands/ClientCommand.swift b/grpc/examples/swift/Greeter/Sources/Commands/Subcommands/ClientCommand.swift new file mode 100644 index 0000000000..8f012f18f0 --- /dev/null +++ b/grpc/examples/swift/Greeter/Sources/Commands/Subcommands/ClientCommand.swift @@ -0,0 +1,140 @@ +/* + * Copyright 2024 Google Inc. 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 ArgumentParser +import FlatBuffers +import GRPCCore +import GRPCNIOTransportHTTP2 +import Models + +enum ClientRequest: String, ExpressibleByArgument { + case get, expand, collect, update +} + +struct ClientCommand: AsyncParsableCommand { + static let configuration = CommandConfiguration( + commandName: "client") + + @Option(help: "Name to send to the server") + var name: String + + @Option(help: "request type") + var request: ClientRequest + + func run() async throws { + try await withGRPCClient( + transport: .http2NIOPosix( + target: .dns(host: "localhost", port: port), + transportSecurity: .plaintext)) + { + let client = models_Greeter.Client(wrapping: $0) + + switch request { + case .get: try await get(client: client) + case .expand: try await expand(client: client) + case .collect: try await collect(client: client) + case .update: try await update(client: client) + } + } + } + + func get( + client: models_Greeter + .Client) async throws + { + for _ in 0..<3 { + var builder = FlatBufferBuilder(initialSize: 64) + let off = builder.create(string: name) + let root = models_HelloRequest.createHelloRequest( + &builder, + nameOffset: off) + builder.finish(offset: root) + + let response = try await client + .Get(GRPCMessage(builder: &builder)) + let message = try? response.decode().message + print("get message: \(message ?? "nil")") + } + } + + func expand( + client: models_Greeter + .Client) async throws + { + for _ in 0..<3 { + var builder = FlatBufferBuilder(initialSize: 64) + let off = builder.create(string: name) + let root = models_HelloRequest.createHelloRequest( + &builder, + nameOffset: off) + builder.finish(offset: root) + try await client.Expand(GRPCMessage(builder: &builder)) { response in + for try await message in response.messages { + let message = try? message.decode().message + print("expand message: \(message ?? "nil")") + } + } + } + } + + func collect( + client: models_Greeter + .Client) async throws + { + for _ in 0..<3 { + let response = try await client.Collect { writer in + for part in name { + print("collect sending: \(part)") + var builder = FlatBufferBuilder(initialSize: 64) + let off = builder.create(string: String(part)) + let root = models_HelloRequest.createHelloRequest( + &builder, + nameOffset: off) + builder.finish(offset: root) + try await writer.write(GRPCMessage(builder: &builder)) + } + } + + let message = try response.decode().message + print("collect message: \(message ?? "nil")") + } + } + + func update( + client: models_Greeter + .Client) async throws + { + for _ in 0..<3 { + try await client.Update { writer in + for part in name { + print("update sending: \(part)") + var builder = FlatBufferBuilder(initialSize: 64) + let off = builder.create(string: String(part)) + let root = models_HelloRequest.createHelloRequest( + &builder, + nameOffset: off) + builder.finish(offset: root) + try await writer.write(GRPCMessage(builder: &builder)) + } + } onResponse: { response in + for try await message in response.messages { + let message = try message.decode().message + print("collect message: \(message ?? "nil")") + } + } + } + } +} diff --git a/grpc/examples/swift/Greeter/Sources/Commands/Subcommands/ServerCommand.swift b/grpc/examples/swift/Greeter/Sources/Commands/Subcommands/ServerCommand.swift new file mode 100644 index 0000000000..b2121b11df --- /dev/null +++ b/grpc/examples/swift/Greeter/Sources/Commands/Subcommands/ServerCommand.swift @@ -0,0 +1,39 @@ +/* + * Copyright 2024 Google Inc. 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 ArgumentParser +import GRPCCore +import GRPCNIOTransportHTTP2 + +struct ServerCommand: AsyncParsableCommand { + static let configuration = CommandConfiguration( + commandName: "serve") + + func run() async throws { + let server = GRPCServer( + transport: .http2NIOPosix( + address: .ipv4(host: "127.0.0.1", port: port), + transportSecurity: .plaintext), + services: [GreeterService()]) + + try await withThrowingDiscardingTaskGroup { group in + group.addTask { try await server.serve() } + if let address = try await server.listeningAddress { + print("Echo listening on \(address)") + } + } + } +} diff --git a/grpc/examples/swift/Greeter/Sources/Model/greeter.grpc.swift b/grpc/examples/swift/Greeter/Sources/Model/greeter.grpc.swift deleted file mode 100644 index 700c5cd595..0000000000 --- a/grpc/examples/swift/Greeter/Sources/Model/greeter.grpc.swift +++ /dev/null @@ -1,147 +0,0 @@ -// Generated GRPC code for FlatBuffers swift! -/// The following code is generated by the Flatbuffers library which might not be in sync with grpc-swift -/// in case of an issue please open github issue, though it would be maintained - -// swiftlint:disable all -// swiftformat:disable all - -#if !os(Windows) -import Foundation -import GRPC -import NIO -import NIOHTTP1 -import FlatBuffers - -public protocol GRPCFlatBufPayload: GRPCPayload, FlatBufferGRPCMessage {} -public extension GRPCFlatBufPayload { - init(serializedByteBuffer: inout NIO.ByteBuffer) throws { - self.init(byteBuffer: FlatBuffers.ByteBuffer(contiguousBytes: serializedByteBuffer.readableBytesView, count: serializedByteBuffer.readableBytes)) - } - func serialize(into buffer: inout NIO.ByteBuffer) throws { - withUnsafeReadableBytes { buffer.writeBytes($0) } - } -} -extension Message: GRPCFlatBufPayload {} - -/// Usage: instantiate models_GreeterServiceClient, then call methods of this protocol to make API calls. -public protocol models_GreeterClientProtocol: GRPCClient { - - var serviceName: String { get } - - var interceptors: models_GreeterClientInterceptorFactoryProtocol? { get } - - func SayHello( - _ request: Message - , callOptions: CallOptions? - ) -> UnaryCall, Message> - - func SayManyHellos( - _ request: Message - , callOptions: CallOptions?, - handler: @escaping (Message) -> Void - ) -> ServerStreamingCall, Message> - -} - -extension models_GreeterClientProtocol { - - public var serviceName: String { "models.Greeter" } - - public func SayHello( - _ request: Message - , callOptions: CallOptions? = nil - ) -> UnaryCall, Message> { - return self.makeUnaryCall( - path: "/models.Greeter/SayHello", - request: request, - callOptions: callOptions ?? self.defaultCallOptions, - interceptors: self.interceptors?.makeSayHelloInterceptors() ?? [] - ) - } - - public func SayManyHellos( - _ request: Message - , callOptions: CallOptions? = nil, - handler: @escaping (Message) -> Void - ) -> ServerStreamingCall, Message> { - return self.makeServerStreamingCall( - path: "/models.Greeter/SayManyHellos", - request: request, - callOptions: callOptions ?? self.defaultCallOptions, - interceptors: self.interceptors?.makeSayManyHellosInterceptors() ?? [], - handler: handler - ) - } -} - -public protocol models_GreeterClientInterceptorFactoryProtocol { - /// - Returns: Interceptors to use when invoking 'SayHello'. - func makeSayHelloInterceptors() -> [ClientInterceptor, Message>] - - /// - Returns: Interceptors to use when invoking 'SayManyHellos'. - func makeSayManyHellosInterceptors() -> [ClientInterceptor, Message>] - -} - -public final class models_GreeterServiceClient: models_GreeterClientProtocol { - public let channel: GRPCChannel - public var defaultCallOptions: CallOptions - public var interceptors: models_GreeterClientInterceptorFactoryProtocol? - - public init( - channel: GRPCChannel, - defaultCallOptions: CallOptions = CallOptions(), - interceptors: models_GreeterClientInterceptorFactoryProtocol? = nil - ) { - self.channel = channel - self.defaultCallOptions = defaultCallOptions - self.interceptors = interceptors - } -} - -public protocol models_GreeterProvider: CallHandlerProvider { - var interceptors: models_GreeterServerInterceptorFactoryProtocol? { get } - func SayHello(request: Message, context: StatusOnlyCallContext) -> EventLoopFuture> - func SayManyHellos(request: Message, context: StreamingResponseCallContext>) -> EventLoopFuture -} - -public extension models_GreeterProvider { - - var serviceName: Substring { return "models.Greeter" } - - func handle(method name: Substring, context: CallHandlerContext) -> GRPCServerHandlerProtocol? { - switch name { - case "SayHello": - return UnaryServerHandler( - context: context, - requestDeserializer: GRPCPayloadDeserializer>(), - responseSerializer: GRPCPayloadSerializer>(), - interceptors: self.interceptors?.makeSayHelloInterceptors() ?? [], - userFunction: self.SayHello(request:context:)) - - case "SayManyHellos": - return ServerStreamingServerHandler( - context: context, - requestDeserializer: GRPCPayloadDeserializer>(), - responseSerializer: GRPCPayloadSerializer>(), - interceptors: self.interceptors?.makeSayManyHellosInterceptors() ?? [], - userFunction: self.SayManyHellos(request:context:)) - - default: return nil; - } - } - -} - -public protocol models_GreeterServerInterceptorFactoryProtocol { - /// - Returns: Interceptors to use when handling 'SayHello'. - /// Defaults to calling `self.makeInterceptors()`. - func makeSayHelloInterceptors() -> [ServerInterceptor, Message>] - - /// - Returns: Interceptors to use when handling 'SayManyHellos'. - /// Defaults to calling `self.makeInterceptors()`. - func makeSayManyHellosInterceptors() -> [ServerInterceptor, Message>] - -} -#endif - diff --git a/grpc/examples/swift/Greeter/Sources/Models/greeter_v2.grpc.swift b/grpc/examples/swift/Greeter/Sources/Models/greeter_v2.grpc.swift new file mode 100644 index 0000000000..d8e1dbb612 --- /dev/null +++ b/grpc/examples/swift/Greeter/Sources/Models/greeter_v2.grpc.swift @@ -0,0 +1,572 @@ +// Generated GRPC code for FlatBuffers swift! +/// The following code is generated by the Flatbuffers library which might not be in sync with grpc-swift +/// in case of an issue please open github issue, though it would be maintained + +// swiftlint:disable all +// swiftformat:disable all + +#if !os(Windows) && compiler(>=6.0) +import FlatBuffers +import Foundation +import GRPCCore +import GRPCNIOTransportCore + + +/// Usage: instantiate models.GreeterServiceClient, then call methods of this protocol to make API calls. +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension FlatBuffersMessageSerializer: MessageSerializer { + public func serialize(_ message: Message) throws -> Bytes where Bytes : GRPCCore.GRPCContiguousBytes { + do { + return try self.serialize(message: message) { GRPCNIOTransportBytes($0) } as! Bytes + } catch let error { + throw RPCError( + code: .invalidArgument, + message: "Can't serialize message", + cause: error + ) + } + } +} + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension FlatBuffersMessageDeserializer: MessageDeserializer { + public func deserialize(_ serializedMessageBytes: Bytes) throws -> Message where Bytes : GRPCCore.GRPCContiguousBytes { + do { + return try serializedMessageBytes.withUnsafeBytes { + try self.deserialize(pointer: $0) + } + } catch let error { + throw RPCError( + code: .invalidArgument, + message: "Can't Decode message of type \(Message.self)", + cause: error + ) + } + } +} + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +public enum models_Greeter: Sendable { + public static let descriptor = GRPCCore.ServiceDescriptor(fullyQualifiedService: "models.Greeter") + public enum Method: Sendable { + public enum Get: Sendable { + public typealias Input = FlatBufferBuilder + public typealias Output = models_HelloResponse + public static let descriptor = GRPCCore.MethodDescriptor( + service: GRPCCore.ServiceDescriptor(fullyQualifiedService: "models.Greeter"), + method: "Get" + ) + } + public enum Collect: Sendable { + public typealias Input = FlatBufferBuilder + public typealias Output = models_HelloResponse + public static let descriptor = GRPCCore.MethodDescriptor( + service: GRPCCore.ServiceDescriptor(fullyQualifiedService: "models.Greeter"), + method: "Collect" + ) + } + public enum Expand: Sendable { + public typealias Input = FlatBufferBuilder + public typealias Output = models_HelloResponse + public static let descriptor = GRPCCore.MethodDescriptor( + service: GRPCCore.ServiceDescriptor(fullyQualifiedService: "models.Greeter"), + method: "Expand" + ) + } + public enum Update: Sendable { + public typealias Input = FlatBufferBuilder + public typealias Output = models_HelloResponse + public static let descriptor = GRPCCore.MethodDescriptor( + service: GRPCCore.ServiceDescriptor(fullyQualifiedService: "models.Greeter"), + method: "Update" + ) + } + public static let descriptors: [GRPCCore.MethodDescriptor] = [ + Get.descriptor, + Collect.descriptor, + Expand.descriptor, + Update.descriptor, + ] + } +} + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension GRPCCore.ServiceDescriptor { + public static let models_Greeter = GRPCCore.ServiceDescriptor(fullyQualifiedService: "models.Greeter") +} + +// MARK: models.Greeter Server + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension models_Greeter { + public protocol StreamingServiceProtocol: GRPCCore.RegistrableRPCService { + func Get( + request: GRPCCore.StreamingServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse> + + func Collect( + request: GRPCCore.StreamingServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse> + + func Expand( + request: GRPCCore.StreamingServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse> + + func Update( + request: GRPCCore.StreamingServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse> + + } + + public protocol ServiceProtocol: models_Greeter.StreamingServiceProtocol { + func Get( + request: GRPCCore.ServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.ServerResponse> + + func Collect( + request: GRPCCore.StreamingServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.ServerResponse> + + func Expand( + request: GRPCCore.ServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse> + + func Update( + request: GRPCCore.StreamingServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse> + + } + + public protocol SimpleServiceProtocol: models_Greeter.ServiceProtocol { + func Get( + request: GRPCMessage, + context: GRPCCore.ServerContext + ) async throws -> GRPCMessage + + func Collect( + request: GRPCCore.RPCAsyncSequence, any Swift.Error>, + context: GRPCCore.ServerContext + ) async throws -> GRPCMessage + + func Expand( + request: GRPCMessage, + response: GRPCCore.RPCWriter>, + context: GRPCCore.ServerContext + ) async throws + + func Update( + request: GRPCCore.RPCAsyncSequence, any Swift.Error>, + response: GRPCCore.RPCWriter>, + context: GRPCCore.ServerContext + ) async throws + + } +} + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension models_Greeter.StreamingServiceProtocol { + public func registerMethods(with router: inout GRPCCore.RPCRouter) where Transport: GRPCCore.ServerTransport { + router.registerHandler( + forMethod: models_Greeter.Method.Get.descriptor, + deserializer: FlatBuffersMessageDeserializer>(), + serializer: FlatBuffersMessageSerializer>(), + handler: { request, context in + try await self.Get( + request: request, + context: context + ) + } + ) + router.registerHandler( + forMethod: models_Greeter.Method.Collect.descriptor, + deserializer: FlatBuffersMessageDeserializer>(), + serializer: FlatBuffersMessageSerializer>(), + handler: { request, context in + try await self.Collect( + request: request, + context: context + ) + } + ) + router.registerHandler( + forMethod: models_Greeter.Method.Expand.descriptor, + deserializer: FlatBuffersMessageDeserializer>(), + serializer: FlatBuffersMessageSerializer>(), + handler: { request, context in + try await self.Expand( + request: request, + context: context + ) + } + ) + router.registerHandler( + forMethod: models_Greeter.Method.Update.descriptor, + deserializer: FlatBuffersMessageDeserializer>(), + serializer: FlatBuffersMessageSerializer>(), + handler: { request, context in + try await self.Update( + request: request, + context: context + ) + } + ) + } +} + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension models_Greeter.ServiceProtocol { + public func Get( + request: GRPCCore.StreamingServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse> { + let response = try await self.Get( + request: GRPCCore.ServerRequest(stream: request), + context: context + ) + return GRPCCore.StreamingServerResponse(single: response) + } + public func Collect( + request: GRPCCore.StreamingServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse> { + let response = try await self.Collect( + request: request, + context: context + ) + return GRPCCore.StreamingServerResponse(single: response) + } + public func Expand( + request: GRPCCore.StreamingServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse> { + let response = try await self.Expand( + request: GRPCCore.ServerRequest(stream: request), + context: context + ) + return response + } +} + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension models_Greeter.SimpleServiceProtocol { + public func Get( + request: GRPCCore.ServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.ServerResponse> { + return GRPCCore.ServerResponse>( + message: try await self.Get( + request: request.message, + context: context + ), + metadata: [:] + ) + } + public func Collect( + request: GRPCCore.StreamingServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.ServerResponse> { + return GRPCCore.ServerResponse>( + message: try await self.Collect( + request: request.messages, + context: context + ), + metadata: [:] + ) + } + public func Expand( + request: GRPCCore.ServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse> { + return GRPCCore.StreamingServerResponse>( + metadata: [:], + producer: { writer in + try await self.Expand( + request: request.message, + response: writer, + context: context + ) + return [:] + } + ) + } + public func Update( + request: GRPCCore.StreamingServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse> { + return GRPCCore.StreamingServerResponse>( + metadata: [:], + producer: { writer in + try await self.Update( + request: request.messages, + response: writer, + context: context + ) + return [:] + } + ) + } +} + + +// MARK: models.Greeter Client + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension models_Greeter { + public protocol ClientProtocol: Sendable { + func Get( + request: GRPCCore.ClientRequest>, + serializer: some GRPCCore.MessageSerializer>, + deserializer: some GRPCCore.MessageDeserializer>, + options: GRPCCore.CallOptions, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse>) async throws -> Result + ) async throws -> Result where Result: Sendable + + func Collect( + request: GRPCCore.StreamingClientRequest>, + serializer: some GRPCCore.MessageSerializer>, + deserializer: some GRPCCore.MessageDeserializer>, + options: GRPCCore.CallOptions, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse>) async throws -> Result + ) async throws -> Result where Result: Sendable + + func Expand( + request: GRPCCore.ClientRequest>, + serializer: some GRPCCore.MessageSerializer>, + deserializer: some GRPCCore.MessageDeserializer>, + options: GRPCCore.CallOptions, + onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse>) async throws -> Result + ) async throws -> Result where Result: Sendable + + func Update( + request: GRPCCore.StreamingClientRequest>, + serializer: some GRPCCore.MessageSerializer>, + deserializer: some GRPCCore.MessageDeserializer>, + options: GRPCCore.CallOptions, + onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse>) async throws -> Result + ) async throws -> Result where Result: Sendable + + } +} + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension models_Greeter { + public struct Client: ClientProtocol where Transport: GRPCCore.ClientTransport { + private let client: GRPCCore.GRPCClient + + public init(wrapping client: GRPCCore.GRPCClient) { + self.client = client + } + + public func Get( + request: GRPCCore.ClientRequest>, + serializer: some GRPCCore.MessageSerializer>, + deserializer: some GRPCCore.MessageDeserializer>, + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse>) async throws -> Result = { response in try response.message } + ) async throws -> Result where Result: Sendable { + try await self.client.unary( + request: request, + descriptor: models_Greeter.Method.Get.descriptor, + serializer: serializer, + deserializer: deserializer, + options: options, + onResponse: handleResponse + ) + } + + public func Collect( + request: GRPCCore.StreamingClientRequest>, + serializer: some GRPCCore.MessageSerializer>, + deserializer: some GRPCCore.MessageDeserializer>, + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse>) async throws -> Result = { response in try response.message } + ) async throws -> Result where Result: Sendable { + try await self.client.clientStreaming( + request: request, + descriptor: models_Greeter.Method.Collect.descriptor, + serializer: serializer, + deserializer: deserializer, + options: options, + onResponse: handleResponse + ) + } + + public func Expand( + request: GRPCCore.ClientRequest>, + serializer: some GRPCCore.MessageSerializer>, + deserializer: some GRPCCore.MessageDeserializer>, + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse>) async throws -> Result + ) async throws -> Result where Result: Sendable { + try await self.client.serverStreaming( + request: request, + descriptor: models_Greeter.Method.Expand.descriptor, + serializer: serializer, + deserializer: deserializer, + options: options, + onResponse: handleResponse + ) + } + + public func Update( + request: GRPCCore.StreamingClientRequest>, + serializer: some GRPCCore.MessageSerializer>, + deserializer: some GRPCCore.MessageDeserializer>, + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse>) async throws -> Result + ) async throws -> Result where Result: Sendable { + try await self.client.bidirectionalStreaming( + request: request, + descriptor: models_Greeter.Method.Update.descriptor, + serializer: serializer, + deserializer: deserializer, + options: options, + onResponse: handleResponse + ) + } + + } +} + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension models_Greeter.ClientProtocol { + public func Get( + request: GRPCCore.ClientRequest>, + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse>) async throws -> Result = { response in try response.message } + ) async throws -> Result where Result: Sendable { + try await self.Get( + request: request, + serializer: FlatBuffersMessageSerializer>(), + deserializer: FlatBuffersMessageDeserializer>(), + options: options, + onResponse: handleResponse + ) + } + + public func Collect( + request: GRPCCore.StreamingClientRequest>, + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse>) async throws -> Result = { response in try response.message } + ) async throws -> Result where Result: Sendable { + try await self.Collect( + request: request, + serializer: FlatBuffersMessageSerializer>(), + deserializer: FlatBuffersMessageDeserializer>(), + options: options, + onResponse: handleResponse + ) + } + + public func Expand( + request: GRPCCore.ClientRequest>, + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse>) async throws -> Result + ) async throws -> Result where Result: Sendable { + try await self.Expand( + request: request, + serializer: FlatBuffersMessageSerializer>(), + deserializer: FlatBuffersMessageDeserializer>(), + options: options, + onResponse: handleResponse + ) + } + + public func Update( + request: GRPCCore.StreamingClientRequest>, + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse>) async throws -> Result + ) async throws -> Result where Result: Sendable { + try await self.Update( + request: request, + serializer: FlatBuffersMessageSerializer>(), + deserializer: FlatBuffersMessageDeserializer>(), + options: options, + onResponse: handleResponse + ) + } + +} + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension models_Greeter.ClientProtocol { + public func Get( + _ message: GRPCMessage, + metadata: GRPCCore.Metadata = [:], + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse>) async throws -> Result = { try $0.message } + ) async throws -> Result where Result: Sendable { + let request = GRPCCore.ClientRequest>( + message: message, + metadata: metadata + ) + return try await self.Get( + request: request, + options: options, + onResponse: handleResponse + ) + } + + public func Collect( + metadata: GRPCCore.Metadata = [:], + options: GRPCCore.CallOptions = .defaults, + requestProducer producer: @Sendable @escaping (GRPCCore.RPCWriter>) async throws -> Void, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse>) async throws -> Result = { try $0.message } + ) async throws -> Result where Result: Sendable { + let request = GRPCCore.StreamingClientRequest>( + metadata: metadata, + producer: producer + ) + return try await self.Collect( + request: request, + options: options, + onResponse: handleResponse + ) + } + + public func Expand( + _ message: GRPCMessage, + metadata: GRPCCore.Metadata = [:], + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse>) async throws -> Result + ) async throws -> Result where Result: Sendable { + let request = GRPCCore.ClientRequest>( + message: message, + metadata: metadata + ) + return try await self.Expand( + request: request, + options: options, + onResponse: handleResponse + ) + } + + public func Update( + metadata: GRPCCore.Metadata = [:], + options: GRPCCore.CallOptions = .defaults, + requestProducer producer: @Sendable @escaping (GRPCCore.RPCWriter>) async throws -> Void, + onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse>) async throws -> Result + ) async throws -> Result where Result: Sendable { + let request = GRPCCore.StreamingClientRequest>( + metadata: metadata, + producer: producer + ) + return try await self.Update( + request: request, + options: options, + onResponse: handleResponse + ) + } + +} + +#endif + diff --git a/grpc/examples/swift/Greeter/Sources/Model/greeter_generated.swift b/grpc/examples/swift/Greeter/Sources/Models/greeter_v2_generated.swift similarity index 81% rename from grpc/examples/swift/Greeter/Sources/Model/greeter_generated.swift rename to grpc/examples/swift/Greeter/Sources/Models/greeter_v2_generated.swift index 954f200e88..b14d59b4a7 100644 --- a/grpc/examples/swift/Greeter/Sources/Model/greeter_generated.swift +++ b/grpc/examples/swift/Greeter/Sources/Models/greeter_v2_generated.swift @@ -8,7 +8,7 @@ import Common import FlatBuffers -public struct models_HelloReply: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable { +public struct models_HelloResponse: FlatBufferVerifiableTable, FlatbuffersVectorInitializable { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -23,16 +23,16 @@ public struct models_HelloReply: FlatBufferTable, FlatbuffersVectorInitializable public var message: String? { let o = _accessor.offset(VT.message); return o == 0 ? nil : _accessor.string(at: o) } public var messageSegmentArray: [UInt8]? { return _accessor.getVector(at: VT.message) } - public static func startHelloReply(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) } + public static func startHelloResponse(_ fbb: inout FlatBufferBuilder) -> UOffset { fbb.startTable(with: 1) } public static func add(message: Offset, _ fbb: inout FlatBufferBuilder) { fbb.add(offset: message, at: VT.message) } - public static func endHelloReply(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end } - public static func createHelloReply( + public static func endHelloResponse(_ fbb: inout FlatBufferBuilder, start: UOffset) -> Offset { let end = Offset(offset: fbb.endTable(at: start)); return end } + public static func createHelloResponse( _ fbb: inout FlatBufferBuilder, messageOffset message: Offset = Offset() ) -> Offset { - let __start = models_HelloReply.startHelloReply(&fbb) - models_HelloReply.add(message: message, &fbb) - return models_HelloReply.endHelloReply(&fbb, start: __start) + let __start = models_HelloResponse.startHelloResponse(&fbb) + models_HelloResponse.add(message: message, &fbb) + return models_HelloResponse.endHelloResponse(&fbb, start: __start) } public static func verify(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable { @@ -42,7 +42,7 @@ public struct models_HelloReply: FlatBufferTable, FlatbuffersVectorInitializable } } -extension models_HelloReply: Encodable { +extension models_HelloResponse: Encodable { enum CodingKeys: String, CodingKey { case message = "message" } @@ -53,7 +53,7 @@ extension models_HelloReply: Encodable { } } -public struct models_HelloRequest: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable { +public struct models_HelloRequest: FlatBufferVerifiableTable, FlatbuffersVectorInitializable { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } diff --git a/grpc/examples/swift/Greeter/Sources/client/main.swift b/grpc/examples/swift/Greeter/Sources/client/main.swift deleted file mode 100644 index 345a0558fc..0000000000 --- a/grpc/examples/swift/Greeter/Sources/client/main.swift +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2024 Google Inc. 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 FlatBuffers -import GRPC -import Logging -import Model -import NIO - -// Quieten the logs. -LoggingSystem.bootstrap { - var handler = StreamLogHandler.standardOutput(label: $0) - handler.logLevel = .critical - return handler -} - -func greet(name: String, client greeter: models_GreeterServiceClient) { - // Form the request with the name, if one was provided. - var builder = FlatBufferBuilder() - let nameOff = builder.create(string: name) - let root = models_HelloRequest.createHelloRequest( - &builder, - nameOffset: nameOff) - builder.finish(offset: root) - - // Make the RPC call to the server. - let sayHello = - greeter - .SayHello(Message(builder: &builder)) - - // wait() on the response to stop the program from exiting before the response is received. - do { - let response = try sayHello.response.wait() - print("Greeter SayHello received: \(response.object.message ?? "Unknown")") - } catch { - print("Greeter failed: \(error)") - } - - let surname = builder.create(string: name) - let manyRoot = models_HelloRequest.createHelloRequest( - &builder, - nameOffset: surname) - builder.finish(offset: manyRoot) - - let call = greeter.SayManyHellos(Message(builder: &builder)) { message in - print( - "Greeter SayManyHellos received: \(message.object.message ?? "Unknown")") - } - - let status = try! call.status.recover { _ in .processingError }.wait() - if status.code != .ok { - print("RPC failed: \(status)") - } -} - -func main(args: [String]) { - // arg0 (dropped) is the program name. We expect arg1 to be the port, and arg2 (optional) to be - // the name sent in the request. - let arg1 = args.dropFirst(1).first - let arg2 = args.dropFirst(2).first - - switch (arg1.flatMap(Int.init), arg2) { - case (.none, _): - print("Usage: PORT [NAME]") - exit(1) - - case (.some(let port), let name): - // Setup an `EventLoopGroup` for the connection to run on. - // - // See: https://github.com/apple/swift-nio#eventloops-and-eventloopgroups - let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) - - // Make sure the group is shutdown when we're done with it. - defer { - try! group.syncShutdownGracefully() - } - - // Configure the channel, we're not using TLS so the connection is `insecure`. - let channel = ClientConnection.insecure(group: group) - .connect(host: "localhost", port: port) - - // Close the connection when we're done with it. - defer { - try! channel.close().wait() - } - - // Provide the connection to the generated client. - let greeter = models_GreeterServiceClient(channel: channel) - - // Do the greeting. - greet(name: name ?? "FlatBuffers!", client: greeter) - } -} - -main(args: CommandLine.arguments) diff --git a/grpc/examples/swift/Greeter/Sources/server/main.swift b/grpc/examples/swift/Greeter/Sources/server/main.swift deleted file mode 100644 index 27255e8c9d..0000000000 --- a/grpc/examples/swift/Greeter/Sources/server/main.swift +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2024 Google Inc. 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 FlatBuffers -import GRPC -import Logging -import Model -import NIO - -class Greeter: models_GreeterProvider { - - var interceptors: models_GreeterServerInterceptorFactoryProtocol? - - let greetings: [String] - - init() { - greetings = ["Hi", "Hallo", "Ciao"] - } - - func SayHello( - request: Message, - context: StatusOnlyCallContext) - -> EventLoopFuture> - { - let recipient = request.object.name ?? "Stranger" - - var builder = FlatBufferBuilder() - let off = builder.create(string: "Hello \(recipient)") - let root = models_HelloReply.createHelloReply(&builder, messageOffset: off) - builder.finish(offset: root) - return context.eventLoop - .makeSucceededFuture(Message(builder: &builder)) - } - - func SayManyHellos( - request: Message, - context: StreamingResponseCallContext>) - -> EventLoopFuture - { - for name in greetings { - var builder = FlatBufferBuilder() - let off = - builder - .create(string: "\(name) \(request.object.name ?? "Unknown")") - let root = models_HelloReply.createHelloReply( - &builder, - messageOffset: off) - builder.finish(offset: root) - _ = context.sendResponse(Message(builder: &builder)) - } - return context.eventLoop.makeSucceededFuture(.ok) - } -} - -// Quieten the logs. -LoggingSystem.bootstrap { - var handler = StreamLogHandler.standardOutput(label: $0) - handler.logLevel = .critical - return handler -} - -let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) -defer { - try! group.syncShutdownGracefully() -} - -// Create some configuration for the server: -let configuration = Server.Configuration( - target: .hostAndPort("localhost", 0), - eventLoopGroup: group, - serviceProviders: [Greeter()]) - -// Start the server and print its address once it has started. -let server = Server.start(configuration: configuration) -server.map { - $0.channel.localAddress -}.whenSuccess { address in - print("server started on port \(address!.port!)") -} - -// Wait on the server's `onClose` future to stop the program from exiting. -_ = try server.flatMap { - $0.onClose -}.wait() diff --git a/grpc/src/compiler/swift_generator.cc b/grpc/src/compiler/swift_generator.cc index b741415393..7286306f5e 100644 --- a/grpc/src/compiler/swift_generator.cc +++ b/grpc/src/compiler/swift_generator.cc @@ -31,349 +31,903 @@ namespace grpc_swift_generator { namespace { -static std::string WrapInNameSpace(const std::vector& components, - const grpc::string& name) { +static std::string ServerResponse() { return "GRPCCore.ServerResponse"; } + +static std::string ServerRequest() { return "GRPCCore.ServerRequest"; } + +static std::string StreamingServerRequest() { + return "GRPCCore.StreamingServerRequest"; +} + +static std::string StreamingServerResponse() { + return "GRPCCore.StreamingServerResponse"; +} + +static std::string QualifiedName(const std::vector& components, + const grpc::string& name, + const std::string separator = "_") { std::string qualified_name; for (auto it = components.begin(); it != components.end(); ++it) - qualified_name += *it + "_"; + qualified_name += *it + separator; return qualified_name + name; } -static grpc::string GenerateMessage(const std::vector& components, - const grpc::string& name) { - return "Message<" + WrapInNameSpace(components, name) + ">"; +static std::string GenerateGRPCMessage(const std::string name) { + return "GRPCMessage<" + name + ">"; } -// MARK: - Client +static std::string GenerateType(const std::string name, + const std::string wrapper) { + return wrapper + "<" + GenerateGRPCMessage(name) + ">"; +} -static void GenerateClientFuncName( - const grpc_generator::Method* method, grpc_generator::Printer* printer, - std::map* dictonary) { - auto vars = *dictonary; - if (method->NoStreaming()) { - printer->Print(vars, - " $GenAccess$func $MethodName$(\n" - " _ request: $Input$\n" - " , callOptions: CallOptions?$isNil$\n" - " ) -> UnaryCall<$Input$, $Output$>"); - return; +static std::string GenerateInputMethodTypes( + const grpc_generator::Method* method) { + if (method->BidiStreaming()) { + return StreamingServerRequest(); + } else if (method->ClientStreaming()) { + return StreamingServerRequest(); + } else if (method->ServerStreaming()) { + return ServerRequest(); + } else { + return ServerRequest(); } +} - if (method->ServerStreaming()) { - printer->Print(vars, - " $GenAccess$func $MethodName$(\n" - " _ request: $Input$\n" - " , callOptions: CallOptions?$isNil$,\n" - " handler: @escaping ($Output$) -> Void\n" - " ) -> ServerStreamingCall<$Input$, $Output$>"); - return; +static std::string GenerateOutputMethodTypes( + const grpc_generator::Method* method) { + if (method->BidiStreaming()) { + return StreamingServerResponse(); + } else if (method->ClientStreaming()) { + return ServerResponse(); + } else if (method->ServerStreaming()) { + return StreamingServerResponse(); + } else { + return ServerResponse(); } +} - if (method->ClientStreaming()) { - printer->Print(vars, - " $GenAccess$func $MethodName$(\n" - " callOptions: CallOptions?$isNil$\n" - " ) -> ClientStreamingCall<$Input$, $Output$>"); - return; +static std::string GenerateMethodTypes(const grpc_generator::Method* method) { + if (method->BidiStreaming()) { + return "bidirectionalStreaming"; + } else if (method->ClientStreaming()) { + return "clientStreaming"; + } else if (method->ServerStreaming()) { + return "serverStreaming"; + } else { + return "unary"; } +} + +void EnforceOSVersion(grpc_generator::Printer* printer) { + printer->Print( + "@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, " + "*)\n"); +} +void Method(grpc_generator::Printer* printer, + std::map* dictonary) { + auto vars = *dictonary; + printer->Print(vars, "$ACCESS$ enum $MethodName$: Sendable {\n"); + printer->Indent(); + printer->Print(vars, "$ACCESS$ typealias Input = FlatBufferBuilder\n"); + printer->Print(vars, "$ACCESS$ typealias Output = $Output$\n"); + printer->Print( + vars, "$ACCESS$ static let descriptor = GRPCCore.MethodDescriptor(\n"); + printer->Indent(); printer->Print(vars, - " $GenAccess$func $MethodName$(\n" - " callOptions: CallOptions?$isNil$,\n" - " handler: @escaping ($Output$ ) -> Void\n" - " ) -> BidirectionalStreamingCall<$Input$, $Output$>"); + "service: GRPCCore.ServiceDescriptor(fullyQualifiedService: " + "\"$ServiceQualifiedName$\"),\n"); + printer->Print(vars, "method: \"$MethodName$\"\n"); + printer->Outdent(); + printer->Print(")\n"); + printer->Outdent(); + printer->Print(vars, "}\n"); } -static void GenerateClientFuncBody( - const grpc_generator::Method* method, grpc_generator::Printer* printer, - std::map* dictonary) { +void GenerateCoders(grpc_generator::Printer* printer) { + EnforceOSVersion(printer); + printer->Print( + "extension FlatBuffersMessageSerializer: MessageSerializer {\n"); + printer->Indent(); + printer->Print( + "public func serialize(_ message: Message) throws -> Bytes where " + "Bytes : GRPCCore.GRPCContiguousBytes {\n"); + printer->Indent(); + printer->Print("do {\n"); + printer->Indent(); + printer->Print( + "return try self.serialize(message: message) { GRPCNIOTransportBytes($0) " + "} as! Bytes\n"); + printer->Outdent(); + printer->Print("} catch let error {\n"); + printer->Indent(); + printer->Print("throw RPCError(\n"); + printer->Indent(); + printer->Print("code: .invalidArgument,\n"); + printer->Print("message: \"Can't serialize message\",\n"); + printer->Print("cause: error\n"); + printer->Outdent(); + printer->Print(")\n"); + printer->Outdent(); + printer->Print("}\n"); + printer->Outdent(); + printer->Print("}\n"); + printer->Outdent(); + printer->Print("}\n\n"); + + EnforceOSVersion(printer); + printer->Print( + "extension FlatBuffersMessageDeserializer: MessageDeserializer {\n"); + printer->Indent(); + printer->Print( + "public func deserialize(_ serializedMessageBytes: Bytes) throws " + "-> Message where Bytes : GRPCCore.GRPCContiguousBytes {\n"); + printer->Indent(); + printer->Print("do {\n"); + printer->Indent(); + printer->Print("return try serializedMessageBytes.withUnsafeBytes {\n"); + printer->Indent(); + printer->Print("try self.deserialize(pointer: $0)\n"); + printer->Outdent(); + printer->Print("}\n"); + printer->Outdent(); + printer->Print("} catch let error {\n"); + printer->Indent(); + printer->Print("throw RPCError(\n"); + printer->Indent(); + printer->Print("code: .invalidArgument,\n"); + printer->Print( + "message: \"Can't Decode message of type \\(Message.self)\",\n"); + printer->Print("cause: error\n"); + printer->Outdent(); + printer->Print(")\n"); + printer->Outdent(); + printer->Print("}\n"); + printer->Outdent(); + printer->Print("}\n"); + printer->Outdent(); + printer->Print("}\n\n"); +} + +void GenerateSharedContent(const grpc_generator::Service* service, + grpc_generator::Printer* printer, + std::map* dictonary) { auto vars = *dictonary; - vars["Interceptor"] = - "interceptors: self.interceptors?.make$MethodName$Interceptors() ?? []"; - if (method->NoStreaming()) { - printer->Print( - vars, - " return self.makeUnaryCall(\n" - " path: \"/$PATH$$ServiceName$/$MethodName$\",\n" - " request: request,\n" - " callOptions: callOptions ?? self.defaultCallOptions,\n" - " $Interceptor$\n" - " )\n"); - return; - } + EnforceOSVersion(printer); + printer->Print(vars, + "$ACCESS$ enum $SwiftServiceQualifiedName$: Sendable {\n"); + printer->Indent(); + printer->Print(vars, + "$ACCESS$ static let descriptor = " + "GRPCCore.ServiceDescriptor(fullyQualifiedService: " + "\"$ServiceQualifiedName$\")\n"); + printer->Print(vars, "$ACCESS$ enum Method: Sendable {\n"); + printer->Indent(); - if (method->ServerStreaming()) { - printer->Print( - vars, - " return self.makeServerStreamingCall(\n" - " path: \"/$PATH$$ServiceName$/$MethodName$\",\n" - " request: request,\n" - " callOptions: callOptions ?? self.defaultCallOptions,\n" - " $Interceptor$,\n" - " handler: handler\n" - " )\n"); - return; + std::vector descriptors; + for (auto it = 0; it < service->method_count(); it++) { + auto method = service->method(it); + vars["Input"] = QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()); + vars["Output"] = QualifiedName(method->get_output_namespace_parts(), + method->get_output_type_name()); + auto name = method->name(); + vars["MethodName"] = name; + descriptors.push_back(name); + Method(printer, &vars); } - if (method->ClientStreaming()) { - printer->Print( - vars, - " return self.makeClientStreamingCall(\n" - " path: \"/$PATH$$ServiceName$/$MethodName$\",\n" - " callOptions: callOptions ?? self.defaultCallOptions,\n" - " $Interceptor$\n" - " )\n"); - return; + printer->Print( + vars, + "$ACCESS$ static let descriptors: [GRPCCore.MethodDescriptor] = [\n"); + printer->Indent(); + for (auto it = descriptors.begin(); it < descriptors.end(); it++) { + vars["MethodName"] = *it; + printer->Print(vars, "$MethodName$.descriptor,\n"); } + printer->Outdent(); + printer->Print("]\n"); + printer->Outdent(); + printer->Print("}\n"); + + printer->Outdent(); + printer->Print("}\n\n"); + + EnforceOSVersion(printer); + printer->Print("extension GRPCCore.ServiceDescriptor {\n"); + printer->Indent(); printer->Print(vars, - " return self.makeBidirectionalStreamingCall(\n" - " path: \"/$PATH$$ServiceName$/$MethodName$\",\n" - " callOptions: callOptions ?? self.defaultCallOptions,\n" - " $Interceptor$,\n" - " handler: handler\n" - " )\n"); + "$ACCESS$ static let $SwiftServiceQualifiedName$ = " + "GRPCCore.ServiceDescriptor(fullyQualifiedService: " + "\"$ServiceQualifiedName$\")\n"); + printer->Outdent(); + printer->Print("}\n"); } -void GenerateClientProtocol(const grpc_generator::Service* service, - grpc_generator::Printer* printer, - std::map* dictonary) { +// Service Generation + +void GenerateFunction(grpc_generator::Printer* printer, + std::map* dictonary) { auto vars = *dictonary; - printer->Print( - vars, - "$ACCESS$ protocol $ServiceQualifiedName$ClientProtocol: GRPCClient {"); - printer->Print("\n\n"); - printer->Print(" var serviceName: String { get }"); - printer->Print("\n\n"); - printer->Print( - vars, - " var interceptors: " - "$ServiceQualifiedName$ClientInterceptorFactoryProtocol? { get }"); - printer->Print("\n\n"); + printer->Print(vars, "func $MethodName$(\n"); + printer->Indent(); + + printer->Print(vars, "request: $Input$,\n"); + printer->Print("context: GRPCCore.ServerContext\n"); + + printer->Outdent(); + printer->Print(vars, ") async throws -> $Output$\n\n"); +} + +void GenerateServiceProtocols(const grpc_generator::Service* service, + grpc_generator::Printer* printer, + std::map* dictonary) { + auto vars = *dictonary; + EnforceOSVersion(printer); + printer->Print(vars, "extension $SwiftServiceQualifiedName$ {\n"); + printer->Indent(); + // Base protocol + printer->Print(vars, + "$ACCESS$ protocol StreamingServiceProtocol: " + "GRPCCore.RegistrableRPCService {\n"); + printer->Indent(); - vars["GenAccess"] = ""; for (auto it = 0; it < service->method_count(); it++) { auto method = service->method(it); - vars["Input"] = GenerateMessage(method->get_input_namespace_parts(), - method->get_input_type_name()); - vars["Output"] = GenerateMessage(method->get_output_namespace_parts(), - method->get_output_type_name()); - vars["MethodName"] = method->name(); - vars["isNil"] = ""; - GenerateClientFuncName(method.get(), &*printer, &vars); - printer->Print("\n\n"); + vars["Input"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + StreamingServerRequest()); + + vars["Output"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + StreamingServerResponse()); + auto name = method->name(); + vars["MethodName"] = name; + GenerateFunction(printer, &vars); } + printer->Outdent(); printer->Print("}\n\n"); - printer->Print(vars, "extension $ServiceQualifiedName$ClientProtocol {"); - printer->Print("\n\n"); + // Service printer->Print(vars, - " $ACCESS$ var serviceName: String { " - "\"$PATH$$ServiceName$\" }\n"); + "$ACCESS$ protocol ServiceProtocol: " + "$SwiftServiceQualifiedName$.StreamingServiceProtocol {\n"); + printer->Indent(); - vars["GenAccess"] = service->is_internal() ? "internal " : "public "; for (auto it = 0; it < service->method_count(); it++) { auto method = service->method(it); - vars["Input"] = GenerateMessage(method->get_input_namespace_parts(), - method->get_input_type_name()); - vars["Output"] = GenerateMessage(method->get_output_namespace_parts(), - method->get_output_type_name()); - vars["MethodName"] = method->name(); - vars["isNil"] = " = nil"; - printer->Print("\n"); - GenerateClientFuncName(method.get(), &*printer, &vars); - printer->Print(" {\n"); - GenerateClientFuncBody(method.get(), &*printer, &vars); - printer->Print(" }\n"); + + vars["Input"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + GenerateInputMethodTypes(&*method)); + + vars["Output"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + GenerateOutputMethodTypes(&*method)); + auto name = method->name(); + vars["MethodName"] = name; + GenerateFunction(printer, &vars); } + + printer->Outdent(); printer->Print("}\n\n"); + // Simple service printer->Print(vars, - "$ACCESS$ protocol " - "$ServiceQualifiedName$ClientInterceptorFactoryProtocol {\n"); + "$ACCESS$ protocol SimpleServiceProtocol: " + "$SwiftServiceQualifiedName$.ServiceProtocol {\n"); + printer->Indent(); + + for (auto it = 0; it < service->method_count(); it++) { + auto method = service->method(it); + + vars["Input"] = GenerateGRPCMessage(QualifiedName( + method->get_input_namespace_parts(), method->get_output_type_name())); + + vars["Output"] = GenerateGRPCMessage(QualifiedName( + method->get_input_namespace_parts(), method->get_output_type_name())); + auto name = method->name(); + vars["MethodName"] = name; + + printer->Print(vars, "func $MethodName$(\n"); + printer->Indent(); + + if (method->ClientStreaming() || method->BidiStreaming()) { + printer->Print( + vars, + "request: GRPCCore.RPCAsyncSequence<$Input$, any Swift.Error>,\n"); + } else { + printer->Print(vars, "request: $Input$,\n"); + } + + if (method->BidiStreaming() || method->ServerStreaming()) { + printer->Print(vars, "response: GRPCCore.RPCWriter<$Output$>,\n"); + } + printer->Print("context: GRPCCore.ServerContext\n"); + + printer->Outdent(); + + if (!method->BidiStreaming() && !method->ServerStreaming()) { + printer->Print(vars, ") async throws -> $Output$\n\n"); + } else { + printer->Print(") async throws\n\n"); + } + } + + printer->Outdent(); + printer->Print("}\n"); + + printer->Outdent(); + printer->Print("}\n\n"); + + EnforceOSVersion(printer); + printer->Print( + vars, + "extension $SwiftServiceQualifiedName$.StreamingServiceProtocol {\n"); + printer->Indent(); + printer->Print( + "public func registerMethods(with router: inout " + "GRPCCore.RPCRouter) where Transport: " + "GRPCCore.ServerTransport {\n"); + printer->Indent(); for (auto it = 0; it < service->method_count(); it++) { auto method = service->method(it); - vars["Input"] = GenerateMessage(method->get_input_namespace_parts(), - method->get_input_type_name()); - vars["Output"] = GenerateMessage(method->get_output_namespace_parts(), - method->get_output_type_name()); - vars["MethodName"] = method->name(); + vars["Input"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "FlatBuffersMessageSerializer"); + + vars["Output"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "FlatBuffersMessageDeserializer"); + + auto name = method->name(); + vars["MethodName"] = name; + + printer->Print("router.registerHandler(\n"); + printer->Indent(); printer->Print( vars, - " /// - Returns: Interceptors to use when invoking '$MethodName$'.\n"); - printer->Print(vars, - " func make$MethodName$Interceptors() -> " - "[ClientInterceptor<$Input$, $Output$>]\n\n"); + "forMethod: " + "$SwiftServiceQualifiedName$.Method.$MethodName$.descriptor,\n"); + printer->Print(vars, "deserializer: $Output$(),\n"); + printer->Print(vars, "serializer: $Input$(),\n"); + printer->Print("handler: { request, context in\n"); + printer->Indent(); + printer->Print(vars, "try await self.$MethodName$(\n"); + printer->Indent(); + printer->Print("request: request,\n"); + printer->Print("context: context\n"); + printer->Outdent(); + printer->Print(")\n"); + printer->Outdent(); + printer->Print("}\n"); + printer->Outdent(); + printer->Print(")\n"); } + + printer->Outdent(); + printer->Print("}\n"); + printer->Outdent(); printer->Print("}\n\n"); } -void GenerateClientClass(grpc_generator::Printer* printer, - std::map* dictonary) { +void CreateServiceProtocolFunctionsImplementations( + grpc_generator::Printer* printer, + std::map* dictonary) { auto vars = *dictonary; - printer->Print(vars, - "$ACCESS$ final class $ServiceQualifiedName$ServiceClient: " - "$ServiceQualifiedName$ClientProtocol {\n"); - printer->Print(vars, " $ACCESS$ let channel: GRPCChannel\n"); - printer->Print(vars, " $ACCESS$ var defaultCallOptions: CallOptions\n"); - printer->Print(vars, - " $ACCESS$ var interceptors: " - "$ServiceQualifiedName$ClientInterceptorFactoryProtocol?\n"); - printer->Print("\n"); - printer->Print( - vars, - " $ACCESS$ init(\n" - " channel: GRPCChannel,\n" - " defaultCallOptions: CallOptions = CallOptions(),\n" - " interceptors: " - "$ServiceQualifiedName$ClientInterceptorFactoryProtocol? = nil\n" - " ) {\n"); - printer->Print(" self.channel = channel\n"); - printer->Print(" self.defaultCallOptions = defaultCallOptions\n"); - printer->Print(" self.interceptors = interceptors\n"); - printer->Print(" }"); - printer->Print("\n"); + printer->Print(vars, "$ACCESS$ func $MethodName$(\n"); + printer->Indent(); + printer->Print(vars, "request: $Input$,\n"); + printer->Print("context: GRPCCore.ServerContext\n"); + printer->Outdent(); + printer->Print(vars, ") async throws -> $Output$ {\n"); + printer->Indent(); + printer->Print(vars, "let response = try await self.$MethodName$(\n"); + printer->Indent(); + printer->Print(vars, "request: $InputRequest$,\n"); + printer->Print("context: context\n"); + printer->Outdent(); + printer->Print(")\n"); + printer->Print(vars, "return $OutputResponse$\n"); + printer->Outdent(); printer->Print("}\n"); } -// MARK: - Server +std::string GenerateInputRequest(const grpc_generator::Method* method) { + if (method->NoStreaming() || method->ServerStreaming()) + return ServerRequest() + "(stream: request)"; + return "request"; +} -grpc::string GenerateServerFuncName(const grpc_generator::Method* method) { - if (method->NoStreaming()) { - return "func $MethodName$(request: $Input$" - ", context: StatusOnlyCallContext) -> EventLoopFuture<$Output$>"; - } +std::string GenerateOutputResponse(const grpc_generator::Method* method) { + if (method->NoStreaming() || method->ClientStreaming()) + return StreamingServerResponse() + "(single: response)"; + return "response"; +} - if (method->ClientStreaming()) { - return "func $MethodName$(context: UnaryResponseCallContext<$Output$>) -> " - "EventLoopFuture<(StreamEvent<$Input$" - ">) -> Void>"; - } +void GenerateServiceDefaultImplementation( + const grpc_generator::Service* service, grpc_generator::Printer* printer, + std::map* dictonary) { + auto vars = *dictonary; + EnforceOSVersion(printer); + printer->Print(vars, + "extension $SwiftServiceQualifiedName$.ServiceProtocol {\n"); + printer->Indent(); - if (method->ServerStreaming()) { - return "func $MethodName$(request: $Input$" - ", context: StreamingResponseCallContext<$Output$>) -> " - "EventLoopFuture"; + for (auto it = 0; it < service->method_count(); it++) { + auto method = service->method(it); + if (method->BidiStreaming()) { + continue; + } + + vars["Input"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + StreamingServerRequest()); + + vars["Output"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + StreamingServerResponse()); + auto name = method->name(); + vars["MethodName"] = name; + + vars["InputRequest"] = GenerateInputRequest(&*method); + vars["OutputResponse"] = GenerateOutputResponse(&*method); + + CreateServiceProtocolFunctionsImplementations(printer, &vars); } - return "func $MethodName$(context: StreamingResponseCallContext<$Output$>) " - "-> EventLoopFuture<(StreamEvent<$Input$>) -> Void>"; + printer->Outdent(); + printer->Print("}\n\n"); } -grpc::string GenerateServerExtensionBody(const grpc_generator::Method* method) { - grpc::string start = " case \"$MethodName$\":\n "; - grpc::string interceptors = - " interceptors: self.interceptors?.make$MethodName$Interceptors() " - "?? [],\n"; - if (method->NoStreaming()) { - return start + - "return UnaryServerHandler(\n" - " context: context,\n" - " requestDeserializer: GRPCPayloadDeserializer<$Input$>(),\n" - " responseSerializer: GRPCPayloadSerializer<$Output$>(),\n" + - interceptors + - " userFunction: self.$MethodName$(request:context:))\n"; - } - if (method->ServerStreaming()) { - return start + - "return ServerStreamingServerHandler(\n" - " context: context,\n" - " requestDeserializer: GRPCPayloadDeserializer<$Input$>(),\n" - " responseSerializer: GRPCPayloadSerializer<$Output$>(),\n" + - interceptors + - " userFunction: self.$MethodName$(request:context:))\n"; - } - if (method->ClientStreaming()) { - return start + - "return ClientStreamingServerHandler(\n" - " context: context,\n" - " requestDeserializer: GRPCPayloadDeserializer<$Input$>(),\n" - " responseSerializer: GRPCPayloadSerializer<$Output$>(),\n" + - interceptors + - " observerFactory: self.$MethodName$(context:))\n"; +void GenerateSimpleServiceImplemetation( + const grpc_generator::Service* service, grpc_generator::Printer* printer, + std::map* dictonary) { + auto vars = *dictonary; + EnforceOSVersion(printer); + printer->Print( + vars, "extension $SwiftServiceQualifiedName$.SimpleServiceProtocol {\n"); + printer->Indent(); + + for (auto it = 0; it < service->method_count(); it++) { + auto method = service->method(it); + + vars["Input"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + GenerateInputMethodTypes(&*method)); + + vars["Output"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + GenerateOutputMethodTypes(&*method)); + auto name = method->name(); + vars["MethodName"] = name; + + printer->Print(vars, "$ACCESS$ func $MethodName$(\n"); + printer->Indent(); + printer->Print(vars, "request: $Input$,\n"); + printer->Print("context: GRPCCore.ServerContext\n"); + printer->Outdent(); + printer->Print(vars, ") async throws -> $Output$ {\n"); + printer->Indent(); + printer->Print(vars, "return $Output$(\n"); + printer->Indent(); + + if (method->NoStreaming() || method->ClientStreaming()) { + vars["Message"] = method->ClientStreaming() ? "messages" : "message"; + printer->Print(vars, "message: try await self.$MethodName$(\n"); + printer->Indent(); + printer->Print(vars, "request: request.$Message$,\n"); + printer->Print("context: context\n"); + printer->Outdent(); + printer->Print(vars, "),\n"); + printer->Print(vars, "metadata: [:]\n"); + } else { + vars["Message"] = method->BidiStreaming() ? "messages" : "message"; + printer->Print(vars, "metadata: [:],\n"); + printer->Print(vars, "producer: { writer in\n"); + printer->Indent(); + printer->Print(vars, "try await self.$MethodName$(\n"); + printer->Indent(); + printer->Print(vars, "request: request.$Message$,\n"); + printer->Print("response: writer,\n"); + printer->Print("context: context\n"); + printer->Outdent(); + printer->Print(")\n"); + printer->Print("return [:]\n"); + printer->Outdent(); + printer->Print(vars, "}\n"); + } + + printer->Outdent(); + printer->Print(")\n"); + printer->Outdent(); + printer->Print("}\n"); } - if (method->BidiStreaming()) { - return start + - "return BidirectionalStreamingServerHandler(\n" - " context: context,\n" - " requestDeserializer: GRPCPayloadDeserializer<$Input$>(),\n" - " responseSerializer: GRPCPayloadSerializer<$Output$>(),\n" + - interceptors + - " observerFactory: self.$MethodName$(context:))\n"; + printer->Outdent(); + printer->Print("}\n\n"); +} + +void GenerateService(const grpc_generator::Service* service, + grpc_generator::Printer* printer, + std::map* dictonary) { + GenerateServiceProtocols(service, printer, dictonary); + GenerateServiceDefaultImplementation(service, printer, dictonary); + GenerateSimpleServiceImplemetation(service, printer, dictonary); +} + +// Client Generation + +void GenerateClientProtocols(const grpc_generator::Service* service, + grpc_generator::Printer* printer, + std::map* dictonary) { + auto vars = *dictonary; + EnforceOSVersion(printer); + printer->Print(vars, "extension $SwiftServiceQualifiedName$ {\n"); + printer->Indent(); + // Base protocol + printer->Print(vars, "$ACCESS$ protocol ClientProtocol: Sendable {\n"); + printer->Indent(); + + for (auto it = 0; it < service->method_count(); it++) { + auto method = service->method(it); + auto name = method->name(); + vars["MethodName"] = name; + + vars["serializer"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "GRPCCore.MessageSerializer"); + + vars["deserializer"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "GRPCCore.MessageDeserializer"); + + if (method->ClientStreaming() || method->BidiStreaming()) { + vars["request"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "GRPCCore.StreamingClientRequest"); + } else { + vars["request"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "GRPCCore.ClientRequest"); + } + + if (method->ServerStreaming() || method->BidiStreaming()) { + vars["response"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "GRPCCore.StreamingClientResponse"); + } else { + vars["response"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "GRPCCore.ClientResponse"); + } + + printer->Print(vars, "func $MethodName$(\n"); + printer->Indent(); + printer->Print(vars, "request: $request$,\n"); + printer->Print(vars, "serializer: some $serializer$,\n"); + printer->Print(vars, "deserializer: some $deserializer$,\n"); + printer->Print("options: GRPCCore.CallOptions,\n"); + printer->Print(vars, + "onResponse handleResponse: @Sendable @escaping " + "($response$) async throws -> Result\n"); + printer->Outdent(); + printer->Print(") async throws -> Result where Result: Sendable\n\n"); } - return ""; + + printer->Outdent(); + printer->Print("}\n"); + printer->Outdent(); + printer->Print("}\n\n"); } -void GenerateServerProtocol(const grpc_generator::Service* service, - grpc_generator::Printer* printer, - std::map* dictonary) { +void GenerateClientStruct(const grpc_generator::Service* service, + grpc_generator::Printer* printer, + std::map* dictonary) { auto vars = *dictonary; + EnforceOSVersion(printer); + printer->Print(vars, "extension $SwiftServiceQualifiedName$ {\n"); + printer->Indent(); + // Base protocol printer->Print(vars, - "$ACCESS$ protocol $ServiceQualifiedName$Provider: " - "CallHandlerProvider {\n"); + "$ACCESS$ struct Client: ClientProtocol where " + "Transport: GRPCCore.ClientTransport {\n"); + printer->Indent(); + printer->Print("private let client: GRPCCore.GRPCClient\n\n"); printer->Print( vars, - " var interceptors: " - "$ServiceQualifiedName$ServerInterceptorFactoryProtocol? { get }\n"); + "$ACCESS$ init(wrapping client: GRPCCore.GRPCClient) {\n"); + printer->Indent(); + printer->Print("self.client = client\n"); + printer->Outdent(); + printer->Print("}\n\n"); + for (auto it = 0; it < service->method_count(); it++) { auto method = service->method(it); - vars["Input"] = GenerateMessage(method->get_input_namespace_parts(), - method->get_input_type_name()); - vars["Output"] = GenerateMessage(method->get_output_namespace_parts(), - method->get_output_type_name()); - vars["MethodName"] = method->name(); - printer->Print(" "); - auto func = GenerateServerFuncName(method.get()); - printer->Print(vars, func.c_str()); - printer->Print("\n"); + auto name = method->name(); + vars["MethodType"] = GenerateMethodTypes(&*method); + vars["MethodName"] = name; + + vars["serializer"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "GRPCCore.MessageSerializer"); + + vars["deserializer"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "GRPCCore.MessageDeserializer"); + + if (method->ClientStreaming() || method->BidiStreaming()) { + vars["request"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "GRPCCore.StreamingClientRequest"); + } else { + vars["request"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "GRPCCore.ClientRequest"); + } + + if (method->ServerStreaming() || method->BidiStreaming()) { + vars["response"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "GRPCCore.StreamingClientResponse"); + vars["CompletionBlock"] = ""; + } else { + vars["response"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "GRPCCore.ClientResponse"); + vars["CompletionBlock"] = " = { response in try response.message }"; + } + + printer->Print(vars, "$ACCESS$ func $MethodName$(\n"); + printer->Indent(); + printer->Print(vars, "request: $request$,\n"); + printer->Print(vars, "serializer: some $serializer$,\n"); + printer->Print(vars, "deserializer: some $deserializer$,\n"); + printer->Print("options: GRPCCore.CallOptions = .defaults,\n"); + printer->Print(vars, + "onResponse handleResponse: @Sendable @escaping " + "($response$) async throws -> Result$CompletionBlock$\n"); + printer->Outdent(); + printer->Print(") async throws -> Result where Result: Sendable {\n"); + printer->Indent(); + printer->Print(vars, "try await self.client.$MethodType$(\n"); + printer->Indent(); + printer->Print("request: request,\n"); + printer->Print( + vars, + "descriptor: " + "$SwiftServiceQualifiedName$.Method.$MethodName$.descriptor,\n"); + printer->Print("serializer: serializer,\n"); + printer->Print("deserializer: deserializer,\n"); + printer->Print("options: options,\n"); + printer->Print("onResponse: handleResponse\n"); + printer->Outdent(); + printer->Print(")\n"); + printer->Outdent(); + printer->Print("}\n\n"); } + + printer->Outdent(); + printer->Print("}\n"); + printer->Outdent(); printer->Print("}\n\n"); +} - printer->Print(vars, "$ACCESS$ extension $ServiceQualifiedName$Provider {\n"); - printer->Print("\n"); +void GenerateClientDefaultImplementation( + const grpc_generator::Service* service, grpc_generator::Printer* printer, + std::map* dictonary) { + auto vars = *dictonary; + EnforceOSVersion(printer); printer->Print(vars, - " var serviceName: Substring { return " - "\"$PATH$$ServiceName$\" }\n"); - printer->Print("\n"); - printer->Print( - " func handle(method name: Substring, context: " - "CallHandlerContext) -> GRPCServerHandlerProtocol? {\n"); - printer->Print(" switch name {\n"); + "extension $SwiftServiceQualifiedName$.ClientProtocol {\n"); + printer->Indent(); + for (auto it = 0; it < service->method_count(); it++) { auto method = service->method(it); - vars["Input"] = GenerateMessage(method->get_input_namespace_parts(), - method->get_input_type_name()); - vars["Output"] = GenerateMessage(method->get_output_namespace_parts(), - method->get_output_type_name()); - vars["MethodName"] = method->name(); - auto body = GenerateServerExtensionBody(method.get()); - printer->Print(vars, body.c_str()); - printer->Print("\n"); + auto name = method->name(); + vars["MethodName"] = name; + + vars["serializer"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "FlatBuffersMessageSerializer"); + + vars["deserializer"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "FlatBuffersMessageDeserializer"); + + if (method->ClientStreaming() || method->BidiStreaming()) { + vars["request"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "GRPCCore.StreamingClientRequest"); + } else { + vars["request"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "GRPCCore.ClientRequest"); + } + + if (method->ServerStreaming() || method->BidiStreaming()) { + vars["response"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "GRPCCore.StreamingClientResponse"); + vars["CompletionBlock"] = ""; + } else { + vars["response"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "GRPCCore.ClientResponse"); + vars["CompletionBlock"] = " = { response in try response.message }"; + } + + printer->Print(vars, "$ACCESS$ func $MethodName$(\n"); + printer->Indent(); + printer->Print(vars, "request: $request$,\n"); + printer->Print("options: GRPCCore.CallOptions = .defaults,\n"); + printer->Print(vars, + "onResponse handleResponse: @Sendable @escaping " + "($response$) async throws -> Result$CompletionBlock$\n"); + printer->Outdent(); + printer->Print(") async throws -> Result where Result: Sendable {\n"); + printer->Indent(); + printer->Print(vars, "try await self.$MethodName$(\n"); + printer->Indent(); + printer->Print("request: request,\n"); + printer->Print(vars, "serializer: $serializer$(),\n"); + printer->Print(vars, "deserializer: $deserializer$(),\n"); + printer->Print("options: options,\n"); + printer->Print("onResponse: handleResponse\n"); + printer->Outdent(); + printer->Print(")\n"); + printer->Outdent(); + printer->Print("}\n\n"); } - printer->Print(" default: return nil;\n"); - printer->Print(" }\n"); - printer->Print(" }\n\n"); + + printer->Outdent(); printer->Print("}\n\n"); +} + +void GenerateClientHelperMethods( + const grpc_generator::Service* service, grpc_generator::Printer* printer, + std::map* dictonary) { + auto vars = *dictonary; + EnforceOSVersion(printer); printer->Print(vars, - "$ACCESS$ protocol " - "$ServiceQualifiedName$ServerInterceptorFactoryProtocol {\n"); + "extension $SwiftServiceQualifiedName$.ClientProtocol {\n"); + printer->Indent(); + for (auto it = 0; it < service->method_count(); it++) { auto method = service->method(it); - vars["Input"] = GenerateMessage(method->get_input_namespace_parts(), - method->get_input_type_name()); - vars["Output"] = GenerateMessage(method->get_output_namespace_parts(), - method->get_output_type_name()); - vars["MethodName"] = method->name(); - printer->Print( - vars, - " /// - Returns: Interceptors to use when handling '$MethodName$'.\n" - " /// Defaults to calling `self.makeInterceptors()`.\n"); - printer->Print(vars, - " func make$MethodName$Interceptors() -> " - "[ServerInterceptor<$Input$, $Output$>]\n\n"); + auto name = method->name(); + vars["MethodName"] = name; + + vars["serializer"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "FlatBuffersMessageSerializer"); + + vars["deserializer"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "FlatBuffersMessageDeserializer"); + + printer->Print(vars, "$ACCESS$ func $MethodName$(\n"); + printer->Indent(); + + if (method->NoStreaming() || method->ServerStreaming()) { + vars["request"] = GenerateGRPCMessage(QualifiedName( + method->get_input_namespace_parts(), method->get_output_type_name())); + printer->Print(vars, "_ message: $request$,\n"); + } + + printer->Print("metadata: GRPCCore.Metadata = [:],\n"); + printer->Print("options: GRPCCore.CallOptions = .defaults,\n"); + + if (method->ClientStreaming() || method->BidiStreaming()) { + vars["request"] = GenerateGRPCMessage(QualifiedName( + method->get_input_namespace_parts(), method->get_output_type_name())); + printer->Print(vars, + "requestProducer producer: @Sendable @escaping " + "(GRPCCore.RPCWriter<$request$>) async throws -> Void,\n"); + } + + if (method->NoStreaming() || method->ClientStreaming()) { + vars["response"] = GenerateGRPCMessage(QualifiedName( + method->get_input_namespace_parts(), method->get_output_type_name())); + + printer->Print(vars, + "onResponse handleResponse: @Sendable @escaping " + "(GRPCCore.ClientResponse<$response$>) async throws -> " + "Result = { try $0.message }\n"); + } else { + vars["response"] = GenerateGRPCMessage(QualifiedName( + method->get_input_namespace_parts(), method->get_output_type_name())); + + printer->Print(vars, + "onResponse handleResponse: @Sendable @escaping " + "(GRPCCore.StreamingClientResponse<$response$>) async " + "throws -> Result\n"); + } + + printer->Outdent(); + printer->Print(") async throws -> Result where Result: Sendable {\n"); + printer->Indent(); + + if (method->ClientStreaming() || method->BidiStreaming()) { + vars["request"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "GRPCCore.StreamingClientRequest"); + } else { + vars["request"] = + GenerateType(QualifiedName(method->get_input_namespace_parts(), + method->get_output_type_name()), + "GRPCCore.ClientRequest"); + } + + printer->Print(vars, "let request = $request$(\n"); + printer->Indent(); + if (method->NoStreaming() || method->ServerStreaming()) { + printer->Print("message: message,\n"); + printer->Print("metadata: metadata\n"); + } else { + printer->Print("metadata: metadata,\n"); + printer->Print("producer: producer\n"); + } + + printer->Outdent(); + printer->Print(")\n"); + + printer->Print(vars, "return try await self.$MethodName$(\n"); + printer->Indent(); + printer->Print("request: request,\n"); + printer->Print("options: options,\n"); + printer->Print("onResponse: handleResponse\n"); + printer->Outdent(); + printer->Print(")\n"); + printer->Outdent(); + printer->Print("}\n\n"); } - printer->Print("}"); + + printer->Outdent(); + printer->Print("}\n\n"); +} + +void GenerateClient(const grpc_generator::Service* service, + grpc_generator::Printer* printer, + std::map* dictonary) { + GenerateClientProtocols(service, printer, dictonary); + GenerateClientStruct(service, printer, dictonary); + GenerateClientDefaultImplementation(service, printer, dictonary); + GenerateClientHelperMethods(service, printer, dictonary); } + } // namespace grpc::string Generate(grpc_generator::File* file, @@ -384,8 +938,10 @@ grpc::string Generate(grpc_generator::File* file, if (!file->package().empty()) { vars["PATH"].append("."); } + vars["SwiftServiceQualifiedName"] = + QualifiedName(service->namespace_parts(), service->name()); vars["ServiceQualifiedName"] = - WrapInNameSpace(service->namespace_parts(), service->name()); + QualifiedName(service->namespace_parts(), service->name(), "."); vars["ServiceName"] = service->name(); vars["ACCESS"] = service->is_internal() ? "internal" : "public"; auto printer = file->CreatePrinter(&output); @@ -393,11 +949,15 @@ grpc::string Generate(grpc_generator::File* file, vars, "/// Usage: instantiate $ServiceQualifiedName$ServiceClient, then call " "methods of this protocol to make API calls.\n"); - GenerateClientProtocol(service, &*printer, &vars); - GenerateClientClass(&*printer, &vars); + GenerateCoders(&*printer); + GenerateSharedContent(service, &*printer, &vars); printer->Print("\n"); - GenerateServerProtocol(service, &*printer, &vars); + printer->Print(vars, "// MARK: $ServiceQualifiedName$ Server\n\n"); + GenerateService(service, &*printer, &vars); printer->Print("\n"); + printer->Print(vars, "// MARK: $ServiceQualifiedName$ Client\n\n"); + + GenerateClient(service, &*printer, &vars); printer->Print("#endif\n"); return output; } @@ -414,30 +974,12 @@ grpc::string GenerateHeader() { code += "// swiftlint:disable all\n"; code += "// swiftformat:disable all\n"; code += "\n"; - code += "#if !os(Windows)\n"; - code += "import Foundation\n"; - code += "import GRPC\n"; - code += "import NIO\n"; - code += "import NIOHTTP1\n"; + code += "#if !os(Windows) && compiler(>=6.0)\n"; code += "import FlatBuffers\n"; + code += "import Foundation\n"; + code += "import GRPCCore\n"; + code += "import GRPCNIOTransportCore\n"; code += "\n"; - code += - "public protocol GRPCFlatBufPayload: GRPCPayload, FlatBufferGRPCMessage " - "{}\n"; - - code += "public extension GRPCFlatBufPayload {\n"; - code += " init(serializedByteBuffer: inout NIO.ByteBuffer) throws {\n"; - code += - " self.init(byteBuffer: FlatBuffers.ByteBuffer(contiguousBytes: " - "serializedByteBuffer.readableBytesView, count: " - "serializedByteBuffer.readableBytes))\n"; - code += " }\n"; - - code += " func serialize(into buffer: inout NIO.ByteBuffer) throws {\n"; - code += " withUnsafeReadableBytes { buffer.writeBytes($0) }\n"; - code += " }\n"; - code += "}\n"; - code += "extension Message: GRPCFlatBufPayload {}\n"; return code; } } // namespace grpc_swift_generator diff --git a/samples/monster_generated.swift b/samples/monster_generated.swift index 3bd45617fd..0ef998757f 100644 --- a/samples/monster_generated.swift +++ b/samples/monster_generated.swift @@ -161,7 +161,7 @@ public struct MyGame_Sample_Vec3_Mutable: FlatBufferStruct, FlatbuffersVectorIni } } -public struct MyGame_Sample_Monster: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +public struct MyGame_Sample_Monster: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -400,7 +400,7 @@ public class MyGame_Sample_MonsterT: NativeObject { public func serialize() -> ByteBuffer { return serialize(type: MyGame_Sample_Monster.self) } } -public struct MyGame_Sample_Weapon: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +public struct MyGame_Sample_Weapon: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } diff --git a/scripts/generate_grpc_examples.py b/scripts/generate_grpc_examples.py index 93058e7b32..9571a6336e 100755 --- a/scripts/generate_grpc_examples.py +++ b/scripts/generate_grpc_examples.py @@ -20,6 +20,7 @@ grpc_examples_path = Path(root_path, "grpc/examples") greeter_schema = str(Path(grpc_examples_path, "greeter.fbs")) +greeter_schema_v2 = str(Path(grpc_examples_path, "greeter_v2.fbs")) COMMON_ARGS = [ "--grpc", @@ -54,8 +55,8 @@ def GenerateGRPCExamples(): "--swift", "--gen-json-emit", ], - schema=greeter_schema, - cwd=Path(grpc_examples_path, "swift/Greeter/Sources/Model"), + schema=greeter_schema_v2, + cwd=Path(grpc_examples_path, "swift/Greeter/Sources/Models"), ) flatc( diff --git a/src/idl_gen_swift.cpp b/src/idl_gen_swift.cpp index f534ca254f..e506013ec6 100644 --- a/src/idl_gen_swift.cpp +++ b/src/idl_gen_swift.cpp @@ -171,7 +171,7 @@ class SwiftGenerator : public BaseGenerator { if (parser_.opts.include_dependence_headers || parser_.opts.generate_all) { code_.SetValue("IMPLEMENTONLY", parser_.opts.swift_implementation_only - ? "@_implementationOnly " + ? "internal " : ""); code_ += "#if canImport(Common)"; code_ += "{{IMPLEMENTONLY}}import Common"; @@ -549,13 +549,14 @@ class SwiftGenerator : public BaseGenerator { code_.SetValue("SHORT_STRUCTNAME", namer_.Type(struct_def)); code_.SetValue("STRUCTNAME", namer_.NamespacedType(struct_def)); code_.SetValue("OBJECTTYPE", struct_def.fixed ? "Struct" : "Table"); + code_.SetValue("PROTOCOL", struct_def.fixed ? "FlatBufferStruct" + : "FlatBufferVerifiableTable"); code_.SetValue("MUTABLE", struct_def.fixed ? Mutable() : ""); GenOSVersionChecks(); code_ += "{{ACCESS_TYPE}} struct {{STRUCTNAME}}{{MUTABLE}}: " - "FlatBuffer{{OBJECTTYPE}}, FlatbuffersVectorInitializable\\"; - if (!struct_def.fixed) code_ += ", Verifiable\\"; + "{{PROTOCOL}}, FlatbuffersVectorInitializable\\"; if (!struct_def.fixed && parser_.opts.generate_object_based_api) code_ += ", ObjectAPIPacker\\"; code_ += " {\n"; diff --git a/swift/Sources/FlatBuffers/ByteBuffer.swift b/swift/Sources/FlatBuffers/ByteBuffer.swift index ec27fd1d73..f8b59eec06 100644 --- a/swift/Sources/FlatBuffers/ByteBuffer.swift +++ b/swift/Sources/FlatBuffers/ByteBuffer.swift @@ -20,7 +20,7 @@ import Foundation /// it allows users to write and read data directly from memory thus the use of its /// functions should be used @frozen -public struct ByteBuffer { +public struct ByteBuffer: @unchecked Sendable { /// Storage is a container that would hold the memory pointer to solve the issue of /// deallocating the memory that was held by (memory: UnsafeMutableRawPointer) @@ -30,7 +30,7 @@ public struct ByteBuffer { enum Blob { #if !os(WASI) case data(Data) - case bytes(ContiguousBytes) + case bytes(any ContiguousBytes) #endif case byteBuffer(_InternalByteBuffer) diff --git a/swift/Sources/FlatBuffers/Enum.swift b/swift/Sources/FlatBuffers/Enum.swift index 65e3a4d375..feb576250a 100644 --- a/swift/Sources/FlatBuffers/Enum.swift +++ b/swift/Sources/FlatBuffers/Enum.swift @@ -23,7 +23,7 @@ import Common /// Enum is a protocol that all flatbuffers enums should conform to /// Since it allows us to get the actual `ByteSize` and `Value` from /// a swift enum. -public protocol Enum { +public protocol Enum: Sendable { /// associatedtype that the type of the enum should conform to associatedtype T: Scalar & Verifiable /// Size of the current associatedtype in the enum diff --git a/swift/Sources/FlatBuffers/FlatBufferBuilder.swift b/swift/Sources/FlatBuffers/FlatBufferBuilder.swift index 9e778d225c..b8e49bd4ec 100644 --- a/swift/Sources/FlatBuffers/FlatBufferBuilder.swift +++ b/swift/Sources/FlatBuffers/FlatBufferBuilder.swift @@ -45,7 +45,7 @@ public struct FlatBufferBuilder { /// Dictonary that stores a map of all the strings that were written to the buffer private var stringOffsetMap: [String: Offset] = [:] /// A check to see if finish(::) was ever called to retreive data object - private var finished = false + private(set) var finished = false /// A check to see if the buffer should serialize Default values private var serializeDefaults: Bool @@ -488,7 +488,7 @@ public struct FlatBufferBuilder { /// /// - Parameter bytes: bytes to be written into the buffer /// - Returns: ``Offset`` of the vector - mutating public func createVector(bytes: ContiguousBytes) -> Offset { + mutating public func createVector(bytes: any ContiguousBytes) -> Offset { bytes.withUnsafeBytes { startVector($0.count, elementSize: MemoryLayout.size) _bb.push(bytes: $0) diff --git a/swift/Sources/FlatBuffers/FlatBufferObject.swift b/swift/Sources/FlatBuffers/FlatBufferObject.swift index 0b9f01b070..a85f107365 100644 --- a/swift/Sources/FlatBuffers/FlatBufferObject.swift +++ b/swift/Sources/FlatBuffers/FlatBufferObject.swift @@ -20,6 +20,8 @@ import Foundation /// since now we will be serializing native structs into the buffer. public protocol NativeStruct {} +public protocol FlatBufferVerifiableNativeStruct: NativeStruct, Verifiable {} + /// FlatbuffersInitializable is a protocol that allows any object to be /// Initialized from a ByteBuffer public protocol FlatbuffersInitializable { @@ -35,6 +37,8 @@ public protocol FlatBufferTable: FlatbuffersInitializable, var __buffer: ByteBuffer! { get } } +public protocol FlatBufferVerifiableTable: FlatBufferTable, Verifiable {} + /// FlatbufferStruct structures all the Flatbuffers structs public protocol FlatBufferStruct: FlatbuffersInitializable, FlatbuffersVectorInitializable diff --git a/swift/Sources/FlatBuffers/Message.swift b/swift/Sources/FlatBuffers/Message.swift index a8cdbf8f07..37729a063b 100644 --- a/swift/Sources/FlatBuffers/Message.swift +++ b/swift/Sources/FlatBuffers/Message.swift @@ -16,50 +16,52 @@ import Foundation -/// FlatBufferGRPCMessage protocol that should allow us to invoke -/// initializers directly from the GRPC generated code -public protocol FlatBufferGRPCMessage { - /// Size of readable bytes in the buffer - var size: Int { get } +enum FlatbuffersGRPCError: Error { + case finishedNotCalledOnBuilder +} + +public protocol GRPCVerifiableMessage { + associatedtype Message + init(pointer: UnsafeRawBufferPointer) init(byteBuffer: ByteBuffer) - @discardableResult - @inline(__always) - func withUnsafeReadableBytes( + func decode() throws -> Message + func withUnsafeReadableBytes( _ body: (UnsafeRawBufferPointer) throws - -> T) rethrows -> T + -> Data) rethrows -> Data } -/// Message is a wrapper around Buffers to to able to send Flatbuffers `Buffers` through the -/// GRPC library -public struct Message: FlatBufferGRPCMessage { - internal var buffer: ByteBuffer - - /// Returns the an object of type T that would be read from the buffer - public var object: T { - T.init( - buffer, - o: Int32(buffer.read(def: UOffset.self, position: buffer.reader)) &+ - Int32(buffer.reader)) - } +public struct GRPCMessage< + Table: FlatBufferVerifiableTable +>: Sendable, GRPCVerifiableMessage { + public typealias Message = Table + + private let buffer: ByteBuffer public var size: Int { Int(buffer.size) } - /// Initializes the message with the type Flatbuffer.Bytebuffer that is transmitted over - /// GRPC - /// - Parameter byteBuffer: Flatbuffer ByteBuffer object + public init(pointer: UnsafeRawBufferPointer) { + buffer = ByteBuffer( + copyingMemoryBound: pointer.baseAddress!, + capacity: pointer.count) + } + + public init(builder: inout FlatBufferBuilder) throws { + guard builder.finished else { + throw FlatbuffersGRPCError.finishedNotCalledOnBuilder + } + + buffer = builder.sizedBuffer + } + public init(byteBuffer: ByteBuffer) { buffer = byteBuffer } - /// Initializes the message by copying the buffer to the message to be sent. - /// from the builder - /// - Parameter builder: FlatbufferBuilder that has the bytes created in - /// - Note: Use `builder.finish(offset)` before passing the builder without prefixing anything to it - public init(builder: inout FlatBufferBuilder) { - buffer = builder.sizedBuffer - builder.clear() + public func decode() throws -> Table { + var buf = buffer + return try getCheckedRoot(byteBuffer: &buf) } @discardableResult @@ -73,3 +75,30 @@ public struct Message: FlatBufferGRPCMessage { } } } + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +public struct FlatBuffersMessageSerializer< + Message: GRPCVerifiableMessage +>: Sendable { + public init() {} + + public func serialize( + message: Message, + _ completion: (UnsafeRawBufferPointer) throws -> Data) throws -> Data + { + return try message.withUnsafeReadableBytes { + try completion($0) + } + } +} + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +public struct FlatBuffersMessageDeserializer< + Message: GRPCVerifiableMessage +>: Sendable { + public init() {} + + public func deserialize(pointer: UnsafeRawBufferPointer) throws -> Message { + Message.init(pointer: pointer) + } +} diff --git a/swift/Sources/FlatBuffers/TableVerifier.swift b/swift/Sources/FlatBuffers/TableVerifier.swift index b09db49e6b..d4c4059dd1 100644 --- a/swift/Sources/FlatBuffers/TableVerifier.swift +++ b/swift/Sources/FlatBuffers/TableVerifier.swift @@ -115,7 +115,7 @@ public struct TableVerifier { unionKeyName: String, fieldName: String, required: Bool, - completion: @escaping (inout Verifier, T, Int) throws -> Void) throws + completion: (inout Verifier, T, Int) throws -> Void) throws where T: UnionEnum { let keyPos = try dereference(key) diff --git a/swift/Sources/FlatBuffers/Vectors/FlatbufferVector.swift b/swift/Sources/FlatBuffers/Vectors/FlatbufferVector.swift index a9b03582bd..fae8b4c13e 100644 --- a/swift/Sources/FlatBuffers/Vectors/FlatbufferVector.swift +++ b/swift/Sources/FlatBuffers/Vectors/FlatbufferVector.swift @@ -68,7 +68,7 @@ public struct FlatbufferVector< } extension FlatbufferVector: Encodable where Element: Encodable { - public func encode(to encoder: Encoder) throws { + public func encode(to encoder: any Encoder) throws { var container = encoder.unkeyedContainer() for element in self { try container.encode(element) diff --git a/swift/Sources/FlatBuffers/Vectors/UnionFlatbufferVector.swift b/swift/Sources/FlatBuffers/Vectors/UnionFlatbufferVector.swift index ab61e6fb17..7b595814f8 100644 --- a/swift/Sources/FlatBuffers/Vectors/UnionFlatbufferVector.swift +++ b/swift/Sources/FlatBuffers/Vectors/UnionFlatbufferVector.swift @@ -49,8 +49,8 @@ public struct UnionFlatbufferVector { public subscript( position: Int, - Type: FlatbuffersVectorInitializable - .Type) -> FlatbuffersVectorInitializable + Type: any FlatbuffersVectorInitializable + .Type) -> any FlatbuffersVectorInitializable { guard position < count else { fatalError( diff --git a/swift/Sources/FlatBuffers/_InternalByteBuffer.swift b/swift/Sources/FlatBuffers/_InternalByteBuffer.swift index 8dced85b41..e4ed2f08dc 100644 --- a/swift/Sources/FlatBuffers/_InternalByteBuffer.swift +++ b/swift/Sources/FlatBuffers/_InternalByteBuffer.swift @@ -146,7 +146,7 @@ struct _InternalByteBuffer { #if !os(WASI) @inline(__always) @usableFromInline - mutating func push(bytes: ContiguousBytes) { + mutating func push(bytes: any ContiguousBytes) { bytes.withUnsafeBytes { ptr in ensureSpace(size: ptr.count) memcpy( diff --git a/swift/Sources/FlexBuffers/ByteBuffer.swift b/swift/Sources/FlexBuffers/ByteBuffer.swift index af75631acc..f4dd2adb77 100644 --- a/swift/Sources/FlexBuffers/ByteBuffer.swift +++ b/swift/Sources/FlexBuffers/ByteBuffer.swift @@ -30,7 +30,7 @@ public struct ByteBuffer { enum Blob { #if !os(WASI) case data(Data) - case bytes(ContiguousBytes) + case bytes(any ContiguousBytes) #endif case byteBuffer(_InternalByteBuffer) diff --git a/swift/Sources/FlexBuffers/FlexBufferType.swift b/swift/Sources/FlexBuffers/FlexBufferType.swift index 4f51c5d287..2d75b2a883 100644 --- a/swift/Sources/FlexBuffers/FlexBufferType.swift +++ b/swift/Sources/FlexBuffers/FlexBufferType.swift @@ -16,7 +16,7 @@ import Foundation -public enum FlexBufferType: UInt64 { +public enum FlexBufferType: UInt64, Sendable { case null = 0 /// Variable width signed integer: `Int8, Int16, Int32, Int64` case int = 1 diff --git a/swift/Sources/FlexBuffers/Utils/BitWidth.swift b/swift/Sources/FlexBuffers/Utils/BitWidth.swift index d6205002a3..d4d8431a97 100644 --- a/swift/Sources/FlexBuffers/Utils/BitWidth.swift +++ b/swift/Sources/FlexBuffers/Utils/BitWidth.swift @@ -17,7 +17,7 @@ import Foundation @usableFromInline -enum BitWidth: UInt64, CaseIterable { +enum BitWidth: UInt64, CaseIterable, Sendable { case w8 = 0 case w16 = 1 case w32 = 2 diff --git a/swift/Sources/FlexBuffers/Utils/Value.swift b/swift/Sources/FlexBuffers/Utils/Value.swift index b9059feb31..36bda4a73f 100644 --- a/swift/Sources/FlexBuffers/Utils/Value.swift +++ b/swift/Sources/FlexBuffers/Utils/Value.swift @@ -20,10 +20,10 @@ import Foundation import Common #endif -public struct Value: Equatable { +public struct Value: Equatable, Sendable { @usableFromInline - enum Union: Equatable { + enum Union: Equatable, Sendable { case i(Int64) case u(UInt64) case f(Double) diff --git a/swift/Sources/FlexBuffers/Writer/FlexBuffersWriter.swift b/swift/Sources/FlexBuffers/Writer/FlexBuffersWriter.swift index 449ab5891a..77a4db7516 100644 --- a/swift/Sources/FlexBuffers/Writer/FlexBuffersWriter.swift +++ b/swift/Sources/FlexBuffers/Writer/FlexBuffersWriter.swift @@ -977,6 +977,9 @@ fileprivate struct Stack: RandomAccessCollection { mutating func removeAll(keepingCapacity keepCapacity: Bool = false) { count = 0 if !keepCapacity { + let ptr = storage.memory + defer { ptr.deallocate() } + capacity = Self.initialCapacity storage.memory = UnsafeMutableRawPointer.allocate( byteCount: capacity, diff --git a/tests/swift/Tests/Flatbuffers/ByteBufferTests.swift b/tests/swift/Tests/Flatbuffers/ByteBufferTests.swift index 4851e990af..ce8f12811b 100644 --- a/tests/swift/Tests/Flatbuffers/ByteBufferTests.swift +++ b/tests/swift/Tests/Flatbuffers/ByteBufferTests.swift @@ -128,5 +128,9 @@ private struct TestNativeStructs: NativeStruct { } extension MyGame_Example_Color: CaseIterable { - public static var allCases: [MyGame_Example_Color] = [.red, .blue, .green] + public static let allCases: [MyGame_Example_Color] = [ + .red, + .blue, + .green, + ] } diff --git a/tests/swift/Tests/Flatbuffers/FlatBuffersArraysTests.swift b/tests/swift/Tests/Flatbuffers/FlatBuffersArraysTests.swift index 7ea7b5b2df..4b85c595d1 100644 --- a/tests/swift/Tests/Flatbuffers/FlatBuffersArraysTests.swift +++ b/tests/swift/Tests/Flatbuffers/FlatBuffersArraysTests.swift @@ -26,6 +26,7 @@ final class FlatBuffersArraysTests: XCTestCase { func testStructSizes() { XCTAssertEqual(MemoryLayout.size, 32) XCTAssertEqual(MemoryLayout.size, 160) + XCTAssertEqual(MemoryLayout.size, 2496) } func testGoldenData() { @@ -233,4 +234,3 @@ extension InlineArray: @retroactive Equatable where Element: Equatable { } #endif - diff --git a/tests/swift/Tests/Flatbuffers/FlatBuffersMonsterWriterTests.swift b/tests/swift/Tests/Flatbuffers/FlatBuffersMonsterWriterTests.swift index d5e541c3ea..63679f248e 100644 --- a/tests/swift/Tests/Flatbuffers/FlatBuffersMonsterWriterTests.swift +++ b/tests/swift/Tests/Flatbuffers/FlatBuffersMonsterWriterTests.swift @@ -52,7 +52,7 @@ class FlatBuffersMonsterWriterTests: XCTestCase { #if os(macOS) // Gets the current path of this test file then // strips out the nested directories. - let filePath = URL(filePath: #file) + let filePath = URL(filePath: #filePath) .deletingLastPathComponent() return filePath.absoluteString #else @@ -331,7 +331,7 @@ class FlatBuffersMonsterWriterTests: XCTestCase { func testCreateMessage() { let fbb = createMonster(withPrefix: false) let byteBuffer = fbb.buffer - let firstMessage = Message(byteBuffer: byteBuffer) + let firstMessage = GRPCMessage(byteBuffer: byteBuffer) firstMessage.withUnsafeReadableBytes { ptr in var bytes = ByteBuffer(contiguousBytes: ptr, count: ptr.count) var monster: Monster = getRoot(byteBuffer: &bytes) @@ -339,7 +339,7 @@ class FlatBuffersMonsterWriterTests: XCTestCase { } let secondByteBuffer = fbb.sizedBuffer - let secondMessage = Message(byteBuffer: secondByteBuffer) + let secondMessage = GRPCMessage(byteBuffer: secondByteBuffer) secondMessage.withUnsafeReadableBytes { ptr in var bytes = ByteBuffer(contiguousBytes: ptr, count: ptr.count) var monster: Monster = getRoot(byteBuffer: &bytes) diff --git a/tests/swift/Tests/Flatbuffers/MutatingBool_generated.swift b/tests/swift/Tests/Flatbuffers/MutatingBool_generated.swift index e5771b9942..e2de1a1f68 100644 --- a/tests/swift/Tests/Flatbuffers/MutatingBool_generated.swift +++ b/tests/swift/Tests/Flatbuffers/MutatingBool_generated.swift @@ -74,7 +74,7 @@ public struct Property_Mutable: FlatBufferStruct, FlatbuffersVectorInitializable } } -public struct TestMutatingBool: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +public struct TestMutatingBool: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } diff --git a/tests/swift/Tests/Flatbuffers/arrays_test_generated.swift b/tests/swift/Tests/Flatbuffers/arrays_test_generated.swift index f9adfe3fc0..01a1391bf1 100644 --- a/tests/swift/Tests/Flatbuffers/arrays_test_generated.swift +++ b/tests/swift/Tests/Flatbuffers/arrays_test_generated.swift @@ -398,7 +398,7 @@ public struct MyGame_Example_LargeArrayStruct_Mutable: FlatBufferStruct, Flatbuf } @available(macOS 26.0, iOS 26.0, watchOS 26.0, tvOS 26.0, *) -public struct MyGame_Example_ArrayTable: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +public struct MyGame_Example_ArrayTable: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } diff --git a/tests/swift/Tests/Flatbuffers/empty_vtable_generated.swift b/tests/swift/Tests/Flatbuffers/empty_vtable_generated.swift index ed809f8c4d..8443bb2d1e 100644 --- a/tests/swift/Tests/Flatbuffers/empty_vtable_generated.swift +++ b/tests/swift/Tests/Flatbuffers/empty_vtable_generated.swift @@ -8,7 +8,7 @@ import Common import FlatBuffers -public struct DataModel_A: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +public struct DataModel_A: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } diff --git a/tests/swift/Tests/Flatbuffers/monster_test.grpc.swift b/tests/swift/Tests/Flatbuffers/monster_test.grpc.swift index cf7332ebfc..2829c67345 100644 --- a/tests/swift/Tests/Flatbuffers/monster_test.grpc.swift +++ b/tests/swift/Tests/Flatbuffers/monster_test.grpc.swift @@ -5,206 +5,568 @@ // swiftlint:disable all // swiftformat:disable all -#if !os(Windows) -import Foundation -import GRPC -import NIO -import NIOHTTP1 +#if !os(Windows) && compiler(>=6.0) import FlatBuffers - -public protocol GRPCFlatBufPayload: GRPCPayload, FlatBufferGRPCMessage {} -public extension GRPCFlatBufPayload { - init(serializedByteBuffer: inout NIO.ByteBuffer) throws { - self.init(byteBuffer: FlatBuffers.ByteBuffer(contiguousBytes: serializedByteBuffer.readableBytesView, count: serializedByteBuffer.readableBytes)) - } - func serialize(into buffer: inout NIO.ByteBuffer) throws { - withUnsafeReadableBytes { buffer.writeBytes($0) } +import Foundation +import GRPCCore +import GRPCNIOTransportCore + + +/// Usage: instantiate MyGame.Example.MonsterStorageServiceClient, then call methods of this protocol to make API calls. +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension FlatBuffersMessageSerializer: MessageSerializer { + public func serialize(_ message: Message) throws -> Bytes where Bytes : GRPCCore.GRPCContiguousBytes { + do { + return try self.serialize(message: message) { GRPCNIOTransportBytes($0) } as! Bytes + } catch let error { + throw RPCError( + code: .invalidArgument, + message: "Can't serialize message", + cause: error + ) + } } } -extension Message: GRPCFlatBufPayload {} - -/// Usage: instantiate MyGame_Example_MonsterStorageServiceClient, then call methods of this protocol to make API calls. -public protocol MyGame_Example_MonsterStorageClientProtocol: GRPCClient { - var serviceName: String { get } - - var interceptors: MyGame_Example_MonsterStorageClientInterceptorFactoryProtocol? { get } - - func Store( - _ request: Message - , callOptions: CallOptions? - ) -> UnaryCall, Message> - - func Retrieve( - _ request: Message - , callOptions: CallOptions?, - handler: @escaping (Message) -> Void - ) -> ServerStreamingCall, Message> - - func GetMaxHitPoint( - callOptions: CallOptions? - ) -> ClientStreamingCall, Message> +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension FlatBuffersMessageDeserializer: MessageDeserializer { + public func deserialize(_ serializedMessageBytes: Bytes) throws -> Message where Bytes : GRPCCore.GRPCContiguousBytes { + do { + return try serializedMessageBytes.withUnsafeBytes { + try self.deserialize(pointer: $0) + } + } catch let error { + throw RPCError( + code: .invalidArgument, + message: "Can't Decode message of type \(Message.self)", + cause: error + ) + } + } +} - func GetMinMaxHitPoints( - callOptions: CallOptions?, - handler: @escaping (Message ) -> Void - ) -> BidirectionalStreamingCall, Message> +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +public enum MyGame_Example_MonsterStorage: Sendable { + public static let descriptor = GRPCCore.ServiceDescriptor(fullyQualifiedService: "MyGame.Example.MonsterStorage") + public enum Method: Sendable { + public enum Store: Sendable { + public typealias Input = FlatBufferBuilder + public typealias Output = MyGame_Example_Stat + public static let descriptor = GRPCCore.MethodDescriptor( + service: GRPCCore.ServiceDescriptor(fullyQualifiedService: "MyGame.Example.MonsterStorage"), + method: "Store" + ) + } + public enum Retrieve: Sendable { + public typealias Input = FlatBufferBuilder + public typealias Output = MyGame_Example_Monster + public static let descriptor = GRPCCore.MethodDescriptor( + service: GRPCCore.ServiceDescriptor(fullyQualifiedService: "MyGame.Example.MonsterStorage"), + method: "Retrieve" + ) + } + public enum GetMaxHitPoint: Sendable { + public typealias Input = FlatBufferBuilder + public typealias Output = MyGame_Example_Stat + public static let descriptor = GRPCCore.MethodDescriptor( + service: GRPCCore.ServiceDescriptor(fullyQualifiedService: "MyGame.Example.MonsterStorage"), + method: "GetMaxHitPoint" + ) + } + public enum GetMinMaxHitPoints: Sendable { + public typealias Input = FlatBufferBuilder + public typealias Output = MyGame_Example_Stat + public static let descriptor = GRPCCore.MethodDescriptor( + service: GRPCCore.ServiceDescriptor(fullyQualifiedService: "MyGame.Example.MonsterStorage"), + method: "GetMinMaxHitPoints" + ) + } + public static let descriptors: [GRPCCore.MethodDescriptor] = [ + Store.descriptor, + Retrieve.descriptor, + GetMaxHitPoint.descriptor, + GetMinMaxHitPoints.descriptor, + ] + } +} +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension GRPCCore.ServiceDescriptor { + public static let MyGame_Example_MonsterStorage = GRPCCore.ServiceDescriptor(fullyQualifiedService: "MyGame.Example.MonsterStorage") } -extension MyGame_Example_MonsterStorageClientProtocol { +// MARK: MyGame.Example.MonsterStorage Server + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension MyGame_Example_MonsterStorage { + public protocol StreamingServiceProtocol: GRPCCore.RegistrableRPCService { + func Store( + request: GRPCCore.StreamingServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse> + + func Retrieve( + request: GRPCCore.StreamingServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse> + + func GetMaxHitPoint( + request: GRPCCore.StreamingServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse> + + func GetMinMaxHitPoints( + request: GRPCCore.StreamingServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse> + + } + + public protocol ServiceProtocol: MyGame_Example_MonsterStorage.StreamingServiceProtocol { + func Store( + request: GRPCCore.ServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.ServerResponse> + + func Retrieve( + request: GRPCCore.ServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse> + + func GetMaxHitPoint( + request: GRPCCore.StreamingServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.ServerResponse> + + func GetMinMaxHitPoints( + request: GRPCCore.StreamingServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse> + + } + + public protocol SimpleServiceProtocol: MyGame_Example_MonsterStorage.ServiceProtocol { + func Store( + request: GRPCMessage, + context: GRPCCore.ServerContext + ) async throws -> GRPCMessage + + func Retrieve( + request: GRPCMessage, + response: GRPCCore.RPCWriter>, + context: GRPCCore.ServerContext + ) async throws + + func GetMaxHitPoint( + request: GRPCCore.RPCAsyncSequence, any Swift.Error>, + context: GRPCCore.ServerContext + ) async throws -> GRPCMessage + + func GetMinMaxHitPoints( + request: GRPCCore.RPCAsyncSequence, any Swift.Error>, + response: GRPCCore.RPCWriter>, + context: GRPCCore.ServerContext + ) async throws + + } +} - public var serviceName: String { "MyGame.Example.MonsterStorage" } +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension MyGame_Example_MonsterStorage.StreamingServiceProtocol { + public func registerMethods(with router: inout GRPCCore.RPCRouter) where Transport: GRPCCore.ServerTransport { + router.registerHandler( + forMethod: MyGame_Example_MonsterStorage.Method.Store.descriptor, + deserializer: FlatBuffersMessageDeserializer>(), + serializer: FlatBuffersMessageSerializer>(), + handler: { request, context in + try await self.Store( + request: request, + context: context + ) + } + ) + router.registerHandler( + forMethod: MyGame_Example_MonsterStorage.Method.Retrieve.descriptor, + deserializer: FlatBuffersMessageDeserializer>(), + serializer: FlatBuffersMessageSerializer>(), + handler: { request, context in + try await self.Retrieve( + request: request, + context: context + ) + } + ) + router.registerHandler( + forMethod: MyGame_Example_MonsterStorage.Method.GetMaxHitPoint.descriptor, + deserializer: FlatBuffersMessageDeserializer>(), + serializer: FlatBuffersMessageSerializer>(), + handler: { request, context in + try await self.GetMaxHitPoint( + request: request, + context: context + ) + } + ) + router.registerHandler( + forMethod: MyGame_Example_MonsterStorage.Method.GetMinMaxHitPoints.descriptor, + deserializer: FlatBuffersMessageDeserializer>(), + serializer: FlatBuffersMessageSerializer>(), + handler: { request, context in + try await self.GetMinMaxHitPoints( + request: request, + context: context + ) + } + ) + } +} +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension MyGame_Example_MonsterStorage.ServiceProtocol { public func Store( - _ request: Message - , callOptions: CallOptions? = nil - ) -> UnaryCall, Message> { - return self.makeUnaryCall( - path: "/MyGame.Example.MonsterStorage/Store", - request: request, - callOptions: callOptions ?? self.defaultCallOptions, - interceptors: self.interceptors?.makeStoreInterceptors() ?? [] + request: GRPCCore.StreamingServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse> { + let response = try await self.Store( + request: GRPCCore.ServerRequest(stream: request), + context: context ) + return GRPCCore.StreamingServerResponse(single: response) } - public func Retrieve( - _ request: Message - , callOptions: CallOptions? = nil, - handler: @escaping (Message) -> Void - ) -> ServerStreamingCall, Message> { - return self.makeServerStreamingCall( - path: "/MyGame.Example.MonsterStorage/Retrieve", + request: GRPCCore.StreamingServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse> { + let response = try await self.Retrieve( + request: GRPCCore.ServerRequest(stream: request), + context: context + ) + return response + } + public func GetMaxHitPoint( + request: GRPCCore.StreamingServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse> { + let response = try await self.GetMaxHitPoint( request: request, - callOptions: callOptions ?? self.defaultCallOptions, - interceptors: self.interceptors?.makeRetrieveInterceptors() ?? [], - handler: handler + context: context ) + return GRPCCore.StreamingServerResponse(single: response) } +} +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension MyGame_Example_MonsterStorage.SimpleServiceProtocol { + public func Store( + request: GRPCCore.ServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.ServerResponse> { + return GRPCCore.ServerResponse>( + message: try await self.Store( + request: request.message, + context: context + ), + metadata: [:] + ) + } + public func Retrieve( + request: GRPCCore.ServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse> { + return GRPCCore.StreamingServerResponse>( + metadata: [:], + producer: { writer in + try await self.Retrieve( + request: request.message, + response: writer, + context: context + ) + return [:] + } + ) + } public func GetMaxHitPoint( - callOptions: CallOptions? = nil - ) -> ClientStreamingCall, Message> { - return self.makeClientStreamingCall( - path: "/MyGame.Example.MonsterStorage/GetMaxHitPoint", - callOptions: callOptions ?? self.defaultCallOptions, - interceptors: self.interceptors?.makeGetMaxHitPointInterceptors() ?? [] + request: GRPCCore.StreamingServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.ServerResponse> { + return GRPCCore.ServerResponse>( + message: try await self.GetMaxHitPoint( + request: request.messages, + context: context + ), + metadata: [:] ) } - public func GetMinMaxHitPoints( - callOptions: CallOptions? = nil, - handler: @escaping (Message ) -> Void - ) -> BidirectionalStreamingCall, Message> { - return self.makeBidirectionalStreamingCall( - path: "/MyGame.Example.MonsterStorage/GetMinMaxHitPoints", - callOptions: callOptions ?? self.defaultCallOptions, - interceptors: self.interceptors?.makeGetMinMaxHitPointsInterceptors() ?? [], - handler: handler + request: GRPCCore.StreamingServerRequest>, + context: GRPCCore.ServerContext + ) async throws -> GRPCCore.StreamingServerResponse> { + return GRPCCore.StreamingServerResponse>( + metadata: [:], + producer: { writer in + try await self.GetMinMaxHitPoints( + request: request.messages, + response: writer, + context: context + ) + return [:] + } ) } } -public protocol MyGame_Example_MonsterStorageClientInterceptorFactoryProtocol { - /// - Returns: Interceptors to use when invoking 'Store'. - func makeStoreInterceptors() -> [ClientInterceptor, Message>] - - /// - Returns: Interceptors to use when invoking 'Retrieve'. - func makeRetrieveInterceptors() -> [ClientInterceptor, Message>] - - /// - Returns: Interceptors to use when invoking 'GetMaxHitPoint'. - func makeGetMaxHitPointInterceptors() -> [ClientInterceptor, Message>] - - /// - Returns: Interceptors to use when invoking 'GetMinMaxHitPoints'. - func makeGetMinMaxHitPointsInterceptors() -> [ClientInterceptor, Message>] +// MARK: MyGame.Example.MonsterStorage Client + +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension MyGame_Example_MonsterStorage { + public protocol ClientProtocol: Sendable { + func Store( + request: GRPCCore.ClientRequest>, + serializer: some GRPCCore.MessageSerializer>, + deserializer: some GRPCCore.MessageDeserializer>, + options: GRPCCore.CallOptions, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse>) async throws -> Result + ) async throws -> Result where Result: Sendable + + func Retrieve( + request: GRPCCore.ClientRequest>, + serializer: some GRPCCore.MessageSerializer>, + deserializer: some GRPCCore.MessageDeserializer>, + options: GRPCCore.CallOptions, + onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse>) async throws -> Result + ) async throws -> Result where Result: Sendable + + func GetMaxHitPoint( + request: GRPCCore.StreamingClientRequest>, + serializer: some GRPCCore.MessageSerializer>, + deserializer: some GRPCCore.MessageDeserializer>, + options: GRPCCore.CallOptions, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse>) async throws -> Result + ) async throws -> Result where Result: Sendable + + func GetMinMaxHitPoints( + request: GRPCCore.StreamingClientRequest>, + serializer: some GRPCCore.MessageSerializer>, + deserializer: some GRPCCore.MessageDeserializer>, + options: GRPCCore.CallOptions, + onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse>) async throws -> Result + ) async throws -> Result where Result: Sendable + + } } -public final class MyGame_Example_MonsterStorageServiceClient: MyGame_Example_MonsterStorageClientProtocol { - public let channel: GRPCChannel - public var defaultCallOptions: CallOptions - public var interceptors: MyGame_Example_MonsterStorageClientInterceptorFactoryProtocol? - - public init( - channel: GRPCChannel, - defaultCallOptions: CallOptions = CallOptions(), - interceptors: MyGame_Example_MonsterStorageClientInterceptorFactoryProtocol? = nil - ) { - self.channel = channel - self.defaultCallOptions = defaultCallOptions - self.interceptors = interceptors +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension MyGame_Example_MonsterStorage { + public struct Client: ClientProtocol where Transport: GRPCCore.ClientTransport { + private let client: GRPCCore.GRPCClient + + public init(wrapping client: GRPCCore.GRPCClient) { + self.client = client + } + + public func Store( + request: GRPCCore.ClientRequest>, + serializer: some GRPCCore.MessageSerializer>, + deserializer: some GRPCCore.MessageDeserializer>, + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse>) async throws -> Result = { response in try response.message } + ) async throws -> Result where Result: Sendable { + try await self.client.unary( + request: request, + descriptor: MyGame_Example_MonsterStorage.Method.Store.descriptor, + serializer: serializer, + deserializer: deserializer, + options: options, + onResponse: handleResponse + ) + } + + public func Retrieve( + request: GRPCCore.ClientRequest>, + serializer: some GRPCCore.MessageSerializer>, + deserializer: some GRPCCore.MessageDeserializer>, + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse>) async throws -> Result + ) async throws -> Result where Result: Sendable { + try await self.client.serverStreaming( + request: request, + descriptor: MyGame_Example_MonsterStorage.Method.Retrieve.descriptor, + serializer: serializer, + deserializer: deserializer, + options: options, + onResponse: handleResponse + ) + } + + public func GetMaxHitPoint( + request: GRPCCore.StreamingClientRequest>, + serializer: some GRPCCore.MessageSerializer>, + deserializer: some GRPCCore.MessageDeserializer>, + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse>) async throws -> Result = { response in try response.message } + ) async throws -> Result where Result: Sendable { + try await self.client.clientStreaming( + request: request, + descriptor: MyGame_Example_MonsterStorage.Method.GetMaxHitPoint.descriptor, + serializer: serializer, + deserializer: deserializer, + options: options, + onResponse: handleResponse + ) + } + + public func GetMinMaxHitPoints( + request: GRPCCore.StreamingClientRequest>, + serializer: some GRPCCore.MessageSerializer>, + deserializer: some GRPCCore.MessageDeserializer>, + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse>) async throws -> Result + ) async throws -> Result where Result: Sendable { + try await self.client.bidirectionalStreaming( + request: request, + descriptor: MyGame_Example_MonsterStorage.Method.GetMinMaxHitPoints.descriptor, + serializer: serializer, + deserializer: deserializer, + options: options, + onResponse: handleResponse + ) + } + } } -public protocol MyGame_Example_MonsterStorageProvider: CallHandlerProvider { - var interceptors: MyGame_Example_MonsterStorageServerInterceptorFactoryProtocol? { get } - func Store(request: Message, context: StatusOnlyCallContext) -> EventLoopFuture> - func Retrieve(request: Message, context: StreamingResponseCallContext>) -> EventLoopFuture - func GetMaxHitPoint(context: UnaryResponseCallContext>) -> EventLoopFuture<(StreamEvent>) -> Void> - func GetMinMaxHitPoints(context: StreamingResponseCallContext>) -> EventLoopFuture<(StreamEvent>) -> Void> +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension MyGame_Example_MonsterStorage.ClientProtocol { + public func Store( + request: GRPCCore.ClientRequest>, + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse>) async throws -> Result = { response in try response.message } + ) async throws -> Result where Result: Sendable { + try await self.Store( + request: request, + serializer: FlatBuffersMessageSerializer>(), + deserializer: FlatBuffersMessageDeserializer>(), + options: options, + onResponse: handleResponse + ) + } + + public func Retrieve( + request: GRPCCore.ClientRequest>, + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse>) async throws -> Result + ) async throws -> Result where Result: Sendable { + try await self.Retrieve( + request: request, + serializer: FlatBuffersMessageSerializer>(), + deserializer: FlatBuffersMessageDeserializer>(), + options: options, + onResponse: handleResponse + ) + } + + public func GetMaxHitPoint( + request: GRPCCore.StreamingClientRequest>, + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse>) async throws -> Result = { response in try response.message } + ) async throws -> Result where Result: Sendable { + try await self.GetMaxHitPoint( + request: request, + serializer: FlatBuffersMessageSerializer>(), + deserializer: FlatBuffersMessageDeserializer>(), + options: options, + onResponse: handleResponse + ) + } + + public func GetMinMaxHitPoints( + request: GRPCCore.StreamingClientRequest>, + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse>) async throws -> Result + ) async throws -> Result where Result: Sendable { + try await self.GetMinMaxHitPoints( + request: request, + serializer: FlatBuffersMessageSerializer>(), + deserializer: FlatBuffersMessageDeserializer>(), + options: options, + onResponse: handleResponse + ) + } + } -public extension MyGame_Example_MonsterStorageProvider { - - var serviceName: Substring { return "MyGame.Example.MonsterStorage" } - - func handle(method name: Substring, context: CallHandlerContext) -> GRPCServerHandlerProtocol? { - switch name { - case "Store": - return UnaryServerHandler( - context: context, - requestDeserializer: GRPCPayloadDeserializer>(), - responseSerializer: GRPCPayloadSerializer>(), - interceptors: self.interceptors?.makeStoreInterceptors() ?? [], - userFunction: self.Store(request:context:)) - - case "Retrieve": - return ServerStreamingServerHandler( - context: context, - requestDeserializer: GRPCPayloadDeserializer>(), - responseSerializer: GRPCPayloadSerializer>(), - interceptors: self.interceptors?.makeRetrieveInterceptors() ?? [], - userFunction: self.Retrieve(request:context:)) - - case "GetMaxHitPoint": - return ClientStreamingServerHandler( - context: context, - requestDeserializer: GRPCPayloadDeserializer>(), - responseSerializer: GRPCPayloadSerializer>(), - interceptors: self.interceptors?.makeGetMaxHitPointInterceptors() ?? [], - observerFactory: self.GetMaxHitPoint(context:)) - - case "GetMinMaxHitPoints": - return BidirectionalStreamingServerHandler( - context: context, - requestDeserializer: GRPCPayloadDeserializer>(), - responseSerializer: GRPCPayloadSerializer>(), - interceptors: self.interceptors?.makeGetMinMaxHitPointsInterceptors() ?? [], - observerFactory: self.GetMinMaxHitPoints(context:)) - - default: return nil; - } +@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) +extension MyGame_Example_MonsterStorage.ClientProtocol { + public func Store( + _ message: GRPCMessage, + metadata: GRPCCore.Metadata = [:], + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse>) async throws -> Result = { try $0.message } + ) async throws -> Result where Result: Sendable { + let request = GRPCCore.ClientRequest>( + message: message, + metadata: metadata + ) + return try await self.Store( + request: request, + options: options, + onResponse: handleResponse + ) } - + + public func Retrieve( + _ message: GRPCMessage, + metadata: GRPCCore.Metadata = [:], + options: GRPCCore.CallOptions = .defaults, + onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse>) async throws -> Result + ) async throws -> Result where Result: Sendable { + let request = GRPCCore.ClientRequest>( + message: message, + metadata: metadata + ) + return try await self.Retrieve( + request: request, + options: options, + onResponse: handleResponse + ) + } + + public func GetMaxHitPoint( + metadata: GRPCCore.Metadata = [:], + options: GRPCCore.CallOptions = .defaults, + requestProducer producer: @Sendable @escaping (GRPCCore.RPCWriter>) async throws -> Void, + onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse>) async throws -> Result = { try $0.message } + ) async throws -> Result where Result: Sendable { + let request = GRPCCore.StreamingClientRequest>( + metadata: metadata, + producer: producer + ) + return try await self.GetMaxHitPoint( + request: request, + options: options, + onResponse: handleResponse + ) + } + + public func GetMinMaxHitPoints( + metadata: GRPCCore.Metadata = [:], + options: GRPCCore.CallOptions = .defaults, + requestProducer producer: @Sendable @escaping (GRPCCore.RPCWriter>) async throws -> Void, + onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse>) async throws -> Result + ) async throws -> Result where Result: Sendable { + let request = GRPCCore.StreamingClientRequest>( + metadata: metadata, + producer: producer + ) + return try await self.GetMinMaxHitPoints( + request: request, + options: options, + onResponse: handleResponse + ) + } + } -public protocol MyGame_Example_MonsterStorageServerInterceptorFactoryProtocol { - /// - Returns: Interceptors to use when handling 'Store'. - /// Defaults to calling `self.makeInterceptors()`. - func makeStoreInterceptors() -> [ServerInterceptor, Message>] - - /// - Returns: Interceptors to use when handling 'Retrieve'. - /// Defaults to calling `self.makeInterceptors()`. - func makeRetrieveInterceptors() -> [ServerInterceptor, Message>] - - /// - Returns: Interceptors to use when handling 'GetMaxHitPoint'. - /// Defaults to calling `self.makeInterceptors()`. - func makeGetMaxHitPointInterceptors() -> [ServerInterceptor, Message>] - - /// - Returns: Interceptors to use when handling 'GetMinMaxHitPoints'. - /// Defaults to calling `self.makeInterceptors()`. - func makeGetMinMaxHitPointsInterceptors() -> [ServerInterceptor, Message>] - -} #endif diff --git a/tests/swift/Tests/Flatbuffers/monster_test_generated.swift b/tests/swift/Tests/Flatbuffers/monster_test_generated.swift index e6311fadcc..0dc49b02db 100644 --- a/tests/swift/Tests/Flatbuffers/monster_test_generated.swift +++ b/tests/swift/Tests/Flatbuffers/monster_test_generated.swift @@ -662,7 +662,7 @@ public struct MyGame_Example_StructOfStructsOfStructs_Mutable: FlatBufferStruct, } } -public struct MyGame_InParentNamespace: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +public struct MyGame_InParentNamespace: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -712,7 +712,7 @@ public class MyGame_InParentNamespaceT: NativeObject { public func serialize() -> ByteBuffer { return serialize(type: MyGame_InParentNamespace.self) } } -public struct MyGame_Example2_Monster: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +public struct MyGame_Example2_Monster: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -762,7 +762,7 @@ public class MyGame_Example2_MonsterT: NativeObject { public func serialize() -> ByteBuffer { return serialize(type: MyGame_Example2_Monster.self) } } -internal struct MyGame_Example_TestSimpleTableWithEnum: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +internal struct MyGame_Example_TestSimpleTableWithEnum: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } internal var __buffer: ByteBuffer! { return _accessor.bb } @@ -840,7 +840,7 @@ internal class MyGame_Example_TestSimpleTableWithEnumT: NativeObject { internal func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_TestSimpleTableWithEnum.self) } } -public struct MyGame_Example_Stat: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +public struct MyGame_Example_Stat: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -976,7 +976,7 @@ public class MyGame_Example_StatT: NativeObject { public func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_Stat.self) } } -public struct MyGame_Example_Referrable: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +public struct MyGame_Example_Referrable: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -1079,7 +1079,7 @@ public class MyGame_Example_ReferrableT: NativeObject { } /// an example documentation comment: "monster object" -public struct MyGame_Example_Monster: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +public struct MyGame_Example_Monster: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -2213,7 +2213,7 @@ public class MyGame_Example_MonsterT: NativeObject { public func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_Monster.self) } } -public struct MyGame_Example_TypeAliases: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +public struct MyGame_Example_TypeAliases: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } diff --git a/tests/swift/Tests/Flatbuffers/more_defaults_generated.swift b/tests/swift/Tests/Flatbuffers/more_defaults_generated.swift index 78c6680b05..e1806cfe6e 100644 --- a/tests/swift/Tests/Flatbuffers/more_defaults_generated.swift +++ b/tests/swift/Tests/Flatbuffers/more_defaults_generated.swift @@ -31,7 +31,7 @@ extension ABC: Encodable { } } -public struct MoreDefaults: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +public struct MoreDefaults: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } diff --git a/tests/swift/Tests/Flatbuffers/nan_inf_test_generated.swift b/tests/swift/Tests/Flatbuffers/nan_inf_test_generated.swift index c850fa1dba..8c15bc1bca 100644 --- a/tests/swift/Tests/Flatbuffers/nan_inf_test_generated.swift +++ b/tests/swift/Tests/Flatbuffers/nan_inf_test_generated.swift @@ -8,7 +8,7 @@ import Common import FlatBuffers -public struct Swift_Tests_NanInfTable: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable { +public struct Swift_Tests_NanInfTable: FlatBufferVerifiableTable, FlatbuffersVectorInitializable { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } diff --git a/tests/swift/Tests/Flatbuffers/optional_scalars_generated.swift b/tests/swift/Tests/Flatbuffers/optional_scalars_generated.swift index 16d21697bf..7c1e68287a 100644 --- a/tests/swift/Tests/Flatbuffers/optional_scalars_generated.swift +++ b/tests/swift/Tests/Flatbuffers/optional_scalars_generated.swift @@ -31,7 +31,7 @@ extension optional_scalars_OptionalByte: Encodable { } } -public struct optional_scalars_ScalarStuff: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable { +public struct optional_scalars_ScalarStuff: FlatBufferVerifiableTable, FlatbuffersVectorInitializable { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } diff --git a/tests/swift/Tests/Flatbuffers/union_vector_generated.swift b/tests/swift/Tests/Flatbuffers/union_vector_generated.swift index 3d2bc56d20..fd12ffeca3 100644 --- a/tests/swift/Tests/Flatbuffers/union_vector_generated.swift +++ b/tests/swift/Tests/Flatbuffers/union_vector_generated.swift @@ -320,7 +320,7 @@ public struct FallingTub_Mutable: FlatBufferStruct, FlatbuffersVectorInitializab } } -public struct Attacker: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +public struct Attacker: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -398,7 +398,7 @@ public class AttackerT: NativeObject { public func serialize() -> ByteBuffer { return serialize(type: Attacker.self) } } -public struct HandFan: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +public struct HandFan: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -476,7 +476,7 @@ public class HandFanT: NativeObject { public func serialize() -> ByteBuffer { return serialize(type: HandFan.self) } } -public struct Movie: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +public struct Movie: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } diff --git a/tests/swift/Tests/Flatbuffers/vector_has_test_generated.swift b/tests/swift/Tests/Flatbuffers/vector_has_test_generated.swift index 48f578f653..2466703e44 100644 --- a/tests/swift/Tests/Flatbuffers/vector_has_test_generated.swift +++ b/tests/swift/Tests/Flatbuffers/vector_has_test_generated.swift @@ -8,7 +8,7 @@ import Common import FlatBuffers -public struct Swift_Tests_Vectors: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable { +public struct Swift_Tests_Vectors: FlatBufferVerifiableTable, FlatbuffersVectorInitializable { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } diff --git a/tests/swift/Tests/Flexbuffers/FlexBuffersReaderTests.swift b/tests/swift/Tests/Flexbuffers/FlexBuffersReaderTests.swift index dbbc637fd5..42ecad3a5f 100644 --- a/tests/swift/Tests/Flexbuffers/FlexBuffersReaderTests.swift +++ b/tests/swift/Tests/Flexbuffers/FlexBuffersReaderTests.swift @@ -127,7 +127,7 @@ final class FlexBuffersReaderTests: XCTestCase { #if os(macOS) // Gets the current path of this test file then // strips out the nested directories. - let filePath = URL(filePath: #file) + let filePath = URL(filePath: #filePath) .deletingLastPathComponent() .deletingLastPathComponent() .deletingLastPathComponent() @@ -136,5 +136,4 @@ final class FlexBuffersReaderTests: XCTestCase { return FileManager.default.currentDirectoryPath #endif } - } diff --git a/tests/swift/Wasm.tests/Tests/FlatBuffers.Test.Swift.WasmTests/monster_test_generated.swift b/tests/swift/Wasm.tests/Tests/FlatBuffers.Test.Swift.WasmTests/monster_test_generated.swift index e6311fadcc..0dc49b02db 100644 --- a/tests/swift/Wasm.tests/Tests/FlatBuffers.Test.Swift.WasmTests/monster_test_generated.swift +++ b/tests/swift/Wasm.tests/Tests/FlatBuffers.Test.Swift.WasmTests/monster_test_generated.swift @@ -662,7 +662,7 @@ public struct MyGame_Example_StructOfStructsOfStructs_Mutable: FlatBufferStruct, } } -public struct MyGame_InParentNamespace: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +public struct MyGame_InParentNamespace: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -712,7 +712,7 @@ public class MyGame_InParentNamespaceT: NativeObject { public func serialize() -> ByteBuffer { return serialize(type: MyGame_InParentNamespace.self) } } -public struct MyGame_Example2_Monster: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +public struct MyGame_Example2_Monster: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -762,7 +762,7 @@ public class MyGame_Example2_MonsterT: NativeObject { public func serialize() -> ByteBuffer { return serialize(type: MyGame_Example2_Monster.self) } } -internal struct MyGame_Example_TestSimpleTableWithEnum: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +internal struct MyGame_Example_TestSimpleTableWithEnum: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } internal var __buffer: ByteBuffer! { return _accessor.bb } @@ -840,7 +840,7 @@ internal class MyGame_Example_TestSimpleTableWithEnumT: NativeObject { internal func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_TestSimpleTableWithEnum.self) } } -public struct MyGame_Example_Stat: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +public struct MyGame_Example_Stat: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -976,7 +976,7 @@ public class MyGame_Example_StatT: NativeObject { public func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_Stat.self) } } -public struct MyGame_Example_Referrable: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +public struct MyGame_Example_Referrable: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -1079,7 +1079,7 @@ public class MyGame_Example_ReferrableT: NativeObject { } /// an example documentation comment: "monster object" -public struct MyGame_Example_Monster: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +public struct MyGame_Example_Monster: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -2213,7 +2213,7 @@ public class MyGame_Example_MonsterT: NativeObject { public func serialize() -> ByteBuffer { return serialize(type: MyGame_Example_Monster.self) } } -public struct MyGame_Example_TypeAliases: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +public struct MyGame_Example_TypeAliases: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } diff --git a/tests/swift/fuzzer/CodeGenerationTests/test_import_generated.swift b/tests/swift/fuzzer/CodeGenerationTests/test_import_generated.swift index 7391dc9c94..6c2adbaecc 100644 --- a/tests/swift/fuzzer/CodeGenerationTests/test_import_generated.swift +++ b/tests/swift/fuzzer/CodeGenerationTests/test_import_generated.swift @@ -3,12 +3,12 @@ // swiftformat:disable all #if canImport(Common) -@_implementationOnly import Common +internal import Common #endif -@_implementationOnly import FlatBuffers +internal import FlatBuffers -internal struct Message: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +internal struct Message: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } internal var __buffer: ByteBuffer! { return _accessor.bb } diff --git a/tests/swift/fuzzer/CodeGenerationTests/test_no_include_generated.swift b/tests/swift/fuzzer/CodeGenerationTests/test_no_include_generated.swift index afb146d7bb..0cd9933d35 100644 --- a/tests/swift/fuzzer/CodeGenerationTests/test_no_include_generated.swift +++ b/tests/swift/fuzzer/CodeGenerationTests/test_no_include_generated.swift @@ -68,7 +68,7 @@ public struct BytesCount_Mutable: FlatBufferStruct, FlatbuffersVectorInitializab } } -public struct InternalMessage: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +public struct InternalMessage: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } @@ -148,7 +148,7 @@ public class InternalMessageT: NativeObject { public func serialize() -> ByteBuffer { return serialize(type: InternalMessage.self) } } -public struct Message: FlatBufferTable, FlatbuffersVectorInitializable, Verifiable, ObjectAPIPacker { +public struct Message: FlatBufferVerifiableTable, FlatbuffersVectorInitializable, ObjectAPIPacker { static func validateVersion() { FlatBuffersVersion_25_12_19() } public var __buffer: ByteBuffer! { return _accessor.bb } From dd36b4ab4ed1825ad2b3602b6151c0472365ed41 Mon Sep 17 00:00:00 2001 From: Mustii <26250654+mustiikhalil@users.noreply.github.com> Date: Tue, 5 May 2026 16:08:14 +0200 Subject: [PATCH 2/2] Address PR comments regarding misspelling & proper method naming. --- grpc/src/compiler/swift_generator.cc | 74 ++++++++++++++-------------- src/idl_gen_swift.cpp | 5 +- 2 files changed, 39 insertions(+), 40 deletions(-) diff --git a/grpc/src/compiler/swift_generator.cc b/grpc/src/compiler/swift_generator.cc index 7286306f5e..68c6a204c5 100644 --- a/grpc/src/compiler/swift_generator.cc +++ b/grpc/src/compiler/swift_generator.cc @@ -45,19 +45,19 @@ static std::string StreamingServerResponse() { static std::string QualifiedName(const std::vector& components, const grpc::string& name, - const std::string separator = "_") { + const std::string& separator = "_") { std::string qualified_name; for (auto it = components.begin(); it != components.end(); ++it) qualified_name += *it + separator; return qualified_name + name; } -static std::string GenerateGRPCMessage(const std::string name) { +static std::string GenerateGRPCMessage(const std::string& name) { return "GRPCMessage<" + name + ">"; } -static std::string GenerateType(const std::string name, - const std::string wrapper) { +static std::string GenerateType(const std::string& name, + const std::string& wrapper) { return wrapper + "<" + GenerateGRPCMessage(name) + ">"; } @@ -105,9 +105,9 @@ void EnforceOSVersion(grpc_generator::Printer* printer) { "*)\n"); } -void Method(grpc_generator::Printer* printer, - std::map* dictonary) { - auto vars = *dictonary; +void GenerateMethodDescriptor(grpc_generator::Printer* printer, + std::map* dictionary) { + auto vars = *dictionary; printer->Print(vars, "$ACCESS$ enum $MethodName$: Sendable {\n"); printer->Indent(); printer->Print(vars, "$ACCESS$ typealias Input = FlatBufferBuilder\n"); @@ -192,8 +192,8 @@ void GenerateCoders(grpc_generator::Printer* printer) { void GenerateSharedContent(const grpc_generator::Service* service, grpc_generator::Printer* printer, - std::map* dictonary) { - auto vars = *dictonary; + std::map* dictionary) { + auto vars = *dictionary; EnforceOSVersion(printer); printer->Print(vars, "$ACCESS$ enum $SwiftServiceQualifiedName$: Sendable {\n"); @@ -215,7 +215,7 @@ void GenerateSharedContent(const grpc_generator::Service* service, auto name = method->name(); vars["MethodName"] = name; descriptors.push_back(name); - Method(printer, &vars); + GenerateMethodDescriptor(printer, &vars); } printer->Print( @@ -248,8 +248,8 @@ void GenerateSharedContent(const grpc_generator::Service* service, // Service Generation void GenerateFunction(grpc_generator::Printer* printer, - std::map* dictonary) { - auto vars = *dictonary; + std::map* dictionary) { + auto vars = *dictionary; printer->Print(vars, "func $MethodName$(\n"); printer->Indent(); @@ -262,8 +262,8 @@ void GenerateFunction(grpc_generator::Printer* printer, void GenerateServiceProtocols(const grpc_generator::Service* service, grpc_generator::Printer* printer, - std::map* dictonary) { - auto vars = *dictonary; + std::map* dictionary) { + auto vars = *dictionary; EnforceOSVersion(printer); printer->Print(vars, "extension $SwiftServiceQualifiedName$ {\n"); printer->Indent(); @@ -421,8 +421,8 @@ void GenerateServiceProtocols(const grpc_generator::Service* service, void CreateServiceProtocolFunctionsImplementations( grpc_generator::Printer* printer, - std::map* dictonary) { - auto vars = *dictonary; + std::map* dictionary) { + auto vars = *dictionary; printer->Print(vars, "$ACCESS$ func $MethodName$(\n"); printer->Indent(); printer->Print(vars, "request: $Input$,\n"); @@ -455,8 +455,8 @@ std::string GenerateOutputResponse(const grpc_generator::Method* method) { void GenerateServiceDefaultImplementation( const grpc_generator::Service* service, grpc_generator::Printer* printer, - std::map* dictonary) { - auto vars = *dictonary; + std::map* dictionary) { + auto vars = *dictionary; EnforceOSVersion(printer); printer->Print(vars, "extension $SwiftServiceQualifiedName$.ServiceProtocol {\n"); @@ -491,8 +491,8 @@ void GenerateServiceDefaultImplementation( void GenerateSimpleServiceImplemetation( const grpc_generator::Service* service, grpc_generator::Printer* printer, - std::map* dictonary) { - auto vars = *dictonary; + std::map* dictionary) { + auto vars = *dictionary; EnforceOSVersion(printer); printer->Print( vars, "extension $SwiftServiceQualifiedName$.SimpleServiceProtocol {\n"); @@ -560,18 +560,18 @@ void GenerateSimpleServiceImplemetation( void GenerateService(const grpc_generator::Service* service, grpc_generator::Printer* printer, - std::map* dictonary) { - GenerateServiceProtocols(service, printer, dictonary); - GenerateServiceDefaultImplementation(service, printer, dictonary); - GenerateSimpleServiceImplemetation(service, printer, dictonary); + std::map* dictionary) { + GenerateServiceProtocols(service, printer, dictionary); + GenerateServiceDefaultImplementation(service, printer, dictionary); + GenerateSimpleServiceImplemetation(service, printer, dictionary); } // Client Generation void GenerateClientProtocols(const grpc_generator::Service* service, grpc_generator::Printer* printer, - std::map* dictonary) { - auto vars = *dictonary; + std::map* dictionary) { + auto vars = *dictionary; EnforceOSVersion(printer); printer->Print(vars, "extension $SwiftServiceQualifiedName$ {\n"); printer->Indent(); @@ -639,8 +639,8 @@ void GenerateClientProtocols(const grpc_generator::Service* service, void GenerateClientStruct(const grpc_generator::Service* service, grpc_generator::Printer* printer, - std::map* dictonary) { - auto vars = *dictonary; + std::map* dictionary) { + auto vars = *dictionary; EnforceOSVersion(printer); printer->Print(vars, "extension $SwiftServiceQualifiedName$ {\n"); printer->Indent(); @@ -737,8 +737,8 @@ void GenerateClientStruct(const grpc_generator::Service* service, void GenerateClientDefaultImplementation( const grpc_generator::Service* service, grpc_generator::Printer* printer, - std::map* dictonary) { - auto vars = *dictonary; + std::map* dictionary) { + auto vars = *dictionary; EnforceOSVersion(printer); printer->Print(vars, "extension $SwiftServiceQualifiedName$.ClientProtocol {\n"); @@ -814,8 +814,8 @@ void GenerateClientDefaultImplementation( void GenerateClientHelperMethods( const grpc_generator::Service* service, grpc_generator::Printer* printer, - std::map* dictonary) { - auto vars = *dictonary; + std::map* dictionary) { + auto vars = *dictionary; EnforceOSVersion(printer); printer->Print(vars, @@ -921,11 +921,11 @@ void GenerateClientHelperMethods( void GenerateClient(const grpc_generator::Service* service, grpc_generator::Printer* printer, - std::map* dictonary) { - GenerateClientProtocols(service, printer, dictonary); - GenerateClientStruct(service, printer, dictonary); - GenerateClientDefaultImplementation(service, printer, dictonary); - GenerateClientHelperMethods(service, printer, dictonary); + std::map* dictionary) { + GenerateClientProtocols(service, printer, dictionary); + GenerateClientStruct(service, printer, dictionary); + GenerateClientDefaultImplementation(service, printer, dictionary); + GenerateClientHelperMethods(service, printer, dictionary); } } // namespace diff --git a/src/idl_gen_swift.cpp b/src/idl_gen_swift.cpp index e506013ec6..437722f471 100644 --- a/src/idl_gen_swift.cpp +++ b/src/idl_gen_swift.cpp @@ -170,9 +170,8 @@ class SwiftGenerator : public BaseGenerator { code_ += "// swiftformat:disable all\n"; if (parser_.opts.include_dependence_headers || parser_.opts.generate_all) { - code_.SetValue("IMPLEMENTONLY", parser_.opts.swift_implementation_only - ? "internal " - : ""); + code_.SetValue("IMPLEMENTONLY", + parser_.opts.swift_implementation_only ? "internal " : ""); code_ += "#if canImport(Common)"; code_ += "{{IMPLEMENTONLY}}import Common"; code_ += "#endif";