mirror of
https://github.com/google/flatbuffers.git
synced 2026-06-18 09:04:26 +00:00
@@ -29,118 +29,208 @@
|
||||
|
||||
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$>";
|
||||
}
|
||||
|
||||
if (method->ClientStreaming()) {
|
||||
return "$GenAccess$ func $MethodName$"
|
||||
"(callOptions: CallOptions?$isNil$) -> "
|
||||
"ClientStreamingCall<$Input$,$Output$>";
|
||||
printer->Print(vars,
|
||||
" $GenAccess$func $MethodName$(\n"
|
||||
" _ request: $Input$\n"
|
||||
" , callOptions: CallOptions?$isNil$\n"
|
||||
" ) -> UnaryCall<$Input$, $Output$>");
|
||||
return;
|
||||
}
|
||||
|
||||
if (method->ServerStreaming()) {
|
||||
return "$GenAccess$ func $MethodName$(_ request: $Input$"
|
||||
", callOptions: CallOptions?$isNil$, handler: @escaping ($Output$"
|
||||
") -> Void) -> ServerStreamingCall<$Input$, $Output$>";
|
||||
printer->Print(vars,
|
||||
" $GenAccess$func $MethodName$(\n"
|
||||
" _ request: $Input$\n"
|
||||
" , callOptions: CallOptions?$isNil$,\n"
|
||||
" handler: @escaping ($Output$) -> Void\n"
|
||||
" ) -> ServerStreamingCall<$Input$, $Output$>");
|
||||
return;
|
||||
}
|
||||
return "$GenAccess$ func $MethodName$"
|
||||
"(callOptions: CallOptions?$isNil$, handler: @escaping ($Output$"
|
||||
") -> Void) -> BidirectionalStreamingCall<$Input$, $Output$>";
|
||||
|
||||
if (method->ClientStreaming()) {
|
||||
printer->Print(vars,
|
||||
" $GenAccess$func $MethodName$(\n"
|
||||
" callOptions: CallOptions?$isNil$\n"
|
||||
" ) -> ClientStreamingCall<$Input$, $Output$>");
|
||||
return;
|
||||
}
|
||||
|
||||
printer->Print(vars,
|
||||
" $GenAccess$func $MethodName$(\n"
|
||||
" callOptions: CallOptions?$isNil$,\n"
|
||||
" handler: @escaping ($Output$ ) -> Void\n"
|
||||
" ) -> BidirectionalStreamingCall<$Input$, $Output$>");
|
||||
}
|
||||
|
||||
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)";
|
||||
}
|
||||
|
||||
if (method->ClientStreaming()) {
|
||||
return "return self.makeClientStreamingCall(path: "
|
||||
"\"/$PATH$$ServiceName$/$MethodName$\", 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->ServerStreaming()) {
|
||||
return "return self.makeServerStreamingCall(path: "
|
||||
"\"/$PATH$$ServiceName$/$MethodName$\", request: request, "
|
||||
"callOptions: callOptions ?? self.defaultCallOptions, handler: "
|
||||
"handler)";
|
||||
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;
|
||||
}
|
||||
return "return self.makeBidirectionalStreamingCall(path: "
|
||||
"\"/$PATH$$ServiceName$/$MethodName$\", 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;
|
||||
}
|
||||
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 }";
|
||||
}
|
||||
if (method->ClientStreaming()) {
|
||||
return start +
|
||||
"return CallHandlerFactory.makeClientStreaming(callHandlerContext: "
|
||||
"callHandlerContext) { context in"
|
||||
"\n "
|
||||
"self.$MethodName$(context: context)"
|
||||
"\n }";
|
||||
"return UnaryServerHandler(\n"
|
||||
" context: context,\n"
|
||||
" requestDeserializer: GRPCPayloadDeserializer<$Input$>(),\n"
|
||||
" responseSerializer: GRPCPayloadSerializer<$Output$>(),\n" +
|
||||
interceptors +
|
||||
" userFunction: self.$MethodName$(request:context:))\n";
|
||||
}
|
||||
if (method->ServerStreaming()) {
|
||||
return start +
|
||||
"return CallHandlerFactory.makeServerStreaming(callHandlerContext: "
|
||||
"callHandlerContext) { context in"
|
||||
"\n "
|
||||
"return { request in"
|
||||
"\n "
|
||||
"self.$MethodName$(request: request, context: context)"
|
||||
"\n }"
|
||||
"\n }";
|
||||
"return ServerStreamingServerHandler(\n"
|
||||
" context: context,\n"
|
||||
" requestDeserializer: GRPCPayloadDeserializer<$Input$>(),\n"
|
||||
" responseSerializer: GRPCPayloadSerializer<$Output$>(),\n" +
|
||||
interceptors +
|
||||
" userFunction: self.$MethodName$(request:context:))\n";
|
||||
}
|
||||
if (method->ClientStreaming()) {
|
||||
return start +
|
||||
"return ClientStreamingServerHandler(\n"
|
||||
" context: context,\n"
|
||||
" requestDeserializer: GRPCPayloadDeserializer<$Input$>(),\n"
|
||||
" responseSerializer: GRPCPayloadSerializer<$Output$>(),\n" +
|
||||
interceptors +
|
||||
" observerFactory: self.$MethodName$(context:))\n";
|
||||
}
|
||||
if (method->BidiStreaming()) {
|
||||
return start +
|
||||
"return 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;
|
||||
|
||||
Reference in New Issue
Block a user