[Swift] Migrate to swift 6.0 and Implements support gRPC v2 (#8983)
* 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
* Address PR comments regarding misspelling & proper method naming.
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index c7cae71..a5a6bab 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -495,7 +495,7 @@
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 4f60a8c..4139903 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 @@
.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 @@
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 @@
[]
#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 @@
#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 0000000..483abcc
--- /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 664f2a0..3fc96ad 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 @@
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",
+ .executableTarget(
+ name: "Commands",
dependencies: [
- "GRPC",
- "Model",
- ],
- path: "Sources/client"),
-
- // Server for the Greeter example
- .target(
- name: "Server",
- 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 0000000..50315b4
--- /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 0000000..74b57c7
--- /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<models_HelloResponse>,
+ context: GRPCCore
+ .ServerContext) async throws -> GRPCMessage<models_HelloResponse>
+ {
+ 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<models_HelloResponse>(builder: &builder)
+ }
+
+ func Collect(
+ request: GRPCCore.RPCAsyncSequence<
+ GRPCMessage<models_HelloResponse>,
+ any Swift.Error
+ >,
+ context: GRPCCore
+ .ServerContext) async throws -> GRPCMessage<models_HelloResponse>
+ {
+ 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<models_HelloResponse>(builder: &builder)
+ }
+
+ func Expand(
+ request: GRPCMessage<models_HelloResponse>,
+ response: GRPCCore.RPCWriter<GRPCMessage<models_HelloResponse>>,
+ context: GRPCCore.ServerContext) async throws
+ {
+
+ let model = try request.decode()
+ print("## GreeterService.Expand: \(model.message)")
+
+ let message = model.message ?? "Unknown"
+ let stream = AsyncThrowingStream<
+ GRPCMessage<models_HelloResponse>,
+ 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<models_HelloResponse>(builder: &builder))
+ } catch {
+ continuation.finish(throwing: error)
+ }
+ }
+
+ continuation.finish()
+ }
+ try await response.write(contentsOf: stream)
+ }
+
+ func Update(
+ request: GRPCCore.RPCAsyncSequence<
+ GRPCMessage<models_HelloResponse>,
+ any Swift.Error
+ >,
+ response: GRPCCore.RPCWriter<GRPCMessage<models_HelloResponse>>,
+ 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<models_HelloResponse>(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 0000000..8f012f1
--- /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<HTTP2ClientTransport.Posix>) 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<HTTP2ClientTransport.Posix>) 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<HTTP2ClientTransport.Posix>) 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<HTTP2ClientTransport.Posix>) 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 0000000..b2121b1
--- /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 700c5cd..0000000
--- 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<models_HelloRequest>
- , callOptions: CallOptions?
- ) -> UnaryCall<Message<models_HelloRequest>, Message<models_HelloReply>>
-
- func SayManyHellos(
- _ request: Message<models_HelloRequest>
- , callOptions: CallOptions?,
- handler: @escaping (Message<models_HelloReply>) -> Void
- ) -> ServerStreamingCall<Message<models_HelloRequest>, Message<models_HelloReply>>
-
-}
-
-extension models_GreeterClientProtocol {
-
- public var serviceName: String { "models.Greeter" }
-
- public func SayHello(
- _ request: Message<models_HelloRequest>
- , callOptions: CallOptions? = nil
- ) -> UnaryCall<Message<models_HelloRequest>, Message<models_HelloReply>> {
- return self.makeUnaryCall(
- path: "/models.Greeter/SayHello",
- request: request,
- callOptions: callOptions ?? self.defaultCallOptions,
- interceptors: self.interceptors?.makeSayHelloInterceptors() ?? []
- )
- }
-
- public func SayManyHellos(
- _ request: Message<models_HelloRequest>
- , callOptions: CallOptions? = nil,
- handler: @escaping (Message<models_HelloReply>) -> Void
- ) -> ServerStreamingCall<Message<models_HelloRequest>, Message<models_HelloReply>> {
- 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<models_HelloRequest>, Message<models_HelloReply>>]
-
- /// - Returns: Interceptors to use when invoking 'SayManyHellos'.
- func makeSayManyHellosInterceptors() -> [ClientInterceptor<Message<models_HelloRequest>, Message<models_HelloReply>>]
-
-}
-
-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<models_HelloRequest>, context: StatusOnlyCallContext) -> EventLoopFuture<Message<models_HelloReply>>
- func SayManyHellos(request: Message<models_HelloRequest>, context: StreamingResponseCallContext<Message<models_HelloReply>>) -> EventLoopFuture<GRPCStatus>
-}
-
-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<Message<models_HelloRequest>>(),
- responseSerializer: GRPCPayloadSerializer<Message<models_HelloReply>>(),
- interceptors: self.interceptors?.makeSayHelloInterceptors() ?? [],
- userFunction: self.SayHello(request:context:))
-
- case "SayManyHellos":
- return ServerStreamingServerHandler(
- context: context,
- requestDeserializer: GRPCPayloadDeserializer<Message<models_HelloRequest>>(),
- responseSerializer: GRPCPayloadSerializer<Message<models_HelloReply>>(),
- 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<models_HelloRequest>, Message<models_HelloReply>>]
-
- /// - Returns: Interceptors to use when handling 'SayManyHellos'.
- /// Defaults to calling `self.makeInterceptors()`.
- func makeSayManyHellosInterceptors() -> [ServerInterceptor<Message<models_HelloRequest>, Message<models_HelloReply>>]
-
-}
-#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 0000000..d8e1dbb
--- /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<Bytes>(_ 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<Bytes>(_ 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<GRPCMessage<models_HelloResponse>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>>
+
+ func Collect(
+ request: GRPCCore.StreamingServerRequest<GRPCMessage<models_HelloResponse>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>>
+
+ func Expand(
+ request: GRPCCore.StreamingServerRequest<GRPCMessage<models_HelloResponse>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>>
+
+ func Update(
+ request: GRPCCore.StreamingServerRequest<GRPCMessage<models_HelloResponse>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>>
+
+ }
+
+ public protocol ServiceProtocol: models_Greeter.StreamingServiceProtocol {
+ func Get(
+ request: GRPCCore.ServerRequest<GRPCMessage<models_HelloResponse>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.ServerResponse<GRPCMessage<models_HelloResponse>>
+
+ func Collect(
+ request: GRPCCore.StreamingServerRequest<GRPCMessage<models_HelloResponse>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.ServerResponse<GRPCMessage<models_HelloResponse>>
+
+ func Expand(
+ request: GRPCCore.ServerRequest<GRPCMessage<models_HelloResponse>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>>
+
+ func Update(
+ request: GRPCCore.StreamingServerRequest<GRPCMessage<models_HelloResponse>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>>
+
+ }
+
+ public protocol SimpleServiceProtocol: models_Greeter.ServiceProtocol {
+ func Get(
+ request: GRPCMessage<models_HelloResponse>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCMessage<models_HelloResponse>
+
+ func Collect(
+ request: GRPCCore.RPCAsyncSequence<GRPCMessage<models_HelloResponse>, any Swift.Error>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCMessage<models_HelloResponse>
+
+ func Expand(
+ request: GRPCMessage<models_HelloResponse>,
+ response: GRPCCore.RPCWriter<GRPCMessage<models_HelloResponse>>,
+ context: GRPCCore.ServerContext
+ ) async throws
+
+ func Update(
+ request: GRPCCore.RPCAsyncSequence<GRPCMessage<models_HelloResponse>, any Swift.Error>,
+ response: GRPCCore.RPCWriter<GRPCMessage<models_HelloResponse>>,
+ 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<Transport>(with router: inout GRPCCore.RPCRouter<Transport>) where Transport: GRPCCore.ServerTransport {
+ router.registerHandler(
+ forMethod: models_Greeter.Method.Get.descriptor,
+ deserializer: FlatBuffersMessageDeserializer<GRPCMessage<models_HelloResponse>>(),
+ serializer: FlatBuffersMessageSerializer<GRPCMessage<models_HelloResponse>>(),
+ handler: { request, context in
+ try await self.Get(
+ request: request,
+ context: context
+ )
+ }
+ )
+ router.registerHandler(
+ forMethod: models_Greeter.Method.Collect.descriptor,
+ deserializer: FlatBuffersMessageDeserializer<GRPCMessage<models_HelloResponse>>(),
+ serializer: FlatBuffersMessageSerializer<GRPCMessage<models_HelloResponse>>(),
+ handler: { request, context in
+ try await self.Collect(
+ request: request,
+ context: context
+ )
+ }
+ )
+ router.registerHandler(
+ forMethod: models_Greeter.Method.Expand.descriptor,
+ deserializer: FlatBuffersMessageDeserializer<GRPCMessage<models_HelloResponse>>(),
+ serializer: FlatBuffersMessageSerializer<GRPCMessage<models_HelloResponse>>(),
+ handler: { request, context in
+ try await self.Expand(
+ request: request,
+ context: context
+ )
+ }
+ )
+ router.registerHandler(
+ forMethod: models_Greeter.Method.Update.descriptor,
+ deserializer: FlatBuffersMessageDeserializer<GRPCMessage<models_HelloResponse>>(),
+ serializer: FlatBuffersMessageSerializer<GRPCMessage<models_HelloResponse>>(),
+ 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<GRPCMessage<models_HelloResponse>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>> {
+ let response = try await self.Get(
+ request: GRPCCore.ServerRequest(stream: request),
+ context: context
+ )
+ return GRPCCore.StreamingServerResponse(single: response)
+ }
+ public func Collect(
+ request: GRPCCore.StreamingServerRequest<GRPCMessage<models_HelloResponse>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>> {
+ let response = try await self.Collect(
+ request: request,
+ context: context
+ )
+ return GRPCCore.StreamingServerResponse(single: response)
+ }
+ public func Expand(
+ request: GRPCCore.StreamingServerRequest<GRPCMessage<models_HelloResponse>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>> {
+ 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<GRPCMessage<models_HelloResponse>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.ServerResponse<GRPCMessage<models_HelloResponse>> {
+ return GRPCCore.ServerResponse<GRPCMessage<models_HelloResponse>>(
+ message: try await self.Get(
+ request: request.message,
+ context: context
+ ),
+ metadata: [:]
+ )
+ }
+ public func Collect(
+ request: GRPCCore.StreamingServerRequest<GRPCMessage<models_HelloResponse>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.ServerResponse<GRPCMessage<models_HelloResponse>> {
+ return GRPCCore.ServerResponse<GRPCMessage<models_HelloResponse>>(
+ message: try await self.Collect(
+ request: request.messages,
+ context: context
+ ),
+ metadata: [:]
+ )
+ }
+ public func Expand(
+ request: GRPCCore.ServerRequest<GRPCMessage<models_HelloResponse>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>> {
+ return GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>>(
+ metadata: [:],
+ producer: { writer in
+ try await self.Expand(
+ request: request.message,
+ response: writer,
+ context: context
+ )
+ return [:]
+ }
+ )
+ }
+ public func Update(
+ request: GRPCCore.StreamingServerRequest<GRPCMessage<models_HelloResponse>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>> {
+ return GRPCCore.StreamingServerResponse<GRPCMessage<models_HelloResponse>>(
+ 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<Result>(
+ request: GRPCCore.ClientRequest<GRPCMessage<models_HelloResponse>>,
+ serializer: some GRPCCore.MessageSerializer<GRPCMessage<models_HelloResponse>>,
+ deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<models_HelloResponse>>,
+ options: GRPCCore.CallOptions,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result
+ ) async throws -> Result where Result: Sendable
+
+ func Collect<Result>(
+ request: GRPCCore.StreamingClientRequest<GRPCMessage<models_HelloResponse>>,
+ serializer: some GRPCCore.MessageSerializer<GRPCMessage<models_HelloResponse>>,
+ deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<models_HelloResponse>>,
+ options: GRPCCore.CallOptions,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result
+ ) async throws -> Result where Result: Sendable
+
+ func Expand<Result>(
+ request: GRPCCore.ClientRequest<GRPCMessage<models_HelloResponse>>,
+ serializer: some GRPCCore.MessageSerializer<GRPCMessage<models_HelloResponse>>,
+ deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<models_HelloResponse>>,
+ options: GRPCCore.CallOptions,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result
+ ) async throws -> Result where Result: Sendable
+
+ func Update<Result>(
+ request: GRPCCore.StreamingClientRequest<GRPCMessage<models_HelloResponse>>,
+ serializer: some GRPCCore.MessageSerializer<GRPCMessage<models_HelloResponse>>,
+ deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<models_HelloResponse>>,
+ options: GRPCCore.CallOptions,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<models_HelloResponse>>) 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<Transport>: ClientProtocol where Transport: GRPCCore.ClientTransport {
+ private let client: GRPCCore.GRPCClient<Transport>
+
+ public init(wrapping client: GRPCCore.GRPCClient<Transport>) {
+ self.client = client
+ }
+
+ public func Get<Result>(
+ request: GRPCCore.ClientRequest<GRPCMessage<models_HelloResponse>>,
+ serializer: some GRPCCore.MessageSerializer<GRPCMessage<models_HelloResponse>>,
+ deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<models_HelloResponse>>,
+ options: GRPCCore.CallOptions = .defaults,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<models_HelloResponse>>) 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<Result>(
+ request: GRPCCore.StreamingClientRequest<GRPCMessage<models_HelloResponse>>,
+ serializer: some GRPCCore.MessageSerializer<GRPCMessage<models_HelloResponse>>,
+ deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<models_HelloResponse>>,
+ options: GRPCCore.CallOptions = .defaults,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<models_HelloResponse>>) 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<Result>(
+ request: GRPCCore.ClientRequest<GRPCMessage<models_HelloResponse>>,
+ serializer: some GRPCCore.MessageSerializer<GRPCMessage<models_HelloResponse>>,
+ deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<models_HelloResponse>>,
+ options: GRPCCore.CallOptions = .defaults,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<models_HelloResponse>>) 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<Result>(
+ request: GRPCCore.StreamingClientRequest<GRPCMessage<models_HelloResponse>>,
+ serializer: some GRPCCore.MessageSerializer<GRPCMessage<models_HelloResponse>>,
+ deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<models_HelloResponse>>,
+ options: GRPCCore.CallOptions = .defaults,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<models_HelloResponse>>) 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<Result>(
+ request: GRPCCore.ClientRequest<GRPCMessage<models_HelloResponse>>,
+ options: GRPCCore.CallOptions = .defaults,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result = { response in try response.message }
+ ) async throws -> Result where Result: Sendable {
+ try await self.Get(
+ request: request,
+ serializer: FlatBuffersMessageSerializer<GRPCMessage<models_HelloResponse>>(),
+ deserializer: FlatBuffersMessageDeserializer<GRPCMessage<models_HelloResponse>>(),
+ options: options,
+ onResponse: handleResponse
+ )
+ }
+
+ public func Collect<Result>(
+ request: GRPCCore.StreamingClientRequest<GRPCMessage<models_HelloResponse>>,
+ options: GRPCCore.CallOptions = .defaults,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result = { response in try response.message }
+ ) async throws -> Result where Result: Sendable {
+ try await self.Collect(
+ request: request,
+ serializer: FlatBuffersMessageSerializer<GRPCMessage<models_HelloResponse>>(),
+ deserializer: FlatBuffersMessageDeserializer<GRPCMessage<models_HelloResponse>>(),
+ options: options,
+ onResponse: handleResponse
+ )
+ }
+
+ public func Expand<Result>(
+ request: GRPCCore.ClientRequest<GRPCMessage<models_HelloResponse>>,
+ options: GRPCCore.CallOptions = .defaults,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result
+ ) async throws -> Result where Result: Sendable {
+ try await self.Expand(
+ request: request,
+ serializer: FlatBuffersMessageSerializer<GRPCMessage<models_HelloResponse>>(),
+ deserializer: FlatBuffersMessageDeserializer<GRPCMessage<models_HelloResponse>>(),
+ options: options,
+ onResponse: handleResponse
+ )
+ }
+
+ public func Update<Result>(
+ request: GRPCCore.StreamingClientRequest<GRPCMessage<models_HelloResponse>>,
+ options: GRPCCore.CallOptions = .defaults,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result
+ ) async throws -> Result where Result: Sendable {
+ try await self.Update(
+ request: request,
+ serializer: FlatBuffersMessageSerializer<GRPCMessage<models_HelloResponse>>(),
+ deserializer: FlatBuffersMessageDeserializer<GRPCMessage<models_HelloResponse>>(),
+ 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<Result>(
+ _ message: GRPCMessage<models_HelloResponse>,
+ metadata: GRPCCore.Metadata = [:],
+ options: GRPCCore.CallOptions = .defaults,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result = { try $0.message }
+ ) async throws -> Result where Result: Sendable {
+ let request = GRPCCore.ClientRequest<GRPCMessage<models_HelloResponse>>(
+ message: message,
+ metadata: metadata
+ )
+ return try await self.Get(
+ request: request,
+ options: options,
+ onResponse: handleResponse
+ )
+ }
+
+ public func Collect<Result>(
+ metadata: GRPCCore.Metadata = [:],
+ options: GRPCCore.CallOptions = .defaults,
+ requestProducer producer: @Sendable @escaping (GRPCCore.RPCWriter<GRPCMessage<models_HelloResponse>>) async throws -> Void,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result = { try $0.message }
+ ) async throws -> Result where Result: Sendable {
+ let request = GRPCCore.StreamingClientRequest<GRPCMessage<models_HelloResponse>>(
+ metadata: metadata,
+ producer: producer
+ )
+ return try await self.Collect(
+ request: request,
+ options: options,
+ onResponse: handleResponse
+ )
+ }
+
+ public func Expand<Result>(
+ _ message: GRPCMessage<models_HelloResponse>,
+ metadata: GRPCCore.Metadata = [:],
+ options: GRPCCore.CallOptions = .defaults,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result
+ ) async throws -> Result where Result: Sendable {
+ let request = GRPCCore.ClientRequest<GRPCMessage<models_HelloResponse>>(
+ message: message,
+ metadata: metadata
+ )
+ return try await self.Expand(
+ request: request,
+ options: options,
+ onResponse: handleResponse
+ )
+ }
+
+ public func Update<Result>(
+ metadata: GRPCCore.Metadata = [:],
+ options: GRPCCore.CallOptions = .defaults,
+ requestProducer producer: @Sendable @escaping (GRPCCore.RPCWriter<GRPCMessage<models_HelloResponse>>) async throws -> Void,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<models_HelloResponse>>) async throws -> Result
+ ) async throws -> Result where Result: Sendable {
+ let request = GRPCCore.StreamingClientRequest<GRPCMessage<models_HelloResponse>>(
+ 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 954f200..b14d59b 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 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 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<T>(_ verifier: inout Verifier, at position: Int, of type: T.Type) throws where T: Verifiable {
@@ -42,7 +42,7 @@
}
}
-extension models_HelloReply: Encodable {
+extension models_HelloResponse: Encodable {
enum CodingKeys: String, CodingKey {
case message = "message"
}
@@ -53,7 +53,7 @@
}
}
-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 345a055..0000000
--- 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<models_HelloRequest>(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 27255e8..0000000
--- 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<models_HelloRequest>,
- context: StatusOnlyCallContext)
- -> EventLoopFuture<Message<models_HelloReply>>
- {
- 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<models_HelloReply>(builder: &builder))
- }
-
- func SayManyHellos(
- request: Message<models_HelloRequest>,
- context: StreamingResponseCallContext<Message<models_HelloReply>>)
- -> EventLoopFuture<GRPCStatus>
- {
- 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<models_HelloReply>(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 b741415..68c6a20 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<std::string>& 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<std::string>& 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<std::string>& components,
- const grpc::string& name) {
- return "Message<" + WrapInNameSpace(components, name) + ">";
+static std::string GenerateGRPCMessage(const std::string& name) {
+ return "GRPCMessage<" + name + ">";
}
-// MARK: - Client
-
-static void GenerateClientFuncName(
- const grpc_generator::Method* method, grpc_generator::Printer* printer,
- std::map<grpc::string, grpc::string>* 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;
- }
-
- 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;
- }
-
- if (method->ClientStreaming()) {
- printer->Print(vars,
- " $GenAccess$func $MethodName$(\n"
- " callOptions: CallOptions?$isNil$\n"
- " ) -> ClientStreamingCall<$Input$, $Output$>");
- return;
- }
-
- printer->Print(vars,
- " $GenAccess$func $MethodName$(\n"
- " callOptions: CallOptions?$isNil$,\n"
- " handler: @escaping ($Output$ ) -> Void\n"
- " ) -> BidirectionalStreamingCall<$Input$, $Output$>");
+static std::string GenerateType(const std::string& name,
+ const std::string& wrapper) {
+ return wrapper + "<" + GenerateGRPCMessage(name) + ">";
}
-static void GenerateClientFuncBody(
- const grpc_generator::Method* method, grpc_generator::Printer* printer,
- std::map<grpc::string, grpc::string>* 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;
+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,
- " return self.makeServerStreamingCall(\n"
- " path: \"/$PATH$$ServiceName$/$MethodName$\",\n"
- " request: request,\n"
- " callOptions: callOptions ?? self.defaultCallOptions,\n"
- " $Interceptor$,\n"
- " handler: handler\n"
- " )\n");
- return;
- }
-
- 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,
- " return self.makeBidirectionalStreamingCall(\n"
- " path: \"/$PATH$$ServiceName$/$MethodName$\",\n"
- " callOptions: callOptions ?? self.defaultCallOptions,\n"
- " $Interceptor$,\n"
- " handler: handler\n"
- " )\n");
}
-void GenerateClientProtocol(const grpc_generator::Service* service,
- grpc_generator::Printer* printer,
- std::map<grpc::string, grpc::string>* dictonary) {
- auto vars = *dictonary;
+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();
+ }
+}
+
+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(
- 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");
+ "@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, "
+ "*)\n");
+}
- 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");
- }
+void GenerateMethodDescriptor(grpc_generator::Printer* printer,
+ std::map<grpc::string, grpc::string>* dictionary) {
+ auto vars = *dictionary;
+ 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,
+ "service: GRPCCore.ServiceDescriptor(fullyQualifiedService: "
+ "\"$ServiceQualifiedName$\"),\n");
+ printer->Print(vars, "method: \"$MethodName$\"\n");
+ printer->Outdent();
+ printer->Print(")\n");
+ printer->Outdent();
+ printer->Print(vars, "}\n");
+}
+
+void GenerateCoders(grpc_generator::Printer* printer) {
+ EnforceOSVersion(printer);
+ printer->Print(
+ "extension FlatBuffersMessageSerializer: MessageSerializer {\n");
+ printer->Indent();
+ printer->Print(
+ "public func serialize<Bytes>(_ 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");
- printer->Print(vars, "extension $ServiceQualifiedName$ClientProtocol {");
- printer->Print("\n\n");
- printer->Print(vars,
- " $ACCESS$ var serviceName: String { "
- "\"$PATH$$ServiceName$\" }\n");
-
- 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");
- }
- printer->Print("}\n\n");
-
- printer->Print(vars,
- "$ACCESS$ protocol "
- "$ServiceQualifiedName$ClientInterceptorFactoryProtocol {\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(
- vars,
- " /// - Returns: Interceptors to use when invoking '$MethodName$'.\n");
- printer->Print(vars,
- " func make$MethodName$Interceptors() -> "
- "[ClientInterceptor<$Input$, $Output$>]\n\n");
- }
+ EnforceOSVersion(printer);
+ printer->Print(
+ "extension FlatBuffersMessageDeserializer: MessageDeserializer {\n");
+ printer->Indent();
+ printer->Print(
+ "public func deserialize<Bytes>(_ 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 GenerateClientClass(grpc_generator::Printer* printer,
- std::map<grpc::string, grpc::string>* dictonary) {
- auto vars = *dictonary;
+void GenerateSharedContent(const grpc_generator::Service* service,
+ grpc_generator::Printer* printer,
+ std::map<grpc::string, grpc::string>* dictionary) {
+ auto vars = *dictionary;
+ EnforceOSVersion(printer);
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");
+ "$ACCESS$ enum $SwiftServiceQualifiedName$: Sendable {\n");
+ printer->Indent();
printer->Print(vars,
- " $ACCESS$ var interceptors: "
- "$ServiceQualifiedName$ClientInterceptorFactoryProtocol?\n");
- printer->Print("\n");
+ "$ACCESS$ static let descriptor = "
+ "GRPCCore.ServiceDescriptor(fullyQualifiedService: "
+ "\"$ServiceQualifiedName$\")\n");
+ printer->Print(vars, "$ACCESS$ enum Method: Sendable {\n");
+ printer->Indent();
+
+ std::vector<std::string> 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);
+ GenerateMethodDescriptor(printer, &vars);
+ }
+
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");
+ "$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,
+ "$ACCESS$ static let $SwiftServiceQualifiedName$ = "
+ "GRPCCore.ServiceDescriptor(fullyQualifiedService: "
+ "\"$ServiceQualifiedName$\")\n");
+ printer->Outdent();
printer->Print("}\n");
}
-// MARK: - Server
+// Service Generation
-grpc::string GenerateServerFuncName(const grpc_generator::Method* method) {
- if (method->NoStreaming()) {
- return "func $MethodName$(request: $Input$"
- ", context: StatusOnlyCallContext) -> EventLoopFuture<$Output$>";
- }
+void GenerateFunction(grpc_generator::Printer* printer,
+ std::map<grpc::string, grpc::string>* dictionary) {
+ auto vars = *dictionary;
+ printer->Print(vars, "func $MethodName$(\n");
+ printer->Indent();
- if (method->ClientStreaming()) {
- return "func $MethodName$(context: UnaryResponseCallContext<$Output$>) -> "
- "EventLoopFuture<(StreamEvent<$Input$"
- ">) -> Void>";
- }
+ printer->Print(vars, "request: $Input$,\n");
+ printer->Print("context: GRPCCore.ServerContext\n");
- if (method->ServerStreaming()) {
- return "func $MethodName$(request: $Input$"
- ", context: StreamingResponseCallContext<$Output$>) -> "
- "EventLoopFuture<GRPCStatus>";
- }
- return "func $MethodName$(context: StreamingResponseCallContext<$Output$>) "
- "-> EventLoopFuture<(StreamEvent<$Input$>) -> Void>";
+ printer->Outdent();
+ printer->Print(vars, ") async throws -> $Output$\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";
- }
- 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";
- }
- return "";
-}
-
-void GenerateServerProtocol(const grpc_generator::Service* service,
- grpc_generator::Printer* printer,
- std::map<grpc::string, grpc::string>* dictonary) {
- auto vars = *dictonary;
+void GenerateServiceProtocols(const grpc_generator::Service* service,
+ grpc_generator::Printer* printer,
+ std::map<grpc::string, grpc::string>* dictionary) {
+ auto vars = *dictionary;
+ EnforceOSVersion(printer);
+ printer->Print(vars, "extension $SwiftServiceQualifiedName$ {\n");
+ printer->Indent();
+ // Base protocol
printer->Print(vars,
- "$ACCESS$ protocol $ServiceQualifiedName$Provider: "
- "CallHandlerProvider {\n");
+ "$ACCESS$ protocol StreamingServiceProtocol: "
+ "GRPCCore.RegistrableRPCService {\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()),
+ 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");
+
+ // Service
+ printer->Print(vars,
+ "$ACCESS$ protocol ServiceProtocol: "
+ "$SwiftServiceQualifiedName$.StreamingServiceProtocol {\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;
+ GenerateFunction(printer, &vars);
+ }
+
+ printer->Outdent();
+ printer->Print("}\n\n");
+
+ // Simple service
+ printer->Print(vars,
+ "$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,
- " var interceptors: "
- "$ServiceQualifiedName$ServerInterceptorFactoryProtocol? { get }\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");
- }
- printer->Print("}\n\n");
-
- printer->Print(vars, "$ACCESS$ extension $ServiceQualifiedName$Provider {\n");
- printer->Print("\n");
- printer->Print(vars,
- " var serviceName: Substring { return "
- "\"$PATH$$ServiceName$\" }\n");
- printer->Print("\n");
+ "extension $SwiftServiceQualifiedName$.StreamingServiceProtocol {\n");
+ printer->Indent();
printer->Print(
- " func handle(method name: Substring, context: "
- "CallHandlerContext) -> GRPCServerHandlerProtocol? {\n");
- printer->Print(" switch name {\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();
- auto body = GenerateServerExtensionBody(method.get());
- printer->Print(vars, body.c_str());
- printer->Print("\n");
- }
- printer->Print(" default: return nil;\n");
- printer->Print(" }\n");
- printer->Print(" }\n\n");
- printer->Print("}\n\n");
+ "public func registerMethods<Transport>(with router: inout "
+ "GRPCCore.RPCRouter<Transport>) where Transport: "
+ "GRPCCore.ServerTransport {\n");
+ printer->Indent();
- printer->Print(vars,
- "$ACCESS$ protocol "
- "$ServiceQualifiedName$ServerInterceptorFactoryProtocol {\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();
+ 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 handling '$MethodName$'.\n"
- " /// Defaults to calling `self.makeInterceptors()`.\n");
- printer->Print(vars,
- " func make$MethodName$Interceptors() -> "
- "[ServerInterceptor<$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->Print("}");
+
+ printer->Outdent();
+ printer->Print("}\n");
+ printer->Outdent();
+ printer->Print("}\n\n");
}
+
+void CreateServiceProtocolFunctionsImplementations(
+ grpc_generator::Printer* printer,
+ std::map<grpc::string, grpc::string>* dictionary) {
+ auto vars = *dictionary;
+ 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");
+}
+
+std::string GenerateInputRequest(const grpc_generator::Method* method) {
+ if (method->NoStreaming() || method->ServerStreaming())
+ return ServerRequest() + "(stream: request)";
+ return "request";
+}
+
+std::string GenerateOutputResponse(const grpc_generator::Method* method) {
+ if (method->NoStreaming() || method->ClientStreaming())
+ return StreamingServerResponse() + "(single: response)";
+ return "response";
+}
+
+void GenerateServiceDefaultImplementation(
+ const grpc_generator::Service* service, grpc_generator::Printer* printer,
+ std::map<grpc::string, grpc::string>* dictionary) {
+ auto vars = *dictionary;
+ EnforceOSVersion(printer);
+ printer->Print(vars,
+ "extension $SwiftServiceQualifiedName$.ServiceProtocol {\n");
+ printer->Indent();
+
+ 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);
+ }
+ printer->Outdent();
+ printer->Print("}\n\n");
+}
+
+void GenerateSimpleServiceImplemetation(
+ const grpc_generator::Service* service, grpc_generator::Printer* printer,
+ std::map<grpc::string, grpc::string>* dictionary) {
+ auto vars = *dictionary;
+ 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");
+ }
+ printer->Outdent();
+ printer->Print("}\n\n");
+}
+
+void GenerateService(const grpc_generator::Service* service,
+ grpc_generator::Printer* printer,
+ std::map<grpc::string, grpc::string>* 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<grpc::string, grpc::string>* dictionary) {
+ auto vars = *dictionary;
+ 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$<Result>(\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");
+ }
+
+ printer->Outdent();
+ printer->Print("}\n");
+ printer->Outdent();
+ printer->Print("}\n\n");
+}
+
+void GenerateClientStruct(const grpc_generator::Service* service,
+ grpc_generator::Printer* printer,
+ std::map<grpc::string, grpc::string>* dictionary) {
+ auto vars = *dictionary;
+ EnforceOSVersion(printer);
+ printer->Print(vars, "extension $SwiftServiceQualifiedName$ {\n");
+ printer->Indent();
+ // Base protocol
+ printer->Print(vars,
+ "$ACCESS$ struct Client<Transport>: ClientProtocol where "
+ "Transport: GRPCCore.ClientTransport {\n");
+ printer->Indent();
+ printer->Print("private let client: GRPCCore.GRPCClient<Transport>\n\n");
+ printer->Print(
+ vars,
+ "$ACCESS$ init(wrapping client: GRPCCore.GRPCClient<Transport>) {\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);
+ 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$<Result>(\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");
+}
+
+void GenerateClientDefaultImplementation(
+ const grpc_generator::Service* service, grpc_generator::Printer* printer,
+ std::map<grpc::string, grpc::string>* dictionary) {
+ auto vars = *dictionary;
+ EnforceOSVersion(printer);
+ printer->Print(vars,
+ "extension $SwiftServiceQualifiedName$.ClientProtocol {\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()),
+ "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$<Result>(\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->Outdent();
+ printer->Print("}\n\n");
+}
+
+void GenerateClientHelperMethods(
+ const grpc_generator::Service* service, grpc_generator::Printer* printer,
+ std::map<grpc::string, grpc::string>* dictionary) {
+ auto vars = *dictionary;
+
+ EnforceOSVersion(printer);
+ printer->Print(vars,
+ "extension $SwiftServiceQualifiedName$.ClientProtocol {\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()),
+ "FlatBuffersMessageSerializer");
+
+ vars["deserializer"] =
+ GenerateType(QualifiedName(method->get_input_namespace_parts(),
+ method->get_output_type_name()),
+ "FlatBuffersMessageDeserializer");
+
+ printer->Print(vars, "$ACCESS$ func $MethodName$<Result>(\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->Outdent();
+ printer->Print("}\n\n");
+}
+
+void GenerateClient(const grpc_generator::Service* service,
+ grpc_generator::Printer* printer,
+ std::map<grpc::string, grpc::string>* dictionary) {
+ GenerateClientProtocols(service, printer, dictionary);
+ GenerateClientStruct(service, printer, dictionary);
+ GenerateClientDefaultImplementation(service, printer, dictionary);
+ GenerateClientHelperMethods(service, printer, dictionary);
+}
+
} // namespace
grpc::string Generate(grpc_generator::File* file,
@@ -384,8 +938,10 @@
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 @@
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 @@
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 3bd4561..0ef9987 100644
--- a/samples/monster_generated.swift
+++ b/samples/monster_generated.swift
@@ -161,7 +161,7 @@
}
}
-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 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 93058e7..9571a63 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 @@
"--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 f534ca2..437722f 100644
--- a/src/idl_gen_swift.cpp
+++ b/src/idl_gen_swift.cpp
@@ -170,9 +170,8 @@
code_ += "// swiftformat:disable all\n";
if (parser_.opts.include_dependence_headers || parser_.opts.generate_all) {
- code_.SetValue("IMPLEMENTONLY", parser_.opts.swift_implementation_only
- ? "@_implementationOnly "
- : "");
+ code_.SetValue("IMPLEMENTONLY",
+ parser_.opts.swift_implementation_only ? "internal " : "");
code_ += "#if canImport(Common)";
code_ += "{{IMPLEMENTONLY}}import Common";
code_ += "#endif";
@@ -549,13 +548,14 @@
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 ec27fd1..f8b59ee 100644
--- a/swift/Sources/FlatBuffers/ByteBuffer.swift
+++ b/swift/Sources/FlatBuffers/ByteBuffer.swift
@@ -20,7 +20,7 @@
/// 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 @@
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 65e3a4d..feb5762 100644
--- a/swift/Sources/FlatBuffers/Enum.swift
+++ b/swift/Sources/FlatBuffers/Enum.swift
@@ -23,7 +23,7 @@
/// 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 9e778d2..b8e49bd 100644
--- a/swift/Sources/FlatBuffers/FlatBufferBuilder.swift
+++ b/swift/Sources/FlatBuffers/FlatBufferBuilder.swift
@@ -45,7 +45,7 @@
/// 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 @@
///
/// - 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<UInt8>.size)
_bb.push(bytes: $0)
diff --git a/swift/Sources/FlatBuffers/FlatBufferObject.swift b/swift/Sources/FlatBuffers/FlatBufferObject.swift
index 0b9f01b..a85f107 100644
--- a/swift/Sources/FlatBuffers/FlatBufferObject.swift
+++ b/swift/Sources/FlatBuffers/FlatBufferObject.swift
@@ -20,6 +20,8 @@
/// 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 @@
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 a8cdbf8..37729a0 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 }
-
- init(byteBuffer: ByteBuffer)
-
- @discardableResult
- @inline(__always)
- func withUnsafeReadableBytes<T>(
- _ body: (UnsafeRawBufferPointer) throws
- -> T) rethrows -> T
+enum FlatbuffersGRPCError: Error {
+ case finishedNotCalledOnBuilder
}
-/// Message is a wrapper around Buffers to to able to send Flatbuffers `Buffers` through the
-/// GRPC library
-public struct Message<T: FlatBufferTable>: FlatBufferGRPCMessage {
- internal var buffer: ByteBuffer
+public protocol GRPCVerifiableMessage<Message> {
+ associatedtype Message
- /// 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))
- }
+ init(pointer: UnsafeRawBufferPointer)
+ init(byteBuffer: ByteBuffer)
+
+ func decode() throws -> Message
+ func withUnsafeReadableBytes<Data>(
+ _ body: (UnsafeRawBufferPointer) throws
+ -> Data) rethrows -> Data
+}
+
+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 @@
}
}
}
+
+@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<Data>(
+ 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 b09db49..d4c4059 100644
--- a/swift/Sources/FlatBuffers/TableVerifier.swift
+++ b/swift/Sources/FlatBuffers/TableVerifier.swift
@@ -115,7 +115,7 @@
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 a9b0358..fae8b4c 100644
--- a/swift/Sources/FlatBuffers/Vectors/FlatbufferVector.swift
+++ b/swift/Sources/FlatBuffers/Vectors/FlatbufferVector.swift
@@ -68,7 +68,7 @@
}
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 ab61e6f..7b59581 100644
--- a/swift/Sources/FlatBuffers/Vectors/UnionFlatbufferVector.swift
+++ b/swift/Sources/FlatBuffers/Vectors/UnionFlatbufferVector.swift
@@ -49,8 +49,8 @@
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 8dced85..e4ed2f0 100644
--- a/swift/Sources/FlatBuffers/_InternalByteBuffer.swift
+++ b/swift/Sources/FlatBuffers/_InternalByteBuffer.swift
@@ -146,7 +146,7 @@
#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 af75631..f4dd2ad 100644
--- a/swift/Sources/FlexBuffers/ByteBuffer.swift
+++ b/swift/Sources/FlexBuffers/ByteBuffer.swift
@@ -30,7 +30,7 @@
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 4f51c5d..2d75b2a 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 d620500..d4d8431 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 b9059fe..36bda4a 100644
--- a/swift/Sources/FlexBuffers/Utils/Value.swift
+++ b/swift/Sources/FlexBuffers/Utils/Value.swift
@@ -20,10 +20,10 @@
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 449ab58..77a4db7 100644
--- a/swift/Sources/FlexBuffers/Writer/FlexBuffersWriter.swift
+++ b/swift/Sources/FlexBuffers/Writer/FlexBuffersWriter.swift
@@ -977,6 +977,9 @@
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 4851e99..ce8f128 100644
--- a/tests/swift/Tests/Flatbuffers/ByteBufferTests.swift
+++ b/tests/swift/Tests/Flatbuffers/ByteBufferTests.swift
@@ -128,5 +128,9 @@
}
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 7ea7b5b..4b85c59 100644
--- a/tests/swift/Tests/Flatbuffers/FlatBuffersArraysTests.swift
+++ b/tests/swift/Tests/Flatbuffers/FlatBuffersArraysTests.swift
@@ -26,6 +26,7 @@
func testStructSizes() {
XCTAssertEqual(MemoryLayout<MyGame_Example_NestedStruct>.size, 32)
XCTAssertEqual(MemoryLayout<MyGame_Example_ArrayStruct>.size, 160)
+ XCTAssertEqual(MemoryLayout<MyGame_Example_LargeArrayStruct>.size, 2496)
}
func testGoldenData() {
@@ -233,4 +234,3 @@
}
#endif
-
diff --git a/tests/swift/Tests/Flatbuffers/FlatBuffersMonsterWriterTests.swift b/tests/swift/Tests/Flatbuffers/FlatBuffersMonsterWriterTests.swift
index d5e541c..63679f2 100644
--- a/tests/swift/Tests/Flatbuffers/FlatBuffersMonsterWriterTests.swift
+++ b/tests/swift/Tests/Flatbuffers/FlatBuffersMonsterWriterTests.swift
@@ -52,7 +52,7 @@
#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 @@
func testCreateMessage() {
let fbb = createMonster(withPrefix: false)
let byteBuffer = fbb.buffer
- let firstMessage = Message<Monster>(byteBuffer: byteBuffer)
+ let firstMessage = GRPCMessage<Monster>(byteBuffer: byteBuffer)
firstMessage.withUnsafeReadableBytes { ptr in
var bytes = ByteBuffer(contiguousBytes: ptr, count: ptr.count)
var monster: Monster = getRoot(byteBuffer: &bytes)
@@ -339,7 +339,7 @@
}
let secondByteBuffer = fbb.sizedBuffer
- let secondMessage = Message<Monster>(byteBuffer: secondByteBuffer)
+ let secondMessage = GRPCMessage<Monster>(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 e5771b9..e2de1a1 100644
--- a/tests/swift/Tests/Flatbuffers/MutatingBool_generated.swift
+++ b/tests/swift/Tests/Flatbuffers/MutatingBool_generated.swift
@@ -74,7 +74,7 @@
}
}
-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 f9adfe3..01a1391 100644
--- a/tests/swift/Tests/Flatbuffers/arrays_test_generated.swift
+++ b/tests/swift/Tests/Flatbuffers/arrays_test_generated.swift
@@ -398,7 +398,7 @@
}
@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 ed809f8..8443bb2 100644
--- a/tests/swift/Tests/Flatbuffers/empty_vtable_generated.swift
+++ b/tests/swift/Tests/Flatbuffers/empty_vtable_generated.swift
@@ -8,7 +8,7 @@
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 cf7332e..2829c67 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
+import Foundation
+import GRPCCore
+import GRPCNIOTransportCore
-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 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<MyGame_Example_Monster>
- , callOptions: CallOptions?
- ) -> UnaryCall<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>>
-
- func Retrieve(
- _ request: Message<MyGame_Example_Stat>
- , callOptions: CallOptions?,
- handler: @escaping (Message<MyGame_Example_Monster>) -> Void
- ) -> ServerStreamingCall<Message<MyGame_Example_Stat>, Message<MyGame_Example_Monster>>
-
- func GetMaxHitPoint(
- callOptions: CallOptions?
- ) -> ClientStreamingCall<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>>
-
- func GetMinMaxHitPoints(
- callOptions: CallOptions?,
- handler: @escaping (Message<MyGame_Example_Stat> ) -> Void
- ) -> BidirectionalStreamingCall<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>>
-
-}
-
-extension MyGame_Example_MonsterStorageClientProtocol {
-
- public var serviceName: String { "MyGame.Example.MonsterStorage" }
-
- public func Store(
- _ request: Message<MyGame_Example_Monster>
- , callOptions: CallOptions? = nil
- ) -> UnaryCall<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>> {
- return self.makeUnaryCall(
- path: "/MyGame.Example.MonsterStorage/Store",
- request: request,
- callOptions: callOptions ?? self.defaultCallOptions,
- interceptors: self.interceptors?.makeStoreInterceptors() ?? []
- )
- }
-
- public func Retrieve(
- _ request: Message<MyGame_Example_Stat>
- , callOptions: CallOptions? = nil,
- handler: @escaping (Message<MyGame_Example_Monster>) -> Void
- ) -> ServerStreamingCall<Message<MyGame_Example_Stat>, Message<MyGame_Example_Monster>> {
- return self.makeServerStreamingCall(
- path: "/MyGame.Example.MonsterStorage/Retrieve",
- request: request,
- callOptions: callOptions ?? self.defaultCallOptions,
- interceptors: self.interceptors?.makeRetrieveInterceptors() ?? [],
- handler: handler
- )
- }
-
- public func GetMaxHitPoint(
- callOptions: CallOptions? = nil
- ) -> ClientStreamingCall<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>> {
- return self.makeClientStreamingCall(
- path: "/MyGame.Example.MonsterStorage/GetMaxHitPoint",
- callOptions: callOptions ?? self.defaultCallOptions,
- interceptors: self.interceptors?.makeGetMaxHitPointInterceptors() ?? []
- )
- }
-
- public func GetMinMaxHitPoints(
- callOptions: CallOptions? = nil,
- handler: @escaping (Message<MyGame_Example_Stat> ) -> Void
- ) -> BidirectionalStreamingCall<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>> {
- return self.makeBidirectionalStreamingCall(
- path: "/MyGame.Example.MonsterStorage/GetMinMaxHitPoints",
- callOptions: callOptions ?? self.defaultCallOptions,
- interceptors: self.interceptors?.makeGetMinMaxHitPointsInterceptors() ?? [],
- handler: handler
- )
- }
-}
-
-public protocol MyGame_Example_MonsterStorageClientInterceptorFactoryProtocol {
- /// - Returns: Interceptors to use when invoking 'Store'.
- func makeStoreInterceptors() -> [ClientInterceptor<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>>]
-
- /// - Returns: Interceptors to use when invoking 'Retrieve'.
- func makeRetrieveInterceptors() -> [ClientInterceptor<Message<MyGame_Example_Stat>, Message<MyGame_Example_Monster>>]
-
- /// - Returns: Interceptors to use when invoking 'GetMaxHitPoint'.
- func makeGetMaxHitPointInterceptors() -> [ClientInterceptor<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>>]
-
- /// - Returns: Interceptors to use when invoking 'GetMinMaxHitPoints'.
- func makeGetMinMaxHitPointsInterceptors() -> [ClientInterceptor<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>>]
-
-}
-
-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
- }
-}
-
-public protocol MyGame_Example_MonsterStorageProvider: CallHandlerProvider {
- var interceptors: MyGame_Example_MonsterStorageServerInterceptorFactoryProtocol? { get }
- func Store(request: Message<MyGame_Example_Monster>, context: StatusOnlyCallContext) -> EventLoopFuture<Message<MyGame_Example_Stat>>
- func Retrieve(request: Message<MyGame_Example_Stat>, context: StreamingResponseCallContext<Message<MyGame_Example_Monster>>) -> EventLoopFuture<GRPCStatus>
- func GetMaxHitPoint(context: UnaryResponseCallContext<Message<MyGame_Example_Stat>>) -> EventLoopFuture<(StreamEvent<Message<MyGame_Example_Monster>>) -> Void>
- func GetMinMaxHitPoints(context: StreamingResponseCallContext<Message<MyGame_Example_Stat>>) -> EventLoopFuture<(StreamEvent<Message<MyGame_Example_Monster>>) -> Void>
-}
-
-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<Message<MyGame_Example_Monster>>(),
- responseSerializer: GRPCPayloadSerializer<Message<MyGame_Example_Stat>>(),
- interceptors: self.interceptors?.makeStoreInterceptors() ?? [],
- userFunction: self.Store(request:context:))
-
- case "Retrieve":
- return ServerStreamingServerHandler(
- context: context,
- requestDeserializer: GRPCPayloadDeserializer<Message<MyGame_Example_Stat>>(),
- responseSerializer: GRPCPayloadSerializer<Message<MyGame_Example_Monster>>(),
- interceptors: self.interceptors?.makeRetrieveInterceptors() ?? [],
- userFunction: self.Retrieve(request:context:))
-
- case "GetMaxHitPoint":
- return ClientStreamingServerHandler(
- context: context,
- requestDeserializer: GRPCPayloadDeserializer<Message<MyGame_Example_Monster>>(),
- responseSerializer: GRPCPayloadSerializer<Message<MyGame_Example_Stat>>(),
- interceptors: self.interceptors?.makeGetMaxHitPointInterceptors() ?? [],
- observerFactory: self.GetMaxHitPoint(context:))
-
- case "GetMinMaxHitPoints":
- return BidirectionalStreamingServerHandler(
- context: context,
- requestDeserializer: GRPCPayloadDeserializer<Message<MyGame_Example_Monster>>(),
- responseSerializer: GRPCPayloadSerializer<Message<MyGame_Example_Stat>>(),
- interceptors: self.interceptors?.makeGetMinMaxHitPointsInterceptors() ?? [],
- observerFactory: self.GetMinMaxHitPoints(context:))
-
- default: return nil;
+/// 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<Bytes>(_ 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
+ )
}
}
-
}
-public protocol MyGame_Example_MonsterStorageServerInterceptorFactoryProtocol {
- /// - Returns: Interceptors to use when handling 'Store'.
- /// Defaults to calling `self.makeInterceptors()`.
- func makeStoreInterceptors() -> [ServerInterceptor<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>>]
-
- /// - Returns: Interceptors to use when handling 'Retrieve'.
- /// Defaults to calling `self.makeInterceptors()`.
- func makeRetrieveInterceptors() -> [ServerInterceptor<Message<MyGame_Example_Stat>, Message<MyGame_Example_Monster>>]
-
- /// - Returns: Interceptors to use when handling 'GetMaxHitPoint'.
- /// Defaults to calling `self.makeInterceptors()`.
- func makeGetMaxHitPointInterceptors() -> [ServerInterceptor<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>>]
-
- /// - Returns: Interceptors to use when handling 'GetMinMaxHitPoints'.
- /// Defaults to calling `self.makeInterceptors()`.
- func makeGetMinMaxHitPointsInterceptors() -> [ServerInterceptor<Message<MyGame_Example_Monster>, Message<MyGame_Example_Stat>>]
-
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
+extension FlatBuffersMessageDeserializer: MessageDeserializer {
+ public func deserialize<Bytes>(_ 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 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")
+}
+
+// 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<GRPCMessage<MyGame_Example_Stat>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Stat>>
+
+ func Retrieve(
+ request: GRPCCore.StreamingServerRequest<GRPCMessage<MyGame_Example_Monster>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Monster>>
+
+ func GetMaxHitPoint(
+ request: GRPCCore.StreamingServerRequest<GRPCMessage<MyGame_Example_Stat>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Stat>>
+
+ func GetMinMaxHitPoints(
+ request: GRPCCore.StreamingServerRequest<GRPCMessage<MyGame_Example_Stat>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Stat>>
+
+ }
+
+ public protocol ServiceProtocol: MyGame_Example_MonsterStorage.StreamingServiceProtocol {
+ func Store(
+ request: GRPCCore.ServerRequest<GRPCMessage<MyGame_Example_Stat>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.ServerResponse<GRPCMessage<MyGame_Example_Stat>>
+
+ func Retrieve(
+ request: GRPCCore.ServerRequest<GRPCMessage<MyGame_Example_Monster>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Monster>>
+
+ func GetMaxHitPoint(
+ request: GRPCCore.StreamingServerRequest<GRPCMessage<MyGame_Example_Stat>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.ServerResponse<GRPCMessage<MyGame_Example_Stat>>
+
+ func GetMinMaxHitPoints(
+ request: GRPCCore.StreamingServerRequest<GRPCMessage<MyGame_Example_Stat>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Stat>>
+
+ }
+
+ public protocol SimpleServiceProtocol: MyGame_Example_MonsterStorage.ServiceProtocol {
+ func Store(
+ request: GRPCMessage<MyGame_Example_Stat>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCMessage<MyGame_Example_Stat>
+
+ func Retrieve(
+ request: GRPCMessage<MyGame_Example_Monster>,
+ response: GRPCCore.RPCWriter<GRPCMessage<MyGame_Example_Monster>>,
+ context: GRPCCore.ServerContext
+ ) async throws
+
+ func GetMaxHitPoint(
+ request: GRPCCore.RPCAsyncSequence<GRPCMessage<MyGame_Example_Stat>, any Swift.Error>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCMessage<MyGame_Example_Stat>
+
+ func GetMinMaxHitPoints(
+ request: GRPCCore.RPCAsyncSequence<GRPCMessage<MyGame_Example_Stat>, any Swift.Error>,
+ response: GRPCCore.RPCWriter<GRPCMessage<MyGame_Example_Stat>>,
+ context: GRPCCore.ServerContext
+ ) async throws
+
+ }
+}
+
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
+extension MyGame_Example_MonsterStorage.StreamingServiceProtocol {
+ public func registerMethods<Transport>(with router: inout GRPCCore.RPCRouter<Transport>) where Transport: GRPCCore.ServerTransport {
+ router.registerHandler(
+ forMethod: MyGame_Example_MonsterStorage.Method.Store.descriptor,
+ deserializer: FlatBuffersMessageDeserializer<GRPCMessage<MyGame_Example_Stat>>(),
+ serializer: FlatBuffersMessageSerializer<GRPCMessage<MyGame_Example_Stat>>(),
+ handler: { request, context in
+ try await self.Store(
+ request: request,
+ context: context
+ )
+ }
+ )
+ router.registerHandler(
+ forMethod: MyGame_Example_MonsterStorage.Method.Retrieve.descriptor,
+ deserializer: FlatBuffersMessageDeserializer<GRPCMessage<MyGame_Example_Monster>>(),
+ serializer: FlatBuffersMessageSerializer<GRPCMessage<MyGame_Example_Monster>>(),
+ handler: { request, context in
+ try await self.Retrieve(
+ request: request,
+ context: context
+ )
+ }
+ )
+ router.registerHandler(
+ forMethod: MyGame_Example_MonsterStorage.Method.GetMaxHitPoint.descriptor,
+ deserializer: FlatBuffersMessageDeserializer<GRPCMessage<MyGame_Example_Stat>>(),
+ serializer: FlatBuffersMessageSerializer<GRPCMessage<MyGame_Example_Stat>>(),
+ handler: { request, context in
+ try await self.GetMaxHitPoint(
+ request: request,
+ context: context
+ )
+ }
+ )
+ router.registerHandler(
+ forMethod: MyGame_Example_MonsterStorage.Method.GetMinMaxHitPoints.descriptor,
+ deserializer: FlatBuffersMessageDeserializer<GRPCMessage<MyGame_Example_Stat>>(),
+ serializer: FlatBuffersMessageSerializer<GRPCMessage<MyGame_Example_Stat>>(),
+ 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: GRPCCore.StreamingServerRequest<GRPCMessage<MyGame_Example_Stat>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Stat>> {
+ let response = try await self.Store(
+ request: GRPCCore.ServerRequest(stream: request),
+ context: context
+ )
+ return GRPCCore.StreamingServerResponse(single: response)
+ }
+ public func Retrieve(
+ request: GRPCCore.StreamingServerRequest<GRPCMessage<MyGame_Example_Monster>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Monster>> {
+ let response = try await self.Retrieve(
+ request: GRPCCore.ServerRequest(stream: request),
+ context: context
+ )
+ return response
+ }
+ public func GetMaxHitPoint(
+ request: GRPCCore.StreamingServerRequest<GRPCMessage<MyGame_Example_Stat>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Stat>> {
+ let response = try await self.GetMaxHitPoint(
+ request: request,
+ 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<GRPCMessage<MyGame_Example_Stat>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.ServerResponse<GRPCMessage<MyGame_Example_Stat>> {
+ return GRPCCore.ServerResponse<GRPCMessage<MyGame_Example_Stat>>(
+ message: try await self.Store(
+ request: request.message,
+ context: context
+ ),
+ metadata: [:]
+ )
+ }
+ public func Retrieve(
+ request: GRPCCore.ServerRequest<GRPCMessage<MyGame_Example_Monster>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Monster>> {
+ return GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Monster>>(
+ metadata: [:],
+ producer: { writer in
+ try await self.Retrieve(
+ request: request.message,
+ response: writer,
+ context: context
+ )
+ return [:]
+ }
+ )
+ }
+ public func GetMaxHitPoint(
+ request: GRPCCore.StreamingServerRequest<GRPCMessage<MyGame_Example_Stat>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.ServerResponse<GRPCMessage<MyGame_Example_Stat>> {
+ return GRPCCore.ServerResponse<GRPCMessage<MyGame_Example_Stat>>(
+ message: try await self.GetMaxHitPoint(
+ request: request.messages,
+ context: context
+ ),
+ metadata: [:]
+ )
+ }
+ public func GetMinMaxHitPoints(
+ request: GRPCCore.StreamingServerRequest<GRPCMessage<MyGame_Example_Stat>>,
+ context: GRPCCore.ServerContext
+ ) async throws -> GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Stat>> {
+ return GRPCCore.StreamingServerResponse<GRPCMessage<MyGame_Example_Stat>>(
+ metadata: [:],
+ producer: { writer in
+ try await self.GetMinMaxHitPoints(
+ request: request.messages,
+ response: writer,
+ context: context
+ )
+ return [:]
+ }
+ )
+ }
+}
+
+
+// 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<Result>(
+ request: GRPCCore.ClientRequest<GRPCMessage<MyGame_Example_Stat>>,
+ serializer: some GRPCCore.MessageSerializer<GRPCMessage<MyGame_Example_Stat>>,
+ deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<MyGame_Example_Stat>>,
+ options: GRPCCore.CallOptions,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<MyGame_Example_Stat>>) async throws -> Result
+ ) async throws -> Result where Result: Sendable
+
+ func Retrieve<Result>(
+ request: GRPCCore.ClientRequest<GRPCMessage<MyGame_Example_Monster>>,
+ serializer: some GRPCCore.MessageSerializer<GRPCMessage<MyGame_Example_Monster>>,
+ deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<MyGame_Example_Monster>>,
+ options: GRPCCore.CallOptions,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<MyGame_Example_Monster>>) async throws -> Result
+ ) async throws -> Result where Result: Sendable
+
+ func GetMaxHitPoint<Result>(
+ request: GRPCCore.StreamingClientRequest<GRPCMessage<MyGame_Example_Stat>>,
+ serializer: some GRPCCore.MessageSerializer<GRPCMessage<MyGame_Example_Stat>>,
+ deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<MyGame_Example_Stat>>,
+ options: GRPCCore.CallOptions,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<MyGame_Example_Stat>>) async throws -> Result
+ ) async throws -> Result where Result: Sendable
+
+ func GetMinMaxHitPoints<Result>(
+ request: GRPCCore.StreamingClientRequest<GRPCMessage<MyGame_Example_Stat>>,
+ serializer: some GRPCCore.MessageSerializer<GRPCMessage<MyGame_Example_Stat>>,
+ deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<MyGame_Example_Stat>>,
+ options: GRPCCore.CallOptions,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<MyGame_Example_Stat>>) 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 MyGame_Example_MonsterStorage {
+ public struct Client<Transport>: ClientProtocol where Transport: GRPCCore.ClientTransport {
+ private let client: GRPCCore.GRPCClient<Transport>
+
+ public init(wrapping client: GRPCCore.GRPCClient<Transport>) {
+ self.client = client
+ }
+
+ public func Store<Result>(
+ request: GRPCCore.ClientRequest<GRPCMessage<MyGame_Example_Stat>>,
+ serializer: some GRPCCore.MessageSerializer<GRPCMessage<MyGame_Example_Stat>>,
+ deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<MyGame_Example_Stat>>,
+ options: GRPCCore.CallOptions = .defaults,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<MyGame_Example_Stat>>) 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<Result>(
+ request: GRPCCore.ClientRequest<GRPCMessage<MyGame_Example_Monster>>,
+ serializer: some GRPCCore.MessageSerializer<GRPCMessage<MyGame_Example_Monster>>,
+ deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<MyGame_Example_Monster>>,
+ options: GRPCCore.CallOptions = .defaults,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<MyGame_Example_Monster>>) 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<Result>(
+ request: GRPCCore.StreamingClientRequest<GRPCMessage<MyGame_Example_Stat>>,
+ serializer: some GRPCCore.MessageSerializer<GRPCMessage<MyGame_Example_Stat>>,
+ deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<MyGame_Example_Stat>>,
+ options: GRPCCore.CallOptions = .defaults,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<MyGame_Example_Stat>>) 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<Result>(
+ request: GRPCCore.StreamingClientRequest<GRPCMessage<MyGame_Example_Stat>>,
+ serializer: some GRPCCore.MessageSerializer<GRPCMessage<MyGame_Example_Stat>>,
+ deserializer: some GRPCCore.MessageDeserializer<GRPCMessage<MyGame_Example_Stat>>,
+ options: GRPCCore.CallOptions = .defaults,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<MyGame_Example_Stat>>) 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
+ )
+ }
+
+ }
+}
+
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
+extension MyGame_Example_MonsterStorage.ClientProtocol {
+ public func Store<Result>(
+ request: GRPCCore.ClientRequest<GRPCMessage<MyGame_Example_Stat>>,
+ options: GRPCCore.CallOptions = .defaults,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<MyGame_Example_Stat>>) async throws -> Result = { response in try response.message }
+ ) async throws -> Result where Result: Sendable {
+ try await self.Store(
+ request: request,
+ serializer: FlatBuffersMessageSerializer<GRPCMessage<MyGame_Example_Stat>>(),
+ deserializer: FlatBuffersMessageDeserializer<GRPCMessage<MyGame_Example_Stat>>(),
+ options: options,
+ onResponse: handleResponse
+ )
+ }
+
+ public func Retrieve<Result>(
+ request: GRPCCore.ClientRequest<GRPCMessage<MyGame_Example_Monster>>,
+ options: GRPCCore.CallOptions = .defaults,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<MyGame_Example_Monster>>) async throws -> Result
+ ) async throws -> Result where Result: Sendable {
+ try await self.Retrieve(
+ request: request,
+ serializer: FlatBuffersMessageSerializer<GRPCMessage<MyGame_Example_Monster>>(),
+ deserializer: FlatBuffersMessageDeserializer<GRPCMessage<MyGame_Example_Monster>>(),
+ options: options,
+ onResponse: handleResponse
+ )
+ }
+
+ public func GetMaxHitPoint<Result>(
+ request: GRPCCore.StreamingClientRequest<GRPCMessage<MyGame_Example_Stat>>,
+ options: GRPCCore.CallOptions = .defaults,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<MyGame_Example_Stat>>) async throws -> Result = { response in try response.message }
+ ) async throws -> Result where Result: Sendable {
+ try await self.GetMaxHitPoint(
+ request: request,
+ serializer: FlatBuffersMessageSerializer<GRPCMessage<MyGame_Example_Stat>>(),
+ deserializer: FlatBuffersMessageDeserializer<GRPCMessage<MyGame_Example_Stat>>(),
+ options: options,
+ onResponse: handleResponse
+ )
+ }
+
+ public func GetMinMaxHitPoints<Result>(
+ request: GRPCCore.StreamingClientRequest<GRPCMessage<MyGame_Example_Stat>>,
+ options: GRPCCore.CallOptions = .defaults,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<MyGame_Example_Stat>>) async throws -> Result
+ ) async throws -> Result where Result: Sendable {
+ try await self.GetMinMaxHitPoints(
+ request: request,
+ serializer: FlatBuffersMessageSerializer<GRPCMessage<MyGame_Example_Stat>>(),
+ deserializer: FlatBuffersMessageDeserializer<GRPCMessage<MyGame_Example_Stat>>(),
+ options: options,
+ onResponse: handleResponse
+ )
+ }
+
+}
+
+@available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *)
+extension MyGame_Example_MonsterStorage.ClientProtocol {
+ public func Store<Result>(
+ _ message: GRPCMessage<MyGame_Example_Stat>,
+ metadata: GRPCCore.Metadata = [:],
+ options: GRPCCore.CallOptions = .defaults,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<MyGame_Example_Stat>>) async throws -> Result = { try $0.message }
+ ) async throws -> Result where Result: Sendable {
+ let request = GRPCCore.ClientRequest<GRPCMessage<MyGame_Example_Stat>>(
+ message: message,
+ metadata: metadata
+ )
+ return try await self.Store(
+ request: request,
+ options: options,
+ onResponse: handleResponse
+ )
+ }
+
+ public func Retrieve<Result>(
+ _ message: GRPCMessage<MyGame_Example_Monster>,
+ metadata: GRPCCore.Metadata = [:],
+ options: GRPCCore.CallOptions = .defaults,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<MyGame_Example_Monster>>) async throws -> Result
+ ) async throws -> Result where Result: Sendable {
+ let request = GRPCCore.ClientRequest<GRPCMessage<MyGame_Example_Monster>>(
+ message: message,
+ metadata: metadata
+ )
+ return try await self.Retrieve(
+ request: request,
+ options: options,
+ onResponse: handleResponse
+ )
+ }
+
+ public func GetMaxHitPoint<Result>(
+ metadata: GRPCCore.Metadata = [:],
+ options: GRPCCore.CallOptions = .defaults,
+ requestProducer producer: @Sendable @escaping (GRPCCore.RPCWriter<GRPCMessage<MyGame_Example_Stat>>) async throws -> Void,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.ClientResponse<GRPCMessage<MyGame_Example_Stat>>) async throws -> Result = { try $0.message }
+ ) async throws -> Result where Result: Sendable {
+ let request = GRPCCore.StreamingClientRequest<GRPCMessage<MyGame_Example_Stat>>(
+ metadata: metadata,
+ producer: producer
+ )
+ return try await self.GetMaxHitPoint(
+ request: request,
+ options: options,
+ onResponse: handleResponse
+ )
+ }
+
+ public func GetMinMaxHitPoints<Result>(
+ metadata: GRPCCore.Metadata = [:],
+ options: GRPCCore.CallOptions = .defaults,
+ requestProducer producer: @Sendable @escaping (GRPCCore.RPCWriter<GRPCMessage<MyGame_Example_Stat>>) async throws -> Void,
+ onResponse handleResponse: @Sendable @escaping (GRPCCore.StreamingClientResponse<GRPCMessage<MyGame_Example_Stat>>) async throws -> Result
+ ) async throws -> Result where Result: Sendable {
+ let request = GRPCCore.StreamingClientRequest<GRPCMessage<MyGame_Example_Stat>>(
+ metadata: metadata,
+ producer: producer
+ )
+ return try await self.GetMinMaxHitPoints(
+ request: request,
+ options: options,
+ onResponse: handleResponse
+ )
+ }
+
+}
+
#endif
diff --git a/tests/swift/Tests/Flatbuffers/monster_test_generated.swift b/tests/swift/Tests/Flatbuffers/monster_test_generated.swift
index e6311fa..0dc49b0 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_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 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 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 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 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 @@
}
/// 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 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 78c6680..e1806cf 100644
--- a/tests/swift/Tests/Flatbuffers/more_defaults_generated.swift
+++ b/tests/swift/Tests/Flatbuffers/more_defaults_generated.swift
@@ -31,7 +31,7 @@
}
}
-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 c850fa1..8c15bc1 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 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 16d2169..7c1e682 100644
--- a/tests/swift/Tests/Flatbuffers/optional_scalars_generated.swift
+++ b/tests/swift/Tests/Flatbuffers/optional_scalars_generated.swift
@@ -31,7 +31,7 @@
}
}
-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 3d2bc56..fd12ffe 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 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 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 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 48f578f..2466703 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 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 dbbc637..42ecad3 100644
--- a/tests/swift/Tests/Flexbuffers/FlexBuffersReaderTests.swift
+++ b/tests/swift/Tests/Flexbuffers/FlexBuffersReaderTests.swift
@@ -127,7 +127,7 @@
#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 @@
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 e6311fa..0dc49b0 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_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 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 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 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 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 @@
}
/// 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 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 7391dc9..6c2adba 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 afb146d..0cd9933 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 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 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 }