Upgrade swift grpc to alpha 24 (#6439)
authormustiikhalil <mustii@mmk.one>
Wed, 3 Feb 2021 23:01:18 +0000 (02:01 +0300)
committerGitHub <noreply@github.com>
Wed, 3 Feb 2021 23:01:18 +0000 (02:01 +0300)
Upgrade swift grpc to alpha 24

grpc/src/compiler/swift_generator.cc
swift/Sources/FlatBuffers/Message.swift
tests/FlatBuffers.GRPC.Swift/Package.swift
tests/FlatBuffers.GRPC.Swift/Sources/Model/greeter.grpc.swift
tests/FlatBuffers.GRPC.Swift/Sources/server/main.swift
tests/FlatBuffers.Test.Swift/Package.swift
tests/FlatBuffers.Test.Swift/Tests/FlatBuffers.Test.SwiftTests/monster_test.grpc.swift

index 95e8858..403a803 100644 (file)
 
 namespace grpc_swift_generator {
 
-std::string WrapInNameSpace(const std::vector<std::string> &components, const grpc::string &name) {
+std::string WrapInNameSpace(const std::vector<std::string> &components,
+                            const grpc::string &name) {
   std::string qualified_name;
   for (auto it = components.begin(); it != components.end(); ++it)
     qualified_name += *it + "_";
   return qualified_name + name;
 }
 
-grpc::string GenerateMessage(const std::vector<std::string> &components, const grpc::string &name) {
+grpc::string GenerateMessage(const std::vector<std::string> &components,
+                             const grpc::string &name) {
   return "Message<" + WrapInNameSpace(components, name) + ">";
 }
 
 // MARK: - Client
 
-grpc::string GenerateClientFuncName(const grpc_generator::Method *method) {
+void GenerateClientFuncName(const grpc_generator::Method *method,
+                            grpc_generator::Printer *printer,
+                            std::map<grpc::string, grpc::string> *dictonary) {
+  auto vars = *dictonary;
   if (method->NoStreaming()) {
-    return "$GenAccess$ func $MethodName$(_ request: $Input$"
-           ", callOptions: CallOptions?$isNil$) -> UnaryCall<$Input$,$Output$>";
+    printer->Print(vars,
+                   "  $GenAccess$func $MethodName$(\n"
+                   "    _ request: $Input$\n"
+                   "    , callOptions: CallOptions?$isNil$\n"
+                   "  ) -> UnaryCall<$Input$, $Output$>");
+    return;
   }
 
-  if (method->ClientStreaming()) {
-    return "$GenAccess$ func $MethodName$"
-           "(callOptions: CallOptions?$isNil$) -> "
-           "ClientStreamingCall<$Input$,$Output$>";
+  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->ServerStreaming()) {
-    return "$GenAccess$ func $MethodName$(_ request: $Input$"
-           ", callOptions: CallOptions?$isNil$, handler: @escaping ($Output$"
-           ") -> Void) -> ServerStreamingCall<$Input$, $Output$>";
+  if (method->ClientStreaming()) {
+    printer->Print(vars,
+                   "  $GenAccess$func $MethodName$(\n"
+                   "    callOptions: CallOptions?$isNil$\n"
+                   "  ) -> ClientStreamingCall<$Input$, $Output$>");
+    return;
   }
-  return "$GenAccess$ func $MethodName$"
-         "(callOptions: CallOptions?$isNil$, handler: @escaping ($Output$"
-         ") -> Void) -> BidirectionalStreamingCall<$Input$, $Output$>";
+
+  printer->Print(vars,
+                 "  $GenAccess$func $MethodName$(\n"
+                 "    callOptions: CallOptions?$isNil$,\n"
+                 "    handler: @escaping ($Output$ ) -> Void\n"
+                 "  ) -> BidirectionalStreamingCall<$Input$, $Output$>");
 }
 
-grpc::string GenerateClientFuncBody(const grpc_generator::Method *method) {
+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()) {
-    return "return self.makeUnaryCall(path: "
-           "\"/$PATH$$ServiceName$/$MethodName$\", request: request, "
-           "callOptions: callOptions ?? self.defaultCallOptions)";
+    printer->Print(
+        vars,
+        "    return self.makeUnaryCall(\n"
+        "      path: \"/$PATH$$ServiceName$/$MethodName$\",\n"
+        "      request: request,\n"
+        "      callOptions: callOptions ?? self.defaultCallOptions,\n"
+        "      $Interceptor$\n"
+        "    )\n");
+    return;
   }
 
-  if (method->ClientStreaming()) {
-    return "return self.makeClientStreamingCall(path: "
-           "\"/$PATH$$ServiceName$/$MethodName$\", callOptions: callOptions ?? "
-           "self.defaultCallOptions)";
+  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->ServerStreaming()) {
-    return "return self.makeServerStreamingCall(path: "
-           "\"/$PATH$$ServiceName$/$MethodName$\", request: request, "
-           "callOptions: callOptions ?? self.defaultCallOptions, handler: "
-           "handler)";
+  if (method->ClientStreaming()) {
+    printer->Print(
+        vars,
+        "    return self.makeClientStreamingCall(\n"
+        "      path: \"/$PATH$$ServiceName$/$MethodName$\",\n"
+        "      callOptions: callOptions ?? self.defaultCallOptions,\n"
+        "      $Interceptor$\n"
+        "    )\n");
+    return;
   }
-  return "return self.makeBidirectionalStreamingCall(path: "
-         "\"/$PATH$$ServiceName$/$MethodName$\", callOptions: callOptions ?? "
-         "self.defaultCallOptions, handler: handler)";
+  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;
-  printer->Print(vars, "$ACCESS$ protocol $ServiceQualifiedName$Service {\n");
+  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");
+
   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["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"] = "";
-    printer->Print("  ");
-    auto func = GenerateClientFuncName(method.get());
-    printer->Print(vars, func.c_str());
+    GenerateClientFuncName(method.get(), &*printer, &vars);
+    printer->Print("\n\n");
+  }
+  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");
   }
   printer->Print("}\n\n");
 }
 
-void GenerateClientClass(const grpc_generator::Service *service,
-                         grpc_generator::Printer *printer,
+void GenerateClientClass(grpc_generator::Printer *printer,
                          std::map<grpc::string, grpc::string> *dictonary) {
   auto vars = *dictonary;
   printer->Print(vars,
-                 "$ACCESS$ final class $ServiceQualifiedName$ServiceClient: GRPCClient, "
-                 "$ServiceQualifiedName$Service {\n");
+                 "$ACCESS$ final class $ServiceQualifiedName$ServiceClient: "
+                 "$ServiceQualifiedName$ClientProtocol {\n");
   printer->Print(vars, "  $ACCESS$ let channel: GRPCChannel\n");
   printer->Print(vars, "  $ACCESS$ var defaultCallOptions: CallOptions\n");
-  printer->Print("\n");
   printer->Print(vars,
-                 "  $ACCESS$ init(channel: GRPCChannel, "
-                 "defaultCallOptions: CallOptions = CallOptions()) {\n");
+                 "  $ACCESS$ var interceptors: "
+                 "$ServiceQualifiedName$ClientInterceptorFactoryProtocol?\n");
+  printer->Print("\n");
+  printer->Print(
+      vars,
+      "  $ACCESS$ init(\n"
+      "    channel: GRPCChannel,\n"
+      "    defaultCallOptions: CallOptions = CallOptions(),\n"
+      "    interceptors: "
+      "$ServiceQualifiedName$ClientInterceptorFactoryProtocol? = nil\n"
+      "  ) {\n");
   printer->Print("    self.channel = channel\n");
   printer->Print("    self.defaultCallOptions = defaultCallOptions\n");
+  printer->Print("    self.interceptors = interceptors\n");
   printer->Print("  }");
   printer->Print("\n");
-  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  ");
-    auto func = GenerateClientFuncName(method.get());
-    printer->Print(vars, func.c_str());
-    printer->Print(" {\n");
-    auto body = GenerateClientFuncBody(method.get());
-    printer->Print("    ");
-    printer->Print(vars, body.c_str());
-    printer->Print("\n  }\n");
-  }
   printer->Print("}\n");
 }
 
@@ -148,7 +238,7 @@ void GenerateClientClass(const grpc_generator::Service *service,
 
 grpc::string GenerateServerFuncName(const grpc_generator::Method *method) {
   if (method->NoStreaming()) {
-    return "func $MethodName$(request: $Input$"
+    return "func $MethodName$(request: $Input$"
            ", context: StatusOnlyCallContext) -> EventLoopFuture<$Output$>";
   }
 
@@ -169,43 +259,44 @@ grpc::string GenerateServerFuncName(const grpc_generator::Method *method) {
 
 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 CallHandlerFactory.makeUnary(callHandlerContext: callHandlerContext) { "
-           "context in"
-           "\n      "
-           "return { request in"
-           "\n        "
-           "self.$MethodName$(request, context: context)"
-           "\n      }"
-           "\n    }";
+           "return UnaryServerHandler(\n"
+           "      context: context,\n"
+           "      requestDeserializer: GRPCPayloadDeserializer<$Input$>(),\n"
+           "      responseSerializer: GRPCPayloadSerializer<$Output$>(),\n" +
+           interceptors +
+           "      userFunction: self.$MethodName$(request:context:))\n";
   }
-  if (method->ClientStreaming()) {
+  if (method->ServerStreaming()) {
     return start +
-           "return CallHandlerFactory.makeClientStreaming(callHandlerContext: "
-           "callHandlerContext) { context in"
-           "\n      "
-           "self.$MethodName$(context: context)"
-           "\n    }";
+           "return ServerStreamingServerHandler(\n"
+           "      context: context,\n"
+           "      requestDeserializer: GRPCPayloadDeserializer<$Input$>(),\n"
+           "      responseSerializer: GRPCPayloadSerializer<$Output$>(),\n" +
+           interceptors +
+           "      userFunction: self.$MethodName$(request:context:))\n";
   }
-  if (method->ServerStreaming()) {
+  if (method->ClientStreaming()) {
     return start +
-           "return CallHandlerFactory.makeServerStreaming(callHandlerContext: "
-           "callHandlerContext) { context in"
-           "\n      "
-           "return { request in"
-           "\n        "
-           "self.$MethodName$(request: request, context: context)"
-           "\n      }"
-           "\n    }";
+           "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 CallHandlerFactory.makeBidirectionalStreaming(callHandlerContext: "
-           "callHandlerContext) { context in"
-           "\n      "
-           "self.$MethodName$(context: context)"
-           "\n    }";
+           "return BidirectionalStreamingServerHandler(\n"
+           "      context: context,\n"
+           "      requestDeserializer: GRPCPayloadDeserializer<$Input$>(),\n"
+           "      responseSerializer: GRPCPayloadSerializer<$Output$>(),\n" +
+           interceptors +
+           "      observerFactory: self.$MethodName$(context:))\n";
   }
   return "";
 }
@@ -214,12 +305,19 @@ void GenerateServerProtocol(const grpc_generator::Service *service,
                             grpc_generator::Printer *printer,
                             std::map<grpc::string, grpc::string> *dictonary) {
   auto vars = *dictonary;
+  printer->Print(vars,
+                 "$ACCESS$ protocol $ServiceQualifiedName$Provider: "
+                 "CallHandlerProvider {\n");
   printer->Print(
-      vars, "$ACCESS$ protocol $ServiceQualifiedName$Provider: CallHandlerProvider {\n");
+      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["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());
@@ -235,13 +333,15 @@ void GenerateServerProtocol(const grpc_generator::Service *service,
                  "\"$PATH$$ServiceName$\" }\n");
   printer->Print("\n");
   printer->Print(
-      "  func handleMethod(_ methodName: Substring, callHandlerContext: "
-      "CallHandlerContext) -> GRPCCallHandler? {\n");
-  printer->Print("    switch methodName {\n");
+      "  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["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());
@@ -250,6 +350,26 @@ void GenerateServerProtocol(const grpc_generator::Service *service,
   printer->Print("    default: return nil;\n");
   printer->Print("    }\n");
   printer->Print("  }\n\n");
+  printer->Print("}\n\n");
+
+  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();
+    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");
+  }
   printer->Print("}");
 }
 
@@ -259,15 +379,17 @@ grpc::string Generate(grpc_generator::File *file,
   std::map<grpc::string, grpc::string> vars;
   vars["PATH"] = file->package();
   if (!file->package().empty()) { vars["PATH"].append("."); }
-  vars["ServiceQualifiedName"] = WrapInNameSpace(service->namespace_parts(), service->name());
+  vars["ServiceQualifiedName"] =
+      WrapInNameSpace(service->namespace_parts(), service->name());
   vars["ServiceName"] = service->name();
   vars["ACCESS"] = service->is_internal() ? "internal" : "public";
   auto printer = file->CreatePrinter(&output);
-  printer->Print(vars,
-                 "/// Usage: instantiate $ServiceQualifiedName$ServiceClient, then call "
-                 "methods of this protocol to make API calls.\n");
+  printer->Print(
+      vars,
+      "/// Usage: instantiate $ServiceQualifiedName$ServiceClient, then call "
+      "methods of this protocol to make API calls.\n");
   GenerateClientProtocol(service, &*printer, &vars);
-  GenerateClientClass(service, &*printer, &vars);
+  GenerateClientClass(&*printer, &vars);
   printer->Print("\n");
   GenerateServerProtocol(service, &*printer, &vars);
   return output;
index b8bba03..52ae487 100644 (file)
@@ -27,7 +27,7 @@ public protocol FlatBufferGRPCMessage {
 
 /// Message is a wrapper around Buffers to to able to send Flatbuffers `Buffers` through the
 /// GRPC library
-public final class Message<T: FlatBufferObject>: FlatBufferGRPCMessage {
+public struct Message<T: FlatBufferObject>: FlatBufferGRPCMessage {
   internal var buffer: ByteBuffer
 
   /// Returns the an object of type T that would be  read from the buffer
index ee9adc2..5692439 100644 (file)
@@ -25,7 +25,7 @@ let package = Package(
   ],
   dependencies: [
     .package(path: "../../swift"),
-    .package(url: "https://github.com/grpc/grpc-swift.git", from: "1.0.0-alpha.19"),
+    .package(url: "https://github.com/grpc/grpc-swift.git", .exact("1.0.0-alpha.24")),
   ],
   targets: [
     // Targets are the basic building blocks of a package. A target can define a module or a test suite.
index e4605e0..aacffe5 100644 (file)
@@ -24,31 +24,84 @@ public extension GRPCFlatBufPayload {
 extension Message: GRPCFlatBufPayload {}
 
 /// Usage: instantiate GreeterServiceClient, then call methods of this protocol to make API calls.
-public protocol GreeterService {
-   func SayHello(_ request: Message<HelloRequest>, callOptions: CallOptions?) -> UnaryCall<Message<HelloRequest>,Message<HelloReply>>
-   func SayManyHellos(_ request: Message<ManyHellosRequest>, callOptions: CallOptions?, handler: @escaping (Message<HelloReply>) -> Void) -> ServerStreamingCall<Message<ManyHellosRequest>, Message<HelloReply>>
+public protocol GreeterClientProtocol: GRPCClient {
+
+  var serviceName: String { get }
+
+  var interceptors: GreeterClientInterceptorFactoryProtocol? { get }
+
+  func SayHello(
+    _ request: Message<HelloRequest>
+    , callOptions: CallOptions?
+  ) -> UnaryCall<Message<HelloRequest>, Message<HelloReply>>
+
+  func SayManyHellos(
+    _ request: Message<ManyHellosRequest>
+    , callOptions: CallOptions?,
+    handler: @escaping (Message<HelloReply>) -> Void
+  ) -> ServerStreamingCall<Message<ManyHellosRequest>, Message<HelloReply>>
+
 }
 
-public final class GreeterServiceClient: GRPCClient, GreeterService {
-  public let channel: GRPCChannel
-  public var defaultCallOptions: CallOptions
+extension GreeterClientProtocol {
 
-  public init(channel: GRPCChannel, defaultCallOptions: CallOptions = CallOptions()) {
-    self.channel = channel
-    self.defaultCallOptions = defaultCallOptions
+  public var serviceName: String { "Greeter" }
+
+  public func SayHello(
+    _ request: Message<HelloRequest>
+    , callOptions: CallOptions? = nil
+  ) -> UnaryCall<Message<HelloRequest>, Message<HelloReply>> {
+    return self.makeUnaryCall(
+      path: "/Greeter/SayHello",
+      request: request,
+      callOptions: callOptions ?? self.defaultCallOptions,
+      interceptors: self.interceptors?.makeSayHelloInterceptors() ?? []
+    )
   }
 
-  public func SayHello(_ request: Message<HelloRequest>, callOptions: CallOptions? = nil) -> UnaryCall<Message<HelloRequest>,Message<HelloReply>> {
-    return self.makeUnaryCall(path: "/Greeter/SayHello", request: request, callOptions: callOptions ?? self.defaultCallOptions)
+  public func SayManyHellos(
+    _ request: Message<ManyHellosRequest>
+    , callOptions: CallOptions? = nil,
+    handler: @escaping (Message<HelloReply>) -> Void
+  ) -> ServerStreamingCall<Message<ManyHellosRequest>, Message<HelloReply>> {
+    return self.makeServerStreamingCall(
+      path: "/Greeter/SayManyHellos",
+      request: request,
+      callOptions: callOptions ?? self.defaultCallOptions,
+      interceptors: self.interceptors?.makeSayManyHellosInterceptors() ?? [],
+      handler: handler
+    )
   }
+}
+
+public protocol GreeterClientInterceptorFactoryProtocol {
+  /// - Returns: Interceptors to use when invoking 'SayHello'.
+  func makeSayHelloInterceptors() -> [ClientInterceptor<Message<HelloRequest>, Message<HelloReply>>]
+
+  /// - Returns: Interceptors to use when invoking 'SayManyHellos'.
+  func makeSayManyHellosInterceptors() -> [ClientInterceptor<Message<ManyHellosRequest>, Message<HelloReply>>]
+
+}
+
+public final class GreeterServiceClient: GreeterClientProtocol {
+  public let channel: GRPCChannel
+  public var defaultCallOptions: CallOptions
+  public var interceptors: GreeterClientInterceptorFactoryProtocol?
 
-  public func SayManyHellos(_ request: Message<ManyHellosRequest>, callOptions: CallOptions? = nil, handler: @escaping (Message<HelloReply>) -> Void) -> ServerStreamingCall<Message<ManyHellosRequest>, Message<HelloReply>> {
-    return self.makeServerStreamingCall(path: "/Greeter/SayManyHellos", request: request, callOptions: callOptions ?? self.defaultCallOptions, handler: handler)
+  public init(
+    channel: GRPCChannel,
+    defaultCallOptions: CallOptions = CallOptions(),
+    interceptors: GreeterClientInterceptorFactoryProtocol? = nil
+  ) {
+    self.channel = channel
+    self.defaultCallOptions = defaultCallOptions
+    self.interceptors = interceptors
   }
 }
 
 public protocol GreeterProvider: CallHandlerProvider {
-  func SayHello(_ request: Message<HelloRequest>, context: StatusOnlyCallContext) -> EventLoopFuture<Message<HelloReply>>
+  var interceptors: GreeterServerInterceptorFactoryProtocol? { get }
+  func SayHello(request: Message<HelloRequest>, context: StatusOnlyCallContext) -> EventLoopFuture<Message<HelloReply>>
   func SayManyHellos(request: Message<ManyHellosRequest>, context: StreamingResponseCallContext<Message<HelloReply>>) -> EventLoopFuture<GRPCStatus>
 }
 
@@ -56,22 +109,37 @@ public extension GreeterProvider {
 
   var serviceName: Substring { return "Greeter" }
 
-  func handleMethod(_ methodName: Substring, callHandlerContext: CallHandlerContext) -> GRPCCallHandler? {
-    switch methodName {
+  func handle(method name: Substring, context: CallHandlerContext) -> GRPCServerHandlerProtocol? {
+    switch name {
     case "SayHello":
-    return CallHandlerFactory.makeUnary(callHandlerContext: callHandlerContext) { context in
-      return { request in
-        self.SayHello(request, context: context)
-      }
-    }
+    return UnaryServerHandler(
+      context: context,
+      requestDeserializer: GRPCPayloadDeserializer<Message<HelloRequest>>(),
+      responseSerializer: GRPCPayloadSerializer<Message<HelloReply>>(),
+      interceptors: self.interceptors?.makeSayHelloInterceptors() ?? [],
+      userFunction: self.SayHello(request:context:))
+
     case "SayManyHellos":
-    return CallHandlerFactory.makeServerStreaming(callHandlerContext: callHandlerContext) { context in
-      return { request in
-        self.SayManyHellos(request: request, context: context)
-      }
-    }
+    return ServerStreamingServerHandler(
+      context: context,
+      requestDeserializer: GRPCPayloadDeserializer<Message<ManyHellosRequest>>(),
+      responseSerializer: GRPCPayloadSerializer<Message<HelloReply>>(),
+      interceptors: self.interceptors?.makeSayManyHellosInterceptors() ?? [],
+      userFunction: self.SayManyHellos(request:context:))
+
     default: return nil;
     }
   }
 
 }
+
+public protocol GreeterServerInterceptorFactoryProtocol {
+  /// - Returns: Interceptors to use when handling 'SayHello'.
+  ///   Defaults to calling `self.makeInterceptors()`.
+  func makeSayHelloInterceptors() -> [ServerInterceptor<Message<HelloRequest>, Message<HelloReply>>]
+
+  /// - Returns: Interceptors to use when handling 'SayManyHellos'.
+  ///   Defaults to calling `self.makeInterceptors()`.
+  func makeSayManyHellosInterceptors() -> [ServerInterceptor<Message<ManyHellosRequest>, Message<HelloReply>>]
+
+}
index 53c0223..d5274c1 100644 (file)
@@ -22,6 +22,8 @@ import NIO
 
 class Greeter: GreeterProvider {
 
+  var interceptors: GreeterServerInterceptorFactoryProtocol?
+
   var hellos: [Message<HelloReply>] = []
 
   init() {
@@ -36,7 +38,7 @@ class Greeter: GreeterProvider {
   }
 
   func SayHello(
-    request: Message<HelloRequest>,
+    request: Message<HelloRequest>,
     context: StatusOnlyCallContext) -> EventLoopFuture<Message<HelloReply>>
   {
     let recipient = request.object.name ?? "Stranger"
index 06d03bd..ee8e9d6 100644 (file)
@@ -25,7 +25,7 @@ let package = Package(
   ],
   dependencies: [
     .package(path: "../../swift/"),
-    .package(url: "https://github.com/grpc/grpc-swift.git", from: "1.0.0-alpha.19"),
+    .package(url: "https://github.com/grpc/grpc-swift.git", .exact("1.0.0-alpha.24")),
   ],
   targets: [
     .target(name: "SwiftFlatBuffers"),
index 414a816..b5fd535 100644 (file)
@@ -24,41 +24,121 @@ public extension GRPCFlatBufPayload {
 extension Message: GRPCFlatBufPayload {}
 
 /// Usage: instantiate MyGame_Example_MonsterStorageServiceClient, then call methods of this protocol to make API calls.
-public protocol MyGame_Example_MonsterStorageService {
-   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>>
+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>>
+
 }
 
-public final class MyGame_Example_MonsterStorageServiceClient: GRPCClient, MyGame_Example_MonsterStorageService {
-  public let channel: GRPCChannel
-  public var defaultCallOptions: CallOptions
+extension MyGame_Example_MonsterStorageClientProtocol {
 
-  public init(channel: GRPCChannel, defaultCallOptions: CallOptions = CallOptions()) {
-    self.channel = channel
-    self.defaultCallOptions = defaultCallOptions
+  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 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)
+  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 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, 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 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)
+  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 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, handler: handler)
+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 {
-  func Store(_ request: Message<MyGame_Example_Monster>, context: StatusOnlyCallContext) -> EventLoopFuture<Message<MyGame_Example_Stat>>
+  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>
@@ -68,30 +148,61 @@ public extension MyGame_Example_MonsterStorageProvider {
 
   var serviceName: Substring { return "MyGame.Example.MonsterStorage" }
 
-  func handleMethod(_ methodName: Substring, callHandlerContext: CallHandlerContext) -> GRPCCallHandler? {
-    switch methodName {
+  func handle(method name: Substring, context: CallHandlerContext) -> GRPCServerHandlerProtocol? {
+    switch name {
     case "Store":
-    return CallHandlerFactory.makeUnary(callHandlerContext: callHandlerContext) { context in
-      return { request in
-        self.Store(request, context: context)
-      }
-    }
+    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 CallHandlerFactory.makeServerStreaming(callHandlerContext: callHandlerContext) { context in
-      return { request in
-        self.Retrieve(request: request, context: context)
-      }
-    }
+    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 CallHandlerFactory.makeClientStreaming(callHandlerContext: callHandlerContext) { context in
-      self.GetMaxHitPoint(context: context)
-    }
+    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 CallHandlerFactory.makeBidirectionalStreaming(callHandlerContext: callHandlerContext) { context in
-      self.GetMinMaxHitPoints(context: context)
-    }
+    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;
     }
   }
 
 }
+
+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>>]
+
+}