Browse Source

Pass `CallOptions` through generated stub (#1911)

Motivation:

`CallOptions` is passed through the RPC methods in `GRPCClient` and set to the default if none (`CallOptions`) is provided. In order to make `CallOptions` easier to access, it will be passed through the RPC methods in the generated stub.

Modifications:

- Unset the default `CallOptions` for the RPC methods in `GRPCClient`.
- Add a new `options: CallOptions` parameter to the RPC methods in the generated stub, with a default value of `CallOptions.defaults`.

Result:

`CallOptions` will be passed through the generated stub rather than through `GRPCClient`.
Clinton Nkwocha 1 year ago
parent
commit
bf5d920562

+ 30 - 12
Sources/GRPCCodeGen/Internal/Translator/ClientCodeTranslator.swift

@@ -111,7 +111,8 @@ extension ClientCodeTranslator {
         for: $0,
         in: service,
         from: codeGenerationRequest,
-        generateSerializerDeserializer: false
+        includeBody: false,
+        includeDefaultCallOptions: false
       )
     }
 
@@ -135,8 +136,9 @@ extension ClientCodeTranslator {
         for: $0,
         in: service,
         from: codeGenerationRequest,
-        generateSerializerDeserializer: true,
-        accessModifier: self.accessModifier
+        includeBody: true,
+        accessModifier: self.accessModifier,
+        includeDefaultCallOptions: true
       )
     }
     let clientProtocolExtension = Declaration.extension(
@@ -155,14 +157,18 @@ extension ClientCodeTranslator {
     for method: CodeGenerationRequest.ServiceDescriptor.MethodDescriptor,
     in service: CodeGenerationRequest.ServiceDescriptor,
     from codeGenerationRequest: CodeGenerationRequest,
-    generateSerializerDeserializer: Bool,
-    accessModifier: AccessModifier? = nil
+    includeBody: Bool,
+    accessModifier: AccessModifier? = nil,
+    includeDefaultCallOptions: Bool
   ) -> Declaration {
+    let isProtocolExtension = includeBody
     let methodParameters = self.makeParameters(
       for: method,
       in: service,
       from: codeGenerationRequest,
-      generateSerializerDeserializer: generateSerializerDeserializer
+      // The serializer/deserializer for the protocol extension method will be auto-generated.
+      includeSerializationParameters: !isProtocolExtension,
+      includeDefaultCallOptions: includeDefaultCallOptions
     )
     let functionSignature = FunctionSignatureDescription(
       accessModifier: accessModifier,
@@ -177,8 +183,8 @@ extension ClientCodeTranslator {
       whereClause: WhereClause(requirements: [.conformance("R", "Sendable")])
     )
 
-    if generateSerializerDeserializer {
-      let body = self.makeSerializerDeserializerCall(
+    if includeBody {
+      let body = self.makeClientProtocolMethodCall(
         for: method,
         in: service,
         from: codeGenerationRequest
@@ -192,7 +198,7 @@ extension ClientCodeTranslator {
     }
   }
 
-  private func makeSerializerDeserializerCall(
+  private func makeClientProtocolMethodCall(
     for method: CodeGenerationRequest.ServiceDescriptor.MethodDescriptor,
     in service: CodeGenerationRequest.ServiceDescriptor,
     from codeGenerationRequest: CodeGenerationRequest
@@ -222,6 +228,7 @@ extension ClientCodeTranslator {
             )
           )
         ),
+        FunctionArgumentDescription(label: "options", expression: .identifierPattern("options")),
         FunctionArgumentDescription(expression: .identifierPattern("body")),
       ]
     )
@@ -235,15 +242,24 @@ extension ClientCodeTranslator {
     for method: CodeGenerationRequest.ServiceDescriptor.MethodDescriptor,
     in service: CodeGenerationRequest.ServiceDescriptor,
     from codeGenerationRequest: CodeGenerationRequest,
-    generateSerializerDeserializer: Bool
+    includeSerializationParameters: Bool,
+    includeDefaultCallOptions: Bool
   ) -> [ParameterDescription] {
     var parameters = [ParameterDescription]()
 
     parameters.append(self.clientRequestParameter(for: method, in: service))
-    if !generateSerializerDeserializer {
+    if includeSerializationParameters {
       parameters.append(self.serializerParameter(for: method, in: service))
       parameters.append(self.deserializerParameter(for: method, in: service))
     }
+    parameters.append(
+      ParameterDescription(
+        label: "options",
+        type: .member("CallOptions"),
+        defaultValue: includeDefaultCallOptions
+          ? .memberAccess(MemberAccessDescription(right: "defaults")) : nil
+      )
+    )
     parameters.append(self.bodyParameter(for: method, in: service))
     return parameters
   }
@@ -393,7 +409,8 @@ extension ClientCodeTranslator {
       for: method,
       in: service,
       from: codeGenerationRequest,
-      generateSerializerDeserializer: false
+      includeSerializationParameters: true,
+      includeDefaultCallOptions: true
     )
     let grpcMethodName = self.clientMethod(
       isInputStreaming: method.isInputStreaming,
@@ -413,6 +430,7 @@ extension ClientCodeTranslator {
         ),
         .init(label: "serializer", expression: .identifierPattern("serializer")),
         .init(label: "deserializer", expression: .identifierPattern("deserializer")),
+        .init(label: "options", expression: .identifierPattern("options")),
         .init(label: "handler", expression: .identifierPattern("body")),
       ]
     )

+ 4 - 4
Sources/GRPCCore/GRPCClient.swift

@@ -274,7 +274,7 @@ public struct GRPCClient: Sendable {
     descriptor: MethodDescriptor,
     serializer: some MessageSerializer<Request>,
     deserializer: some MessageDeserializer<Response>,
-    options: CallOptions = .defaults,
+    options: CallOptions,
     handler: @Sendable @escaping (ClientResponse.Single<Response>) async throws -> ReturnValue
   ) async throws -> ReturnValue {
     try await self.bidirectionalStreaming(
@@ -305,7 +305,7 @@ public struct GRPCClient: Sendable {
     descriptor: MethodDescriptor,
     serializer: some MessageSerializer<Request>,
     deserializer: some MessageDeserializer<Response>,
-    options: CallOptions = .defaults,
+    options: CallOptions,
     handler: @Sendable @escaping (ClientResponse.Single<Response>) async throws -> ReturnValue
   ) async throws -> ReturnValue {
     try await self.bidirectionalStreaming(
@@ -336,7 +336,7 @@ public struct GRPCClient: Sendable {
     descriptor: MethodDescriptor,
     serializer: some MessageSerializer<Request>,
     deserializer: some MessageDeserializer<Response>,
-    options: CallOptions = .defaults,
+    options: CallOptions,
     handler: @Sendable @escaping (ClientResponse.Stream<Response>) async throws -> ReturnValue
   ) async throws -> ReturnValue {
     try await self.bidirectionalStreaming(
@@ -368,7 +368,7 @@ public struct GRPCClient: Sendable {
     descriptor: MethodDescriptor,
     serializer: some MessageSerializer<Request>,
     deserializer: some MessageDeserializer<Response>,
-    options: CallOptions = .defaults,
+    options: CallOptions,
     handler: @Sendable @escaping (ClientResponse.Stream<Response>) async throws -> ReturnValue
   ) async throws -> ReturnValue {
     switch self.state.load(ordering: .sequentiallyConsistent) {

+ 55 - 0
Sources/InteroperabilityTests/Generated/test.grpc.swift

@@ -459,6 +459,7 @@ public protocol Grpc_Testing_TestServiceClientProtocol: Sendable {
         request: ClientRequest.Single<Grpc_Testing_TestService.Method.EmptyCall.Input>,
         serializer: some MessageSerializer<Grpc_Testing_TestService.Method.EmptyCall.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_TestService.Method.EmptyCall.Output>,
+        options: CallOptions,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_TestService.Method.EmptyCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable
 
@@ -467,6 +468,7 @@ public protocol Grpc_Testing_TestServiceClientProtocol: Sendable {
         request: ClientRequest.Single<Grpc_Testing_TestService.Method.UnaryCall.Input>,
         serializer: some MessageSerializer<Grpc_Testing_TestService.Method.UnaryCall.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_TestService.Method.UnaryCall.Output>,
+        options: CallOptions,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_TestService.Method.UnaryCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable
 
@@ -477,6 +479,7 @@ public protocol Grpc_Testing_TestServiceClientProtocol: Sendable {
         request: ClientRequest.Single<Grpc_Testing_TestService.Method.CacheableUnaryCall.Input>,
         serializer: some MessageSerializer<Grpc_Testing_TestService.Method.CacheableUnaryCall.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_TestService.Method.CacheableUnaryCall.Output>,
+        options: CallOptions,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_TestService.Method.CacheableUnaryCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable
 
@@ -486,6 +489,7 @@ public protocol Grpc_Testing_TestServiceClientProtocol: Sendable {
         request: ClientRequest.Single<Grpc_Testing_TestService.Method.StreamingOutputCall.Input>,
         serializer: some MessageSerializer<Grpc_Testing_TestService.Method.StreamingOutputCall.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_TestService.Method.StreamingOutputCall.Output>,
+        options: CallOptions,
         _ body: @Sendable @escaping (ClientResponse.Stream<Grpc_Testing_TestService.Method.StreamingOutputCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable
 
@@ -495,6 +499,7 @@ public protocol Grpc_Testing_TestServiceClientProtocol: Sendable {
         request: ClientRequest.Stream<Grpc_Testing_TestService.Method.StreamingInputCall.Input>,
         serializer: some MessageSerializer<Grpc_Testing_TestService.Method.StreamingInputCall.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_TestService.Method.StreamingInputCall.Output>,
+        options: CallOptions,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_TestService.Method.StreamingInputCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable
 
@@ -505,6 +510,7 @@ public protocol Grpc_Testing_TestServiceClientProtocol: Sendable {
         request: ClientRequest.Stream<Grpc_Testing_TestService.Method.FullDuplexCall.Input>,
         serializer: some MessageSerializer<Grpc_Testing_TestService.Method.FullDuplexCall.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_TestService.Method.FullDuplexCall.Output>,
+        options: CallOptions,
         _ body: @Sendable @escaping (ClientResponse.Stream<Grpc_Testing_TestService.Method.FullDuplexCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable
 
@@ -516,6 +522,7 @@ public protocol Grpc_Testing_TestServiceClientProtocol: Sendable {
         request: ClientRequest.Stream<Grpc_Testing_TestService.Method.HalfDuplexCall.Input>,
         serializer: some MessageSerializer<Grpc_Testing_TestService.Method.HalfDuplexCall.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_TestService.Method.HalfDuplexCall.Output>,
+        options: CallOptions,
         _ body: @Sendable @escaping (ClientResponse.Stream<Grpc_Testing_TestService.Method.HalfDuplexCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable
 
@@ -525,6 +532,7 @@ public protocol Grpc_Testing_TestServiceClientProtocol: Sendable {
         request: ClientRequest.Single<Grpc_Testing_TestService.Method.UnimplementedCall.Input>,
         serializer: some MessageSerializer<Grpc_Testing_TestService.Method.UnimplementedCall.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_TestService.Method.UnimplementedCall.Output>,
+        options: CallOptions,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_TestService.Method.UnimplementedCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable
 }
@@ -533,96 +541,112 @@ public protocol Grpc_Testing_TestServiceClientProtocol: Sendable {
 extension Grpc_Testing_TestService.ClientProtocol {
     public func emptyCall<R>(
         request: ClientRequest.Single<Grpc_Testing_TestService.Method.EmptyCall.Input>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_TestService.Method.EmptyCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.emptyCall(
             request: request,
             serializer: ProtobufSerializer<Grpc_Testing_TestService.Method.EmptyCall.Input>(),
             deserializer: ProtobufDeserializer<Grpc_Testing_TestService.Method.EmptyCall.Output>(),
+            options: options,
             body
         )
     }
 
     public func unaryCall<R>(
         request: ClientRequest.Single<Grpc_Testing_TestService.Method.UnaryCall.Input>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_TestService.Method.UnaryCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.unaryCall(
             request: request,
             serializer: ProtobufSerializer<Grpc_Testing_TestService.Method.UnaryCall.Input>(),
             deserializer: ProtobufDeserializer<Grpc_Testing_TestService.Method.UnaryCall.Output>(),
+            options: options,
             body
         )
     }
 
     public func cacheableUnaryCall<R>(
         request: ClientRequest.Single<Grpc_Testing_TestService.Method.CacheableUnaryCall.Input>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_TestService.Method.CacheableUnaryCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.cacheableUnaryCall(
             request: request,
             serializer: ProtobufSerializer<Grpc_Testing_TestService.Method.CacheableUnaryCall.Input>(),
             deserializer: ProtobufDeserializer<Grpc_Testing_TestService.Method.CacheableUnaryCall.Output>(),
+            options: options,
             body
         )
     }
 
     public func streamingOutputCall<R>(
         request: ClientRequest.Single<Grpc_Testing_TestService.Method.StreamingOutputCall.Input>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Stream<Grpc_Testing_TestService.Method.StreamingOutputCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.streamingOutputCall(
             request: request,
             serializer: ProtobufSerializer<Grpc_Testing_TestService.Method.StreamingOutputCall.Input>(),
             deserializer: ProtobufDeserializer<Grpc_Testing_TestService.Method.StreamingOutputCall.Output>(),
+            options: options,
             body
         )
     }
 
     public func streamingInputCall<R>(
         request: ClientRequest.Stream<Grpc_Testing_TestService.Method.StreamingInputCall.Input>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_TestService.Method.StreamingInputCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.streamingInputCall(
             request: request,
             serializer: ProtobufSerializer<Grpc_Testing_TestService.Method.StreamingInputCall.Input>(),
             deserializer: ProtobufDeserializer<Grpc_Testing_TestService.Method.StreamingInputCall.Output>(),
+            options: options,
             body
         )
     }
 
     public func fullDuplexCall<R>(
         request: ClientRequest.Stream<Grpc_Testing_TestService.Method.FullDuplexCall.Input>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Stream<Grpc_Testing_TestService.Method.FullDuplexCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.fullDuplexCall(
             request: request,
             serializer: ProtobufSerializer<Grpc_Testing_TestService.Method.FullDuplexCall.Input>(),
             deserializer: ProtobufDeserializer<Grpc_Testing_TestService.Method.FullDuplexCall.Output>(),
+            options: options,
             body
         )
     }
 
     public func halfDuplexCall<R>(
         request: ClientRequest.Stream<Grpc_Testing_TestService.Method.HalfDuplexCall.Input>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Stream<Grpc_Testing_TestService.Method.HalfDuplexCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.halfDuplexCall(
             request: request,
             serializer: ProtobufSerializer<Grpc_Testing_TestService.Method.HalfDuplexCall.Input>(),
             deserializer: ProtobufDeserializer<Grpc_Testing_TestService.Method.HalfDuplexCall.Output>(),
+            options: options,
             body
         )
     }
 
     public func unimplementedCall<R>(
         request: ClientRequest.Single<Grpc_Testing_TestService.Method.UnimplementedCall.Input>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_TestService.Method.UnimplementedCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.unimplementedCall(
             request: request,
             serializer: ProtobufSerializer<Grpc_Testing_TestService.Method.UnimplementedCall.Input>(),
             deserializer: ProtobufDeserializer<Grpc_Testing_TestService.Method.UnimplementedCall.Output>(),
+            options: options,
             body
         )
     }
@@ -643,6 +667,7 @@ public struct Grpc_Testing_TestServiceClient: Grpc_Testing_TestService.ClientPro
         request: ClientRequest.Single<Grpc_Testing_TestService.Method.EmptyCall.Input>,
         serializer: some MessageSerializer<Grpc_Testing_TestService.Method.EmptyCall.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_TestService.Method.EmptyCall.Output>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_TestService.Method.EmptyCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.client.unary(
@@ -650,6 +675,7 @@ public struct Grpc_Testing_TestServiceClient: Grpc_Testing_TestService.ClientPro
             descriptor: Grpc_Testing_TestService.Method.EmptyCall.descriptor,
             serializer: serializer,
             deserializer: deserializer,
+            options: options,
             handler: body
         )
     }
@@ -659,6 +685,7 @@ public struct Grpc_Testing_TestServiceClient: Grpc_Testing_TestService.ClientPro
         request: ClientRequest.Single<Grpc_Testing_TestService.Method.UnaryCall.Input>,
         serializer: some MessageSerializer<Grpc_Testing_TestService.Method.UnaryCall.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_TestService.Method.UnaryCall.Output>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_TestService.Method.UnaryCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.client.unary(
@@ -666,6 +693,7 @@ public struct Grpc_Testing_TestServiceClient: Grpc_Testing_TestService.ClientPro
             descriptor: Grpc_Testing_TestService.Method.UnaryCall.descriptor,
             serializer: serializer,
             deserializer: deserializer,
+            options: options,
             handler: body
         )
     }
@@ -677,6 +705,7 @@ public struct Grpc_Testing_TestServiceClient: Grpc_Testing_TestService.ClientPro
         request: ClientRequest.Single<Grpc_Testing_TestService.Method.CacheableUnaryCall.Input>,
         serializer: some MessageSerializer<Grpc_Testing_TestService.Method.CacheableUnaryCall.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_TestService.Method.CacheableUnaryCall.Output>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_TestService.Method.CacheableUnaryCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.client.unary(
@@ -684,6 +713,7 @@ public struct Grpc_Testing_TestServiceClient: Grpc_Testing_TestService.ClientPro
             descriptor: Grpc_Testing_TestService.Method.CacheableUnaryCall.descriptor,
             serializer: serializer,
             deserializer: deserializer,
+            options: options,
             handler: body
         )
     }
@@ -694,6 +724,7 @@ public struct Grpc_Testing_TestServiceClient: Grpc_Testing_TestService.ClientPro
         request: ClientRequest.Single<Grpc_Testing_TestService.Method.StreamingOutputCall.Input>,
         serializer: some MessageSerializer<Grpc_Testing_TestService.Method.StreamingOutputCall.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_TestService.Method.StreamingOutputCall.Output>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Stream<Grpc_Testing_TestService.Method.StreamingOutputCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.client.serverStreaming(
@@ -701,6 +732,7 @@ public struct Grpc_Testing_TestServiceClient: Grpc_Testing_TestService.ClientPro
             descriptor: Grpc_Testing_TestService.Method.StreamingOutputCall.descriptor,
             serializer: serializer,
             deserializer: deserializer,
+            options: options,
             handler: body
         )
     }
@@ -711,6 +743,7 @@ public struct Grpc_Testing_TestServiceClient: Grpc_Testing_TestService.ClientPro
         request: ClientRequest.Stream<Grpc_Testing_TestService.Method.StreamingInputCall.Input>,
         serializer: some MessageSerializer<Grpc_Testing_TestService.Method.StreamingInputCall.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_TestService.Method.StreamingInputCall.Output>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_TestService.Method.StreamingInputCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.client.clientStreaming(
@@ -718,6 +751,7 @@ public struct Grpc_Testing_TestServiceClient: Grpc_Testing_TestService.ClientPro
             descriptor: Grpc_Testing_TestService.Method.StreamingInputCall.descriptor,
             serializer: serializer,
             deserializer: deserializer,
+            options: options,
             handler: body
         )
     }
@@ -729,6 +763,7 @@ public struct Grpc_Testing_TestServiceClient: Grpc_Testing_TestService.ClientPro
         request: ClientRequest.Stream<Grpc_Testing_TestService.Method.FullDuplexCall.Input>,
         serializer: some MessageSerializer<Grpc_Testing_TestService.Method.FullDuplexCall.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_TestService.Method.FullDuplexCall.Output>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Stream<Grpc_Testing_TestService.Method.FullDuplexCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.client.bidirectionalStreaming(
@@ -736,6 +771,7 @@ public struct Grpc_Testing_TestServiceClient: Grpc_Testing_TestService.ClientPro
             descriptor: Grpc_Testing_TestService.Method.FullDuplexCall.descriptor,
             serializer: serializer,
             deserializer: deserializer,
+            options: options,
             handler: body
         )
     }
@@ -748,6 +784,7 @@ public struct Grpc_Testing_TestServiceClient: Grpc_Testing_TestService.ClientPro
         request: ClientRequest.Stream<Grpc_Testing_TestService.Method.HalfDuplexCall.Input>,
         serializer: some MessageSerializer<Grpc_Testing_TestService.Method.HalfDuplexCall.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_TestService.Method.HalfDuplexCall.Output>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Stream<Grpc_Testing_TestService.Method.HalfDuplexCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.client.bidirectionalStreaming(
@@ -755,6 +792,7 @@ public struct Grpc_Testing_TestServiceClient: Grpc_Testing_TestService.ClientPro
             descriptor: Grpc_Testing_TestService.Method.HalfDuplexCall.descriptor,
             serializer: serializer,
             deserializer: deserializer,
+            options: options,
             handler: body
         )
     }
@@ -765,6 +803,7 @@ public struct Grpc_Testing_TestServiceClient: Grpc_Testing_TestService.ClientPro
         request: ClientRequest.Single<Grpc_Testing_TestService.Method.UnimplementedCall.Input>,
         serializer: some MessageSerializer<Grpc_Testing_TestService.Method.UnimplementedCall.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_TestService.Method.UnimplementedCall.Output>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_TestService.Method.UnimplementedCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.client.unary(
@@ -772,6 +811,7 @@ public struct Grpc_Testing_TestServiceClient: Grpc_Testing_TestService.ClientPro
             descriptor: Grpc_Testing_TestService.Method.UnimplementedCall.descriptor,
             serializer: serializer,
             deserializer: deserializer,
+            options: options,
             handler: body
         )
     }
@@ -786,6 +826,7 @@ public protocol Grpc_Testing_UnimplementedServiceClientProtocol: Sendable {
         request: ClientRequest.Single<Grpc_Testing_UnimplementedService.Method.UnimplementedCall.Input>,
         serializer: some MessageSerializer<Grpc_Testing_UnimplementedService.Method.UnimplementedCall.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_UnimplementedService.Method.UnimplementedCall.Output>,
+        options: CallOptions,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_UnimplementedService.Method.UnimplementedCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable
 }
@@ -794,12 +835,14 @@ public protocol Grpc_Testing_UnimplementedServiceClientProtocol: Sendable {
 extension Grpc_Testing_UnimplementedService.ClientProtocol {
     public func unimplementedCall<R>(
         request: ClientRequest.Single<Grpc_Testing_UnimplementedService.Method.UnimplementedCall.Input>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_UnimplementedService.Method.UnimplementedCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.unimplementedCall(
             request: request,
             serializer: ProtobufSerializer<Grpc_Testing_UnimplementedService.Method.UnimplementedCall.Input>(),
             deserializer: ProtobufDeserializer<Grpc_Testing_UnimplementedService.Method.UnimplementedCall.Output>(),
+            options: options,
             body
         )
     }
@@ -820,6 +863,7 @@ public struct Grpc_Testing_UnimplementedServiceClient: Grpc_Testing_Unimplemente
         request: ClientRequest.Single<Grpc_Testing_UnimplementedService.Method.UnimplementedCall.Input>,
         serializer: some MessageSerializer<Grpc_Testing_UnimplementedService.Method.UnimplementedCall.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_UnimplementedService.Method.UnimplementedCall.Output>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_UnimplementedService.Method.UnimplementedCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.client.unary(
@@ -827,6 +871,7 @@ public struct Grpc_Testing_UnimplementedServiceClient: Grpc_Testing_Unimplemente
             descriptor: Grpc_Testing_UnimplementedService.Method.UnimplementedCall.descriptor,
             serializer: serializer,
             deserializer: deserializer,
+            options: options,
             handler: body
         )
     }
@@ -839,6 +884,7 @@ public protocol Grpc_Testing_ReconnectServiceClientProtocol: Sendable {
         request: ClientRequest.Single<Grpc_Testing_ReconnectService.Method.Start.Input>,
         serializer: some MessageSerializer<Grpc_Testing_ReconnectService.Method.Start.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_ReconnectService.Method.Start.Output>,
+        options: CallOptions,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_ReconnectService.Method.Start.Output>) async throws -> R
     ) async throws -> R where R: Sendable
 
@@ -846,6 +892,7 @@ public protocol Grpc_Testing_ReconnectServiceClientProtocol: Sendable {
         request: ClientRequest.Single<Grpc_Testing_ReconnectService.Method.Stop.Input>,
         serializer: some MessageSerializer<Grpc_Testing_ReconnectService.Method.Stop.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_ReconnectService.Method.Stop.Output>,
+        options: CallOptions,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_ReconnectService.Method.Stop.Output>) async throws -> R
     ) async throws -> R where R: Sendable
 }
@@ -854,24 +901,28 @@ public protocol Grpc_Testing_ReconnectServiceClientProtocol: Sendable {
 extension Grpc_Testing_ReconnectService.ClientProtocol {
     public func start<R>(
         request: ClientRequest.Single<Grpc_Testing_ReconnectService.Method.Start.Input>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_ReconnectService.Method.Start.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.start(
             request: request,
             serializer: ProtobufSerializer<Grpc_Testing_ReconnectService.Method.Start.Input>(),
             deserializer: ProtobufDeserializer<Grpc_Testing_ReconnectService.Method.Start.Output>(),
+            options: options,
             body
         )
     }
 
     public func stop<R>(
         request: ClientRequest.Single<Grpc_Testing_ReconnectService.Method.Stop.Input>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_ReconnectService.Method.Stop.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.stop(
             request: request,
             serializer: ProtobufSerializer<Grpc_Testing_ReconnectService.Method.Stop.Input>(),
             deserializer: ProtobufDeserializer<Grpc_Testing_ReconnectService.Method.Stop.Output>(),
+            options: options,
             body
         )
     }
@@ -890,6 +941,7 @@ public struct Grpc_Testing_ReconnectServiceClient: Grpc_Testing_ReconnectService
         request: ClientRequest.Single<Grpc_Testing_ReconnectService.Method.Start.Input>,
         serializer: some MessageSerializer<Grpc_Testing_ReconnectService.Method.Start.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_ReconnectService.Method.Start.Output>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_ReconnectService.Method.Start.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.client.unary(
@@ -897,6 +949,7 @@ public struct Grpc_Testing_ReconnectServiceClient: Grpc_Testing_ReconnectService
             descriptor: Grpc_Testing_ReconnectService.Method.Start.descriptor,
             serializer: serializer,
             deserializer: deserializer,
+            options: options,
             handler: body
         )
     }
@@ -905,6 +958,7 @@ public struct Grpc_Testing_ReconnectServiceClient: Grpc_Testing_ReconnectService
         request: ClientRequest.Single<Grpc_Testing_ReconnectService.Method.Stop.Input>,
         serializer: some MessageSerializer<Grpc_Testing_ReconnectService.Method.Stop.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_ReconnectService.Method.Stop.Output>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_ReconnectService.Method.Stop.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.client.unary(
@@ -912,6 +966,7 @@ public struct Grpc_Testing_ReconnectServiceClient: Grpc_Testing_ReconnectService
             descriptor: Grpc_Testing_ReconnectService.Method.Stop.descriptor,
             serializer: serializer,
             deserializer: deserializer,
+            options: options,
             handler: body
         )
     }

+ 25 - 0
Sources/performance-worker/Generated/grpc_testing_benchmark_service.grpc.swift

@@ -210,6 +210,7 @@ internal protocol Grpc_Testing_BenchmarkServiceClientProtocol: Sendable {
         request: ClientRequest.Single<Grpc_Testing_BenchmarkService.Method.UnaryCall.Input>,
         serializer: some MessageSerializer<Grpc_Testing_BenchmarkService.Method.UnaryCall.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_BenchmarkService.Method.UnaryCall.Output>,
+        options: CallOptions,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_BenchmarkService.Method.UnaryCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable
 
@@ -220,6 +221,7 @@ internal protocol Grpc_Testing_BenchmarkServiceClientProtocol: Sendable {
         request: ClientRequest.Stream<Grpc_Testing_BenchmarkService.Method.StreamingCall.Input>,
         serializer: some MessageSerializer<Grpc_Testing_BenchmarkService.Method.StreamingCall.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_BenchmarkService.Method.StreamingCall.Output>,
+        options: CallOptions,
         _ body: @Sendable @escaping (ClientResponse.Stream<Grpc_Testing_BenchmarkService.Method.StreamingCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable
 
@@ -229,6 +231,7 @@ internal protocol Grpc_Testing_BenchmarkServiceClientProtocol: Sendable {
         request: ClientRequest.Stream<Grpc_Testing_BenchmarkService.Method.StreamingFromClient.Input>,
         serializer: some MessageSerializer<Grpc_Testing_BenchmarkService.Method.StreamingFromClient.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_BenchmarkService.Method.StreamingFromClient.Output>,
+        options: CallOptions,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_BenchmarkService.Method.StreamingFromClient.Output>) async throws -> R
     ) async throws -> R where R: Sendable
 
@@ -238,6 +241,7 @@ internal protocol Grpc_Testing_BenchmarkServiceClientProtocol: Sendable {
         request: ClientRequest.Single<Grpc_Testing_BenchmarkService.Method.StreamingFromServer.Input>,
         serializer: some MessageSerializer<Grpc_Testing_BenchmarkService.Method.StreamingFromServer.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_BenchmarkService.Method.StreamingFromServer.Output>,
+        options: CallOptions,
         _ body: @Sendable @escaping (ClientResponse.Stream<Grpc_Testing_BenchmarkService.Method.StreamingFromServer.Output>) async throws -> R
     ) async throws -> R where R: Sendable
 
@@ -247,6 +251,7 @@ internal protocol Grpc_Testing_BenchmarkServiceClientProtocol: Sendable {
         request: ClientRequest.Stream<Grpc_Testing_BenchmarkService.Method.StreamingBothWays.Input>,
         serializer: some MessageSerializer<Grpc_Testing_BenchmarkService.Method.StreamingBothWays.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_BenchmarkService.Method.StreamingBothWays.Output>,
+        options: CallOptions,
         _ body: @Sendable @escaping (ClientResponse.Stream<Grpc_Testing_BenchmarkService.Method.StreamingBothWays.Output>) async throws -> R
     ) async throws -> R where R: Sendable
 }
@@ -255,60 +260,70 @@ internal protocol Grpc_Testing_BenchmarkServiceClientProtocol: Sendable {
 extension Grpc_Testing_BenchmarkService.ClientProtocol {
     internal func unaryCall<R>(
         request: ClientRequest.Single<Grpc_Testing_BenchmarkService.Method.UnaryCall.Input>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_BenchmarkService.Method.UnaryCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.unaryCall(
             request: request,
             serializer: ProtobufSerializer<Grpc_Testing_BenchmarkService.Method.UnaryCall.Input>(),
             deserializer: ProtobufDeserializer<Grpc_Testing_BenchmarkService.Method.UnaryCall.Output>(),
+            options: options,
             body
         )
     }
 
     internal func streamingCall<R>(
         request: ClientRequest.Stream<Grpc_Testing_BenchmarkService.Method.StreamingCall.Input>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Stream<Grpc_Testing_BenchmarkService.Method.StreamingCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.streamingCall(
             request: request,
             serializer: ProtobufSerializer<Grpc_Testing_BenchmarkService.Method.StreamingCall.Input>(),
             deserializer: ProtobufDeserializer<Grpc_Testing_BenchmarkService.Method.StreamingCall.Output>(),
+            options: options,
             body
         )
     }
 
     internal func streamingFromClient<R>(
         request: ClientRequest.Stream<Grpc_Testing_BenchmarkService.Method.StreamingFromClient.Input>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_BenchmarkService.Method.StreamingFromClient.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.streamingFromClient(
             request: request,
             serializer: ProtobufSerializer<Grpc_Testing_BenchmarkService.Method.StreamingFromClient.Input>(),
             deserializer: ProtobufDeserializer<Grpc_Testing_BenchmarkService.Method.StreamingFromClient.Output>(),
+            options: options,
             body
         )
     }
 
     internal func streamingFromServer<R>(
         request: ClientRequest.Single<Grpc_Testing_BenchmarkService.Method.StreamingFromServer.Input>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Stream<Grpc_Testing_BenchmarkService.Method.StreamingFromServer.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.streamingFromServer(
             request: request,
             serializer: ProtobufSerializer<Grpc_Testing_BenchmarkService.Method.StreamingFromServer.Input>(),
             deserializer: ProtobufDeserializer<Grpc_Testing_BenchmarkService.Method.StreamingFromServer.Output>(),
+            options: options,
             body
         )
     }
 
     internal func streamingBothWays<R>(
         request: ClientRequest.Stream<Grpc_Testing_BenchmarkService.Method.StreamingBothWays.Input>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Stream<Grpc_Testing_BenchmarkService.Method.StreamingBothWays.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.streamingBothWays(
             request: request,
             serializer: ProtobufSerializer<Grpc_Testing_BenchmarkService.Method.StreamingBothWays.Input>(),
             deserializer: ProtobufDeserializer<Grpc_Testing_BenchmarkService.Method.StreamingBothWays.Output>(),
+            options: options,
             body
         )
     }
@@ -328,6 +343,7 @@ internal struct Grpc_Testing_BenchmarkServiceClient: Grpc_Testing_BenchmarkServi
         request: ClientRequest.Single<Grpc_Testing_BenchmarkService.Method.UnaryCall.Input>,
         serializer: some MessageSerializer<Grpc_Testing_BenchmarkService.Method.UnaryCall.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_BenchmarkService.Method.UnaryCall.Output>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_BenchmarkService.Method.UnaryCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.client.unary(
@@ -335,6 +351,7 @@ internal struct Grpc_Testing_BenchmarkServiceClient: Grpc_Testing_BenchmarkServi
             descriptor: Grpc_Testing_BenchmarkService.Method.UnaryCall.descriptor,
             serializer: serializer,
             deserializer: deserializer,
+            options: options,
             handler: body
         )
     }
@@ -346,6 +363,7 @@ internal struct Grpc_Testing_BenchmarkServiceClient: Grpc_Testing_BenchmarkServi
         request: ClientRequest.Stream<Grpc_Testing_BenchmarkService.Method.StreamingCall.Input>,
         serializer: some MessageSerializer<Grpc_Testing_BenchmarkService.Method.StreamingCall.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_BenchmarkService.Method.StreamingCall.Output>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Stream<Grpc_Testing_BenchmarkService.Method.StreamingCall.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.client.bidirectionalStreaming(
@@ -353,6 +371,7 @@ internal struct Grpc_Testing_BenchmarkServiceClient: Grpc_Testing_BenchmarkServi
             descriptor: Grpc_Testing_BenchmarkService.Method.StreamingCall.descriptor,
             serializer: serializer,
             deserializer: deserializer,
+            options: options,
             handler: body
         )
     }
@@ -363,6 +382,7 @@ internal struct Grpc_Testing_BenchmarkServiceClient: Grpc_Testing_BenchmarkServi
         request: ClientRequest.Stream<Grpc_Testing_BenchmarkService.Method.StreamingFromClient.Input>,
         serializer: some MessageSerializer<Grpc_Testing_BenchmarkService.Method.StreamingFromClient.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_BenchmarkService.Method.StreamingFromClient.Output>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Single<Grpc_Testing_BenchmarkService.Method.StreamingFromClient.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.client.clientStreaming(
@@ -370,6 +390,7 @@ internal struct Grpc_Testing_BenchmarkServiceClient: Grpc_Testing_BenchmarkServi
             descriptor: Grpc_Testing_BenchmarkService.Method.StreamingFromClient.descriptor,
             serializer: serializer,
             deserializer: deserializer,
+            options: options,
             handler: body
         )
     }
@@ -380,6 +401,7 @@ internal struct Grpc_Testing_BenchmarkServiceClient: Grpc_Testing_BenchmarkServi
         request: ClientRequest.Single<Grpc_Testing_BenchmarkService.Method.StreamingFromServer.Input>,
         serializer: some MessageSerializer<Grpc_Testing_BenchmarkService.Method.StreamingFromServer.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_BenchmarkService.Method.StreamingFromServer.Output>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Stream<Grpc_Testing_BenchmarkService.Method.StreamingFromServer.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.client.serverStreaming(
@@ -387,6 +409,7 @@ internal struct Grpc_Testing_BenchmarkServiceClient: Grpc_Testing_BenchmarkServi
             descriptor: Grpc_Testing_BenchmarkService.Method.StreamingFromServer.descriptor,
             serializer: serializer,
             deserializer: deserializer,
+            options: options,
             handler: body
         )
     }
@@ -397,6 +420,7 @@ internal struct Grpc_Testing_BenchmarkServiceClient: Grpc_Testing_BenchmarkServi
         request: ClientRequest.Stream<Grpc_Testing_BenchmarkService.Method.StreamingBothWays.Input>,
         serializer: some MessageSerializer<Grpc_Testing_BenchmarkService.Method.StreamingBothWays.Input>,
         deserializer: some MessageDeserializer<Grpc_Testing_BenchmarkService.Method.StreamingBothWays.Output>,
+        options: CallOptions = .defaults,
         _ body: @Sendable @escaping (ClientResponse.Stream<Grpc_Testing_BenchmarkService.Method.StreamingBothWays.Output>) async throws -> R
     ) async throws -> R where R: Sendable {
         try await self.client.bidirectionalStreaming(
@@ -404,6 +428,7 @@ internal struct Grpc_Testing_BenchmarkServiceClient: Grpc_Testing_BenchmarkServi
             descriptor: Grpc_Testing_BenchmarkService.Method.StreamingBothWays.descriptor,
             serializer: serializer,
             deserializer: deserializer,
+            options: options,
             handler: body
         )
     }

+ 27 - 3
Sources/performance-worker/Generated/grpc_testing_control.pb.swift

@@ -1364,7 +1364,15 @@ extension Grpc_Testing_ClientConfig: SwiftProtobuf.Message, SwiftProtobuf._Messa
     var _medianLatencyCollectionIntervalMillis: Int32 = 0
     var _clientProcesses: Int32 = 0
 
-    static let defaultInstance = _StorageClass()
+    #if swift(>=5.10)
+      // This property is used as the initial default value for new instances of the type.
+      // The type itself is protecting the reference to its storage via CoW semantics.
+      // This will force a copy to be made of this reference when the first mutation occurs;
+      // hence, it is safe to mark this as `nonisolated(unsafe)`.
+      static nonisolated(unsafe) let defaultInstance = _StorageClass()
+    #else
+      static let defaultInstance = _StorageClass()
+    #endif
 
     private init() {}
 
@@ -1982,7 +1990,15 @@ extension Grpc_Testing_Scenario: SwiftProtobuf.Message, SwiftProtobuf._MessageIm
     var _benchmarkSeconds: Int32 = 0
     var _spawnLocalWorkerCount: Int32 = 0
 
-    static let defaultInstance = _StorageClass()
+    #if swift(>=5.10)
+      // This property is used as the initial default value for new instances of the type.
+      // The type itself is protecting the reference to its storage via CoW semantics.
+      // This will force a copy to be made of this reference when the first mutation occurs;
+      // hence, it is safe to mark this as `nonisolated(unsafe)`.
+      static nonisolated(unsafe) let defaultInstance = _StorageClass()
+    #else
+      static let defaultInstance = _StorageClass()
+    #endif
 
     private init() {}
 
@@ -2162,7 +2178,15 @@ extension Grpc_Testing_ScenarioResultSummary: SwiftProtobuf.Message, SwiftProtob
     var _startTime: SwiftProtobuf.Google_Protobuf_Timestamp? = nil
     var _endTime: SwiftProtobuf.Google_Protobuf_Timestamp? = nil
 
-    static let defaultInstance = _StorageClass()
+    #if swift(>=5.10)
+      // This property is used as the initial default value for new instances of the type.
+      // The type itself is protecting the reference to its storage via CoW semantics.
+      // This will force a copy to be made of this reference when the first mutation occurs;
+      // hence, it is safe to mark this as `nonisolated(unsafe)`.
+      static nonisolated(unsafe) let defaultInstance = _StorageClass()
+    #else
+      static let defaultInstance = _StorageClass()
+    #endif
 
     private init() {}
 

+ 35 - 0
Tests/GRPCCodeGenTests/Internal/Translator/ClientCodeTranslatorSnippetBasedTests.swift

@@ -50,6 +50,7 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
               request: ClientRequest.Single<NamespaceA_ServiceA.Method.MethodA.Input>,
               serializer: some MessageSerializer<NamespaceA_ServiceA.Method.MethodA.Input>,
               deserializer: some MessageDeserializer<NamespaceA_ServiceA.Method.MethodA.Output>,
+              options: CallOptions,
               _ body: @Sendable @escaping (ClientResponse.Single<NamespaceA_ServiceA.Method.MethodA.Output>) async throws -> R
           ) async throws -> R where R: Sendable
       }
@@ -57,12 +58,14 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
       extension NamespaceA_ServiceA.ClientProtocol {
           public func methodA<R>(
               request: ClientRequest.Single<NamespaceA_ServiceA.Method.MethodA.Input>,
+              options: CallOptions = .defaults,
               _ body: @Sendable @escaping (ClientResponse.Single<NamespaceA_ServiceA.Method.MethodA.Output>) async throws -> R
           ) async throws -> R where R: Sendable {
               try await self.methodA(
                   request: request,
                   serializer: ProtobufSerializer<NamespaceA_ServiceA.Method.MethodA.Input>(),
                   deserializer: ProtobufDeserializer<NamespaceA_ServiceA.Method.MethodA.Output>(),
+                  options: options,
                   body
               )
           }
@@ -81,6 +84,7 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
               request: ClientRequest.Single<NamespaceA_ServiceA.Method.MethodA.Input>,
               serializer: some MessageSerializer<NamespaceA_ServiceA.Method.MethodA.Input>,
               deserializer: some MessageDeserializer<NamespaceA_ServiceA.Method.MethodA.Output>,
+              options: CallOptions = .defaults,
               _ body: @Sendable @escaping (ClientResponse.Single<NamespaceA_ServiceA.Method.MethodA.Output>) async throws -> R
           ) async throws -> R where R: Sendable {
               try await self.client.unary(
@@ -88,6 +92,7 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
                   descriptor: NamespaceA_ServiceA.Method.MethodA.descriptor,
                   serializer: serializer,
                   deserializer: deserializer,
+                  options: options,
                   handler: body
               )
           }
@@ -126,6 +131,7 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
               request: ClientRequest.Stream<NamespaceA_ServiceA.Method.MethodA.Input>,
               serializer: some MessageSerializer<NamespaceA_ServiceA.Method.MethodA.Input>,
               deserializer: some MessageDeserializer<NamespaceA_ServiceA.Method.MethodA.Output>,
+              options: CallOptions,
               _ body: @Sendable @escaping (ClientResponse.Single<NamespaceA_ServiceA.Method.MethodA.Output>) async throws -> R
           ) async throws -> R where R: Sendable
       }
@@ -133,12 +139,14 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
       extension NamespaceA_ServiceA.ClientProtocol {
           public func methodA<R>(
               request: ClientRequest.Stream<NamespaceA_ServiceA.Method.MethodA.Input>,
+              options: CallOptions = .defaults,
               _ body: @Sendable @escaping (ClientResponse.Single<NamespaceA_ServiceA.Method.MethodA.Output>) async throws -> R
           ) async throws -> R where R: Sendable {
               try await self.methodA(
                   request: request,
                   serializer: ProtobufSerializer<NamespaceA_ServiceA.Method.MethodA.Input>(),
                   deserializer: ProtobufDeserializer<NamespaceA_ServiceA.Method.MethodA.Output>(),
+                  options: options,
                   body
               )
           }
@@ -157,6 +165,7 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
               request: ClientRequest.Stream<NamespaceA_ServiceA.Method.MethodA.Input>,
               serializer: some MessageSerializer<NamespaceA_ServiceA.Method.MethodA.Input>,
               deserializer: some MessageDeserializer<NamespaceA_ServiceA.Method.MethodA.Output>,
+              options: CallOptions = .defaults,
               _ body: @Sendable @escaping (ClientResponse.Single<NamespaceA_ServiceA.Method.MethodA.Output>) async throws -> R
           ) async throws -> R where R: Sendable {
               try await self.client.clientStreaming(
@@ -164,6 +173,7 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
                   descriptor: NamespaceA_ServiceA.Method.MethodA.descriptor,
                   serializer: serializer,
                   deserializer: deserializer,
+                  options: options,
                   handler: body
               )
           }
@@ -202,6 +212,7 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
               request: ClientRequest.Single<NamespaceA_ServiceA.Method.MethodA.Input>,
               serializer: some MessageSerializer<NamespaceA_ServiceA.Method.MethodA.Input>,
               deserializer: some MessageDeserializer<NamespaceA_ServiceA.Method.MethodA.Output>,
+              options: CallOptions,
               _ body: @Sendable @escaping (ClientResponse.Stream<NamespaceA_ServiceA.Method.MethodA.Output>) async throws -> R
           ) async throws -> R where R: Sendable
       }
@@ -209,12 +220,14 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
       extension NamespaceA_ServiceA.ClientProtocol {
           public func methodA<R>(
               request: ClientRequest.Single<NamespaceA_ServiceA.Method.MethodA.Input>,
+              options: CallOptions = .defaults,
               _ body: @Sendable @escaping (ClientResponse.Stream<NamespaceA_ServiceA.Method.MethodA.Output>) async throws -> R
           ) async throws -> R where R: Sendable {
               try await self.methodA(
                   request: request,
                   serializer: ProtobufSerializer<NamespaceA_ServiceA.Method.MethodA.Input>(),
                   deserializer: ProtobufDeserializer<NamespaceA_ServiceA.Method.MethodA.Output>(),
+                  options: options,
                   body
               )
           }
@@ -233,6 +246,7 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
               request: ClientRequest.Single<NamespaceA_ServiceA.Method.MethodA.Input>,
               serializer: some MessageSerializer<NamespaceA_ServiceA.Method.MethodA.Input>,
               deserializer: some MessageDeserializer<NamespaceA_ServiceA.Method.MethodA.Output>,
+              options: CallOptions = .defaults,
               _ body: @Sendable @escaping (ClientResponse.Stream<NamespaceA_ServiceA.Method.MethodA.Output>) async throws -> R
           ) async throws -> R where R: Sendable {
               try await self.client.serverStreaming(
@@ -240,6 +254,7 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
                   descriptor: NamespaceA_ServiceA.Method.MethodA.descriptor,
                   serializer: serializer,
                   deserializer: deserializer,
+                  options: options,
                   handler: body
               )
           }
@@ -278,6 +293,7 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
               request: ClientRequest.Stream<NamespaceA_ServiceA.Method.MethodA.Input>,
               serializer: some MessageSerializer<NamespaceA_ServiceA.Method.MethodA.Input>,
               deserializer: some MessageDeserializer<NamespaceA_ServiceA.Method.MethodA.Output>,
+              options: CallOptions,
               _ body: @Sendable @escaping (ClientResponse.Stream<NamespaceA_ServiceA.Method.MethodA.Output>) async throws -> R
           ) async throws -> R where R: Sendable
       }
@@ -285,12 +301,14 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
       extension NamespaceA_ServiceA.ClientProtocol {
           public func methodA<R>(
               request: ClientRequest.Stream<NamespaceA_ServiceA.Method.MethodA.Input>,
+              options: CallOptions = .defaults,
               _ body: @Sendable @escaping (ClientResponse.Stream<NamespaceA_ServiceA.Method.MethodA.Output>) async throws -> R
           ) async throws -> R where R: Sendable {
               try await self.methodA(
                   request: request,
                   serializer: ProtobufSerializer<NamespaceA_ServiceA.Method.MethodA.Input>(),
                   deserializer: ProtobufDeserializer<NamespaceA_ServiceA.Method.MethodA.Output>(),
+                  options: options,
                   body
               )
           }
@@ -309,6 +327,7 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
               request: ClientRequest.Stream<NamespaceA_ServiceA.Method.MethodA.Input>,
               serializer: some MessageSerializer<NamespaceA_ServiceA.Method.MethodA.Input>,
               deserializer: some MessageDeserializer<NamespaceA_ServiceA.Method.MethodA.Output>,
+              options: CallOptions = .defaults,
               _ body: @Sendable @escaping (ClientResponse.Stream<NamespaceA_ServiceA.Method.MethodA.Output>) async throws -> R
           ) async throws -> R where R: Sendable {
               try await self.client.bidirectionalStreaming(
@@ -316,6 +335,7 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
                   descriptor: NamespaceA_ServiceA.Method.MethodA.descriptor,
                   serializer: serializer,
                   deserializer: deserializer,
+                  options: options,
                   handler: body
               )
           }
@@ -362,6 +382,7 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
               request: ClientRequest.Stream<NamespaceA_ServiceA.Method.MethodA.Input>,
               serializer: some MessageSerializer<NamespaceA_ServiceA.Method.MethodA.Input>,
               deserializer: some MessageDeserializer<NamespaceA_ServiceA.Method.MethodA.Output>,
+              options: CallOptions,
               _ body: @Sendable @escaping (ClientResponse.Single<NamespaceA_ServiceA.Method.MethodA.Output>) async throws -> R
           ) async throws -> R where R: Sendable
           
@@ -370,6 +391,7 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
               request: ClientRequest.Single<NamespaceA_ServiceA.Method.MethodB.Input>,
               serializer: some MessageSerializer<NamespaceA_ServiceA.Method.MethodB.Input>,
               deserializer: some MessageDeserializer<NamespaceA_ServiceA.Method.MethodB.Output>,
+              options: CallOptions,
               _ body: @Sendable @escaping (ClientResponse.Stream<NamespaceA_ServiceA.Method.MethodB.Output>) async throws -> R
           ) async throws -> R where R: Sendable
       }
@@ -377,24 +399,28 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
       extension NamespaceA_ServiceA.ClientProtocol {
           package func methodA<R>(
               request: ClientRequest.Stream<NamespaceA_ServiceA.Method.MethodA.Input>,
+              options: CallOptions = .defaults,
               _ body: @Sendable @escaping (ClientResponse.Single<NamespaceA_ServiceA.Method.MethodA.Output>) async throws -> R
           ) async throws -> R where R: Sendable {
               try await self.methodA(
                   request: request,
                   serializer: ProtobufSerializer<NamespaceA_ServiceA.Method.MethodA.Input>(),
                   deserializer: ProtobufDeserializer<NamespaceA_ServiceA.Method.MethodA.Output>(),
+                  options: options,
                   body
               )
           }
           
           package func methodB<R>(
               request: ClientRequest.Single<NamespaceA_ServiceA.Method.MethodB.Input>,
+              options: CallOptions = .defaults,
               _ body: @Sendable @escaping (ClientResponse.Stream<NamespaceA_ServiceA.Method.MethodB.Output>) async throws -> R
           ) async throws -> R where R: Sendable {
               try await self.methodB(
                   request: request,
                   serializer: ProtobufSerializer<NamespaceA_ServiceA.Method.MethodB.Input>(),
                   deserializer: ProtobufDeserializer<NamespaceA_ServiceA.Method.MethodB.Output>(),
+                  options: options,
                   body
               )
           }
@@ -413,6 +439,7 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
               request: ClientRequest.Stream<NamespaceA_ServiceA.Method.MethodA.Input>,
               serializer: some MessageSerializer<NamespaceA_ServiceA.Method.MethodA.Input>,
               deserializer: some MessageDeserializer<NamespaceA_ServiceA.Method.MethodA.Output>,
+              options: CallOptions = .defaults,
               _ body: @Sendable @escaping (ClientResponse.Single<NamespaceA_ServiceA.Method.MethodA.Output>) async throws -> R
           ) async throws -> R where R: Sendable {
               try await self.client.clientStreaming(
@@ -420,6 +447,7 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
                   descriptor: NamespaceA_ServiceA.Method.MethodA.descriptor,
                   serializer: serializer,
                   deserializer: deserializer,
+                  options: options,
                   handler: body
               )
           }
@@ -429,6 +457,7 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
               request: ClientRequest.Single<NamespaceA_ServiceA.Method.MethodB.Input>,
               serializer: some MessageSerializer<NamespaceA_ServiceA.Method.MethodB.Input>,
               deserializer: some MessageDeserializer<NamespaceA_ServiceA.Method.MethodB.Output>,
+              options: CallOptions = .defaults,
               _ body: @Sendable @escaping (ClientResponse.Stream<NamespaceA_ServiceA.Method.MethodB.Output>) async throws -> R
           ) async throws -> R where R: Sendable {
               try await self.client.serverStreaming(
@@ -436,6 +465,7 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
                   descriptor: NamespaceA_ServiceA.Method.MethodB.descriptor,
                   serializer: serializer,
                   deserializer: deserializer,
+                  options: options,
                   handler: body
               )
           }
@@ -474,6 +504,7 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
               request: ClientRequest.Single<ServiceA.Method.MethodA.Input>,
               serializer: some MessageSerializer<ServiceA.Method.MethodA.Input>,
               deserializer: some MessageDeserializer<ServiceA.Method.MethodA.Output>,
+              options: CallOptions,
               _ body: @Sendable @escaping (ClientResponse.Single<ServiceA.Method.MethodA.Output>) async throws -> R
           ) async throws -> R where R: Sendable
       }
@@ -481,12 +512,14 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
       extension ServiceA.ClientProtocol {
           internal func methodA<R>(
               request: ClientRequest.Single<ServiceA.Method.MethodA.Input>,
+              options: CallOptions = .defaults,
               _ body: @Sendable @escaping (ClientResponse.Single<ServiceA.Method.MethodA.Output>) async throws -> R
           ) async throws -> R where R: Sendable {
               try await self.methodA(
                   request: request,
                   serializer: ProtobufSerializer<ServiceA.Method.MethodA.Input>(),
                   deserializer: ProtobufDeserializer<ServiceA.Method.MethodA.Output>(),
+                  options: options,
                   body
               )
           }
@@ -505,6 +538,7 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
               request: ClientRequest.Single<ServiceA.Method.MethodA.Input>,
               serializer: some MessageSerializer<ServiceA.Method.MethodA.Input>,
               deserializer: some MessageDeserializer<ServiceA.Method.MethodA.Output>,
+              options: CallOptions = .defaults,
               _ body: @Sendable @escaping (ClientResponse.Single<ServiceA.Method.MethodA.Output>) async throws -> R
           ) async throws -> R where R: Sendable {
               try await self.client.unary(
@@ -512,6 +546,7 @@ final class ClientCodeTranslatorSnippetBasedTests: XCTestCase {
                   descriptor: ServiceA.Method.MethodA.descriptor,
                   serializer: serializer,
                   deserializer: deserializer,
+                  options: options,
                   handler: body
               )
           }

+ 18 - 2
Tests/GRPCCoreTests/Configuration/Generated/service_config.pb.swift

@@ -2680,7 +2680,15 @@ extension Grpc_ServiceConfig_RlsLoadBalancingPolicyConfig: SwiftProtobuf.Message
     var _childPolicy: [Grpc_ServiceConfig_LoadBalancingConfig] = []
     var _childPolicyConfigTargetFieldName: String = String()
 
-    static let defaultInstance = _StorageClass()
+    #if swift(>=5.10)
+      // This property is used as the initial default value for new instances of the type.
+      // The type itself is protecting the reference to its storage via CoW semantics.
+      // This will force a copy to be made of this reference when the first mutation occurs;
+      // hence, it is safe to mark this as `nonisolated(unsafe)`.
+      static nonisolated(unsafe) let defaultInstance = _StorageClass()
+    #else
+      static let defaultInstance = _StorageClass()
+    #endif
 
     private init() {}
 
@@ -3004,7 +3012,15 @@ extension Grpc_ServiceConfig_XdsClusterResolverLoadBalancingPolicyConfig.Discove
     var _overrideHostStatus: [Grpc_ServiceConfig_OverrideHostLoadBalancingPolicyConfig.HealthStatus] = []
     var _telemetryLabels: Dictionary<String,String> = [:]
 
-    static let defaultInstance = _StorageClass()
+    #if swift(>=5.10)
+      // This property is used as the initial default value for new instances of the type.
+      // The type itself is protecting the reference to its storage via CoW semantics.
+      // This will force a copy to be made of this reference when the first mutation occurs;
+      // hence, it is safe to mark this as `nonisolated(unsafe)`.
+      static nonisolated(unsafe) let defaultInstance = _StorageClass()
+    #else
+      static let defaultInstance = _StorageClass()
+    #endif
 
     private init() {}
 

+ 32 - 16
Tests/GRPCCoreTests/GRPCClientTests.swift

@@ -68,7 +68,8 @@ final class GRPCClientTests: XCTestCase {
         request: .init(message: [3, 1, 4, 1, 5]),
         descriptor: BinaryEcho.Methods.collect,
         serializer: IdentitySerializer(),
-        deserializer: IdentityDeserializer()
+        deserializer: IdentityDeserializer(),
+        options: .defaults
       ) { response in
         let message = try response.message
         XCTAssertEqual(message, [3, 1, 4, 1, 5])
@@ -86,7 +87,8 @@ final class GRPCClientTests: XCTestCase {
         }),
         descriptor: BinaryEcho.Methods.collect,
         serializer: IdentitySerializer(),
-        deserializer: IdentityDeserializer()
+        deserializer: IdentityDeserializer(),
+        options: .defaults
       ) { response in
         let message = try response.message
         XCTAssertEqual(message, [3, 1, 4, 1, 5])
@@ -100,7 +102,8 @@ final class GRPCClientTests: XCTestCase {
         request: .init(message: [3, 1, 4, 1, 5]),
         descriptor: BinaryEcho.Methods.expand,
         serializer: IdentitySerializer(),
-        deserializer: IdentityDeserializer()
+        deserializer: IdentityDeserializer(),
+        options: .defaults
       ) { response in
         var responseParts = response.messages.makeAsyncIterator()
         for byte in [3, 1, 4, 1, 5] as [UInt8] {
@@ -121,7 +124,8 @@ final class GRPCClientTests: XCTestCase {
         }),
         descriptor: BinaryEcho.Methods.update,
         serializer: IdentitySerializer(),
-        deserializer: IdentityDeserializer()
+        deserializer: IdentityDeserializer(),
+        options: .defaults
       ) { response in
         var responseParts = response.messages.makeAsyncIterator()
         for byte in [3, 1, 4, 1, 5] as [UInt8] {
@@ -138,7 +142,8 @@ final class GRPCClientTests: XCTestCase {
         request: .init(message: [3, 1, 4, 1, 5]),
         descriptor: MethodDescriptor(service: "not", method: "implemented"),
         serializer: IdentitySerializer(),
-        deserializer: IdentityDeserializer()
+        deserializer: IdentityDeserializer(),
+        options: .defaults
       ) { response in
         XCTAssertThrowsRPCError(try response.accepted.get()) { error in
           XCTAssertEqual(error.code, .unimplemented)
@@ -157,7 +162,8 @@ final class GRPCClientTests: XCTestCase {
         }),
         descriptor: MethodDescriptor(service: "not", method: "implemented"),
         serializer: IdentitySerializer(),
-        deserializer: IdentityDeserializer()
+        deserializer: IdentityDeserializer(),
+        options: .defaults
       ) { response in
         XCTAssertThrowsRPCError(try response.accepted.get()) { error in
           XCTAssertEqual(error.code, .unimplemented)
@@ -172,7 +178,8 @@ final class GRPCClientTests: XCTestCase {
         request: .init(message: [3, 1, 4, 1, 5]),
         descriptor: MethodDescriptor(service: "not", method: "implemented"),
         serializer: IdentitySerializer(),
-        deserializer: IdentityDeserializer()
+        deserializer: IdentityDeserializer(),
+        options: .defaults
       ) { response in
         XCTAssertThrowsRPCError(try response.accepted.get()) { error in
           XCTAssertEqual(error.code, .unimplemented)
@@ -191,7 +198,8 @@ final class GRPCClientTests: XCTestCase {
         }),
         descriptor: MethodDescriptor(service: "not", method: "implemented"),
         serializer: IdentitySerializer(),
-        deserializer: IdentityDeserializer()
+        deserializer: IdentityDeserializer(),
+        options: .defaults
       ) { response in
         XCTAssertThrowsRPCError(try response.accepted.get()) { error in
           XCTAssertEqual(error.code, .unimplemented)
@@ -209,7 +217,8 @@ final class GRPCClientTests: XCTestCase {
               request: .init(message: [i]),
               descriptor: BinaryEcho.Methods.collect,
               serializer: IdentitySerializer(),
-              deserializer: IdentityDeserializer()
+              deserializer: IdentityDeserializer(),
+              options: .defaults
             ) { response in
               let message = try response.message
               XCTAssertEqual(message, [i])
@@ -236,7 +245,8 @@ final class GRPCClientTests: XCTestCase {
         request: .init(message: [3, 1, 4, 1, 5]),
         descriptor: BinaryEcho.Methods.collect,
         serializer: IdentitySerializer(),
-        deserializer: IdentityDeserializer()
+        deserializer: IdentityDeserializer(),
+        options: .defaults
       ) { response in
         XCTAssertRejected(response) { error in
           XCTAssertEqual(error.code, .unavailable)
@@ -255,7 +265,8 @@ final class GRPCClientTests: XCTestCase {
         request: .init(message: [3, 1, 4, 1, 5]),
         descriptor: BinaryEcho.Methods.collect,
         serializer: IdentitySerializer(),
-        deserializer: IdentityDeserializer()
+        deserializer: IdentityDeserializer(),
+        options: .defaults
       ) { response in
         let message = try response.message
         XCTAssertEqual(message, [3, 1, 4, 1, 5])
@@ -270,7 +281,8 @@ final class GRPCClientTests: XCTestCase {
           request: .init(message: [3, 1, 4, 1, 5]),
           descriptor: BinaryEcho.Methods.collect,
           serializer: IdentitySerializer(),
-          deserializer: IdentityDeserializer()
+          deserializer: IdentityDeserializer(),
+          options: .defaults
         ) { _ in }
       } errorHandler: { error in
         XCTAssertEqual(error.code, .clientIsStopped)
@@ -292,7 +304,8 @@ final class GRPCClientTests: XCTestCase {
               request: .init(message: [3, 1, 4, 1, 5]),
               descriptor: BinaryEcho.Methods.collect,
               serializer: IdentitySerializer(),
-              deserializer: IdentityDeserializer()
+              deserializer: IdentityDeserializer(),
+              options: .defaults
             ) { _ in }
           } errorHandler: { error in
             XCTAssertEqual(error.code, .clientIsStopped)
@@ -306,7 +319,8 @@ final class GRPCClientTests: XCTestCase {
         }),
         descriptor: BinaryEcho.Methods.collect,
         serializer: IdentitySerializer(),
-        deserializer: IdentityDeserializer()
+        deserializer: IdentityDeserializer(),
+        options: .defaults
       ) { response in
         let message = try response.message
         XCTAssertEqual(message, [3, 1, 4, 1, 5])
@@ -338,7 +352,8 @@ final class GRPCClientTests: XCTestCase {
           }),
           descriptor: BinaryEcho.Methods.collect,
           serializer: IdentitySerializer(),
-          deserializer: IdentityDeserializer()
+          deserializer: IdentityDeserializer(),
+          options: .defaults
         ) { response in
           XCTAssertRejected(response) { error in
             XCTAssertEqual(error.code, .unknown)
@@ -351,7 +366,8 @@ final class GRPCClientTests: XCTestCase {
         request: .init(message: [3, 1, 4, 1, 5]),
         descriptor: BinaryEcho.Methods.collect,
         serializer: IdentitySerializer(),
-        deserializer: IdentityDeserializer()
+        deserializer: IdentityDeserializer(),
+        options: .defaults
       ) { response in
         let message = try response.message
         XCTAssertEqual(message, [3, 1, 4, 1, 5])

+ 10 - 0
Tests/GRPCProtobufCodeGenTests/ProtobufCodeGeneratorTests.swift

@@ -87,6 +87,7 @@ final class ProtobufCodeGeneratorTests: XCTestCase {
                 request: ClientRequest.Single<Hello_World_Greeter.Method.SayHello.Input>,
                 serializer: some MessageSerializer<Hello_World_Greeter.Method.SayHello.Input>,
                 deserializer: some MessageDeserializer<Hello_World_Greeter.Method.SayHello.Output>,
+                options: CallOptions,
                 _ body: @Sendable @escaping (ClientResponse.Single<Hello_World_Greeter.Method.SayHello.Output>) async throws -> R
             ) async throws -> R where R: Sendable
         }
@@ -95,12 +96,14 @@ final class ProtobufCodeGeneratorTests: XCTestCase {
         extension Hello_World_Greeter.ClientProtocol {
             internal func sayHello<R>(
                 request: ClientRequest.Single<Hello_World_Greeter.Method.SayHello.Input>,
+                options: CallOptions = .defaults,
                 _ body: @Sendable @escaping (ClientResponse.Single<Hello_World_Greeter.Method.SayHello.Output>) async throws -> R
             ) async throws -> R where R: Sendable {
                 try await self.sayHello(
                     request: request,
                     serializer: ProtobufSerializer<Hello_World_Greeter.Method.SayHello.Input>(),
                     deserializer: ProtobufDeserializer<Hello_World_Greeter.Method.SayHello.Output>(),
+                    options: options,
                     body
                 )
             }
@@ -120,6 +123,7 @@ final class ProtobufCodeGeneratorTests: XCTestCase {
                 request: ClientRequest.Single<Hello_World_Greeter.Method.SayHello.Input>,
                 serializer: some MessageSerializer<Hello_World_Greeter.Method.SayHello.Input>,
                 deserializer: some MessageDeserializer<Hello_World_Greeter.Method.SayHello.Output>,
+                options: CallOptions = .defaults,
                 _ body: @Sendable @escaping (ClientResponse.Single<Hello_World_Greeter.Method.SayHello.Output>) async throws -> R
             ) async throws -> R where R: Sendable {
                 try await self.client.unary(
@@ -127,6 +131,7 @@ final class ProtobufCodeGeneratorTests: XCTestCase {
                     descriptor: Hello_World_Greeter.Method.SayHello.descriptor,
                     serializer: serializer,
                     deserializer: deserializer,
+                    options: options,
                     handler: body
                 )
             }
@@ -335,6 +340,7 @@ final class ProtobufCodeGeneratorTests: XCTestCase {
             request: ClientRequest.Single<Greeter.Method.SayHello.Input>,
             serializer: some MessageSerializer<Greeter.Method.SayHello.Input>,
             deserializer: some MessageDeserializer<Greeter.Method.SayHello.Output>,
+            options: CallOptions,
             _ body: @Sendable @escaping (ClientResponse.Single<Greeter.Method.SayHello.Output>) async throws -> R
           ) async throws -> R where R: Sendable
         }
@@ -343,12 +349,14 @@ final class ProtobufCodeGeneratorTests: XCTestCase {
         extension Greeter.ClientProtocol {
           package func sayHello<R>(
             request: ClientRequest.Single<Greeter.Method.SayHello.Input>,
+            options: CallOptions = .defaults,
             _ body: @Sendable @escaping (ClientResponse.Single<Greeter.Method.SayHello.Output>) async throws -> R
           ) async throws -> R where R: Sendable {
             try await self.sayHello(
               request: request,
               serializer: ProtobufSerializer<Greeter.Method.SayHello.Input>(),
               deserializer: ProtobufDeserializer<Greeter.Method.SayHello.Output>(),
+              options: options,
               body
             )
           }
@@ -368,6 +376,7 @@ final class ProtobufCodeGeneratorTests: XCTestCase {
             request: ClientRequest.Single<Greeter.Method.SayHello.Input>,
             serializer: some MessageSerializer<Greeter.Method.SayHello.Input>,
             deserializer: some MessageDeserializer<Greeter.Method.SayHello.Output>,
+            options: CallOptions = .defaults,
             _ body: @Sendable @escaping (ClientResponse.Single<Greeter.Method.SayHello.Output>) async throws -> R
           ) async throws -> R where R: Sendable {
             try await self.client.unary(
@@ -375,6 +384,7 @@ final class ProtobufCodeGeneratorTests: XCTestCase {
               descriptor: Greeter.Method.SayHello.descriptor,
               serializer: serializer,
               deserializer: deserializer,
+              options: options,
               handler: body
             )
           }