-
Notifications
You must be signed in to change notification settings - Fork 0
Support @bufbuild/protobuf
#1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| This is the static code generation variant of the Hello World. Code in these examples is pre-generated using protoc and the Node gRPC protoc plugin, and the generated code can be found in various `*_pb.js` files. The command line sequence for generating those files is as follows (assuming that `protoc` and `grpc_node_plugin` are present, and starting in the directory which contains this README.md file): | ||
|
|
||
| ```sh | ||
| cd ../protos | ||
| npm install -g grpc-tools @bufbuild/protoc-gen-es | ||
| grpc_tools_node_protoc --es_out=target=js,js_import_style=legacy_commonjs:../helloworld/static_codegen_es/ --grpc_out=grpc_js,runtime=es:../helloworld/static_codegen_es/ helloworld.proto | ||
| ``` | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| /* | ||
| * | ||
| * Copyright 2015 gRPC authors. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| * | ||
| */ | ||
|
|
||
| var parseArgs = require('minimist'); | ||
| var messages = require('./helloworld_pb'); | ||
| var services = require('./helloworld_grpc_pb'); | ||
|
|
||
| var grpc = require('@grpc/grpc-js'); | ||
|
|
||
| function main() { | ||
| var argv = parseArgs(process.argv.slice(2), { | ||
| string: 'target' | ||
| }); | ||
| var target; | ||
| if (argv.target) { | ||
| target = argv.target; | ||
| } else { | ||
| target = 'localhost:50051'; | ||
| } | ||
| var client = new services.GreeterClient(target, | ||
| grpc.credentials.createInsecure()); | ||
| var request = new messages.HelloRequest(); | ||
| var user; | ||
| if (argv._.length > 0) { | ||
| user = argv._[0]; | ||
| } else { | ||
| user = 'world'; | ||
| } | ||
| request.setName(user); | ||
| client.sayHello(request, function(err, response) { | ||
| console.log('Greeting:', response.getMessage()); | ||
| }); | ||
| } | ||
|
|
||
| main(); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| /* | ||
| * | ||
| * Copyright 2015 gRPC authors. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| * | ||
| */ | ||
|
|
||
| var messages = require('./helloworld_pb'); | ||
| var services = require('./helloworld_grpc_pb'); | ||
|
|
||
| var grpc = require('@grpc/grpc-js'); | ||
|
|
||
| /** | ||
| * Implements the SayHello RPC method. | ||
| */ | ||
| function sayHello(call, callback) { | ||
| var reply = new messages.HelloReply(); | ||
| reply.setMessage('Hello ' + call.request.getName()); | ||
| callback(null, reply); | ||
| } | ||
|
|
||
| /** | ||
| * Starts an RPC server that receives requests for the Greeter service at the | ||
| * sample server port | ||
| */ | ||
| function main() { | ||
| var server = new grpc.Server(); | ||
| server.addService(services.GreeterService, {sayHello: sayHello}); | ||
| server.bindAsync('0.0.0.0:50051', grpc.ServerCredentials.createInsecure(), (err, port) => { | ||
| if (err != null) { | ||
| return console.error(err); | ||
| } | ||
| console.log(`gRPC listening on ${port}`) | ||
| }); | ||
| } | ||
|
|
||
| main(); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| // GENERATED CODE -- DO NOT EDIT! | ||
|
|
||
| // Original file comments: | ||
| // Copyright 2015 gRPC authors. | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
| // | ||
| 'use strict'; | ||
| var grpc = require('@grpc/grpc-js'); | ||
| var proto = require('@bufbuild/protobuf'); | ||
| var helloworld_pb = require('./helloworld_pb.js'); | ||
|
|
||
| function serialize_helloworld_HelloReply(arg) { | ||
srikrsna-buf marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| if (!proto.isMessage(arg, helloworld_pb.HelloReplySchema)) { | ||
| throw new Error('Expected argument of type helloworld.HelloReply'); | ||
| } | ||
| return Buffer.from(proto.toBinary(helloworld_pb.HelloReplySchema, arg)); | ||
| } | ||
|
|
||
| function deserialize_helloworld_HelloReply(buffer_arg) { | ||
| return proto.fromBinary(helloworld_pb.HelloReplySchema, new Uint8Array(buffer_arg)); | ||
| } | ||
|
|
||
| function serialize_helloworld_HelloRequest(arg) { | ||
| if (!proto.isMessage(arg, helloworld_pb.HelloRequestSchema)) { | ||
| throw new Error('Expected argument of type helloworld.HelloRequest'); | ||
| } | ||
| return Buffer.from(proto.toBinary(helloworld_pb.HelloRequestSchema, arg)); | ||
| } | ||
|
|
||
| function deserialize_helloworld_HelloRequest(buffer_arg) { | ||
| return proto.fromBinary(helloworld_pb.HelloRequestSchema, new Uint8Array(buffer_arg)); | ||
| } | ||
|
|
||
|
|
||
| // The greeting service definition. | ||
| var GreeterService = exports.GreeterService = { | ||
| // Sends a greeting | ||
| sayHello: { | ||
| path: '/helloworld.Greeter/SayHello', | ||
| requestStream: false, | ||
| responseStream: false, | ||
| requestType: helloworld_pb.HelloRequestSchema, | ||
| responseType: helloworld_pb.HelloReplySchema, | ||
| requestSerialize: serialize_helloworld_HelloRequest, | ||
| requestDeserialize: deserialize_helloworld_HelloRequest, | ||
| responseSerialize: serialize_helloworld_HelloReply, | ||
| responseDeserialize: deserialize_helloworld_HelloReply, | ||
| }, | ||
| sayHelloStreamReply: { | ||
| path: '/helloworld.Greeter/SayHelloStreamReply', | ||
| requestStream: false, | ||
| responseStream: true, | ||
| requestType: helloworld_pb.HelloRequestSchema, | ||
| responseType: helloworld_pb.HelloReplySchema, | ||
| requestSerialize: serialize_helloworld_HelloRequest, | ||
| requestDeserialize: deserialize_helloworld_HelloRequest, | ||
| responseSerialize: serialize_helloworld_HelloReply, | ||
| responseDeserialize: deserialize_helloworld_HelloReply, | ||
| }, | ||
| }; | ||
|
|
||
| exports.GreeterClient = grpc.makeGenericClientConstructor(GreeterService, 'Greeter'); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,56 @@ | ||
| // Copyright 2015 gRPC authors. | ||
| // | ||
| // Licensed under the Apache License, Version 2.0 (the "License"); | ||
| // you may not use this file except in compliance with the License. | ||
| // You may obtain a copy of the License at | ||
| // | ||
| // http://www.apache.org/licenses/LICENSE-2.0 | ||
| // | ||
| // Unless required by applicable law or agreed to in writing, software | ||
| // distributed under the License is distributed on an "AS IS" BASIS, | ||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| // See the License for the specific language governing permissions and | ||
| // limitations under the License. | ||
|
|
||
| // @generated by protoc-gen-es v2.7.0 with parameter "target=js,js_import_style=legacy_commonjs" | ||
| // @generated from file helloworld.proto (package helloworld, syntax proto3) | ||
| /* eslint-disable */ | ||
|
|
||
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
|
|
||
| const { fileDesc, messageDesc, serviceDesc } = require("@bufbuild/protobuf/codegenv2"); | ||
|
|
||
| /** | ||
| * Describes the file helloworld.proto. | ||
| */ | ||
| const file_helloworld = /*@__PURE__*/ | ||
| fileDesc("ChBoZWxsb3dvcmxkLnByb3RvEgpoZWxsb3dvcmxkIhwKDEhlbGxvUmVxdWVzdBIMCgRuYW1lGAEgASgJIh0KCkhlbGxvUmVwbHkSDwoHbWVzc2FnZRgBIAEoCTKWAQoHR3JlZXRlchI+CghTYXlIZWxsbxIYLmhlbGxvd29ybGQuSGVsbG9SZXF1ZXN0GhYuaGVsbG93b3JsZC5IZWxsb1JlcGx5IgASSwoTU2F5SGVsbG9TdHJlYW1SZXBseRIYLmhlbGxvd29ybGQuSGVsbG9SZXF1ZXN0GhYuaGVsbG93b3JsZC5IZWxsb1JlcGx5IgAwAUI2Chtpby5ncnBjLmV4YW1wbGVzLmhlbGxvd29ybGRCD0hlbGxvV29ybGRQcm90b1ABogIDSExXYgZwcm90bzM"); | ||
|
|
||
| /** | ||
| * Describes the message helloworld.HelloRequest. | ||
| * Use `create(HelloRequestSchema)` to create a new message. | ||
| */ | ||
| const HelloRequestSchema = /*@__PURE__*/ | ||
| messageDesc(file_helloworld, 0); | ||
|
|
||
| /** | ||
| * Describes the message helloworld.HelloReply. | ||
| * Use `create(HelloReplySchema)` to create a new message. | ||
| */ | ||
| const HelloReplySchema = /*@__PURE__*/ | ||
| messageDesc(file_helloworld, 1); | ||
|
|
||
| /** | ||
| * The greeting service definition. | ||
| * | ||
| * @generated from service helloworld.Greeter | ||
| */ | ||
| const Greeter = /*@__PURE__*/ | ||
| serviceDesc(file_helloworld, 0); | ||
|
|
||
|
|
||
| exports.file_helloworld = file_helloworld; | ||
| exports.HelloRequestSchema = HelloRequestSchema; | ||
| exports.HelloReplySchema = HelloReplySchema; | ||
| exports.Greeter = Greeter; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -112,21 +112,27 @@ grpc::string MessageIdentifierName(const grpc::string& name) { | |
| return grpc_generator::StringReplace(name, ".", "_"); | ||
| } | ||
|
|
||
| grpc::string NodeObjectPath(const Descriptor* descriptor) { | ||
| grpc::string NodeObjectPath(const Descriptor* descriptor, const grpc::string& runtime) { | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Don't know how to test it, but the diff looks good to me. |
||
| grpc::string module_alias = ModuleAlias(descriptor->file()->name()); | ||
| if (runtime == "es" && descriptor->file()->name().find("google/protobuf") == 0) { | ||
| module_alias = "wkt"; | ||
| } | ||
| grpc::string name = descriptor->full_name(); | ||
| grpc_generator::StripPrefix(&name, descriptor->file()->package() + "."); | ||
| if (runtime == "es") { | ||
| name += "Schema"; | ||
| } | ||
| return module_alias + "." + name; | ||
| } | ||
|
|
||
| // Prints out the message serializer and deserializer functions | ||
| void PrintMessageTransformer(const Descriptor* descriptor, Printer* out, | ||
| // Prints out the message serializer and deserializer functions for google-protobuf. | ||
| void PrintGoogleProtobufMessageTransformer(const Descriptor* descriptor, Printer* out, | ||
| const Parameters& params) { | ||
| map<grpc::string, grpc::string> template_vars; | ||
| grpc::string full_name = descriptor->full_name(); | ||
| template_vars["identifier_name"] = MessageIdentifierName(full_name); | ||
| template_vars["name"] = full_name; | ||
| template_vars["node_name"] = NodeObjectPath(descriptor); | ||
| template_vars["node_name"] = NodeObjectPath(descriptor, params.runtime); | ||
| // Print the serializer | ||
| out->Print(template_vars, "function serialize_$identifier_name$(arg) {\n"); | ||
| out->Indent(); | ||
|
|
@@ -153,15 +159,59 @@ void PrintMessageTransformer(const Descriptor* descriptor, Printer* out, | |
| out->Print("}\n\n"); | ||
| } | ||
|
|
||
| void PrintMethod(const MethodDescriptor* method, Printer* out) { | ||
| // Prints out the message serializer and deserializer functions for bufbuild-protobuf. | ||
| void PrintBufbuildProtobufMessageTransformer(const Descriptor* descriptor, Printer* out, | ||
| const Parameters& params) { | ||
| map<grpc::string, grpc::string> template_vars; | ||
| grpc::string full_name = descriptor->full_name(); | ||
| template_vars["identifier_name"] = MessageIdentifierName(full_name); | ||
| template_vars["name"] = full_name; | ||
| template_vars["node_name"] = NodeObjectPath(descriptor, params.runtime); | ||
| // Print the serializer | ||
| out->Print(template_vars, "function serialize_$identifier_name$(arg) {\n"); | ||
| out->Indent(); | ||
| if (!params.omit_serialize_instanceof) { | ||
| out->Print(template_vars, "if (!proto.isMessage(arg, $node_name$)) {\n"); | ||
| out->Indent(); | ||
| out->Print(template_vars, | ||
| "throw new Error('Expected argument of type $name$');\n"); | ||
| out->Outdent(); | ||
| out->Print("}\n"); | ||
| } | ||
| out->Print(template_vars, "return Buffer.from(proto.toBinary($node_name$, arg));\n"); | ||
| out->Outdent(); | ||
| out->Print("}\n\n"); | ||
|
|
||
| // Print the deserializer | ||
| out->Print(template_vars, | ||
| "function deserialize_$identifier_name$(buffer_arg) {\n"); | ||
| out->Indent(); | ||
| out->Print( | ||
| template_vars, | ||
| "return proto.fromBinary($node_name$, new Uint8Array(buffer_arg));\n"); | ||
| out->Outdent(); | ||
| out->Print("}\n\n"); | ||
| } | ||
|
|
||
| // Prints out the message serializer and deserializer functions | ||
| void PrintMessageTransformer(const Descriptor* descriptor, Printer* out, | ||
| const Parameters& params) { | ||
| if (params.runtime == "es") { | ||
| PrintBufbuildProtobufMessageTransformer(descriptor, out, params); | ||
| } else { | ||
| PrintGoogleProtobufMessageTransformer(descriptor, out, params); | ||
| } | ||
| } | ||
|
|
||
| void PrintMethod(const MethodDescriptor* method, Printer* out, const Parameters& params) { | ||
| const Descriptor* input_type = method->input_type(); | ||
| const Descriptor* output_type = method->output_type(); | ||
| map<grpc::string, grpc::string> vars; | ||
| vars["service_name"] = method->service()->full_name(); | ||
| vars["name"] = method->name(); | ||
| vars["input_type"] = NodeObjectPath(input_type); | ||
| vars["input_type"] = NodeObjectPath(input_type, params.runtime); | ||
| vars["input_type_id"] = MessageIdentifierName(input_type->full_name()); | ||
| vars["output_type"] = NodeObjectPath(output_type); | ||
| vars["output_type"] = NodeObjectPath(output_type, params.runtime); | ||
| vars["output_type_id"] = MessageIdentifierName(output_type->full_name()); | ||
| vars["client_stream"] = method->client_streaming() ? "true" : "false"; | ||
| vars["server_stream"] = method->server_streaming() ? "true" : "false"; | ||
|
|
@@ -198,7 +248,7 @@ void PrintService(const ServiceDescriptor* service, Printer* out, | |
| grpc_generator::LowercaseFirstLetter(service->method(i)->name()); | ||
| out->PrintRaw(GetNodeComments(service->method(i), true).c_str()); | ||
| out->Print("$method_name$: ", "method_name", method_name); | ||
| PrintMethod(service->method(i), out); | ||
| PrintMethod(service->method(i), out, params); | ||
| out->Print(",\n"); | ||
| out->PrintRaw(GetNodeComments(service->method(i), false).c_str()); | ||
| } | ||
|
|
@@ -218,14 +268,25 @@ void PrintImports(const FileDescriptor* file, Printer* out, | |
| grpc::string package = params.grpc_js ? "@grpc/grpc-js" : "grpc"; | ||
| out->Print("var grpc = require('$package$');\n", "package", package); | ||
| } | ||
| if (params.runtime == "es") { | ||
| out->Print("var proto = require('@bufbuild/protobuf');\n"); | ||
| } | ||
| if (file->message_type_count() > 0) { | ||
| grpc::string file_path = | ||
| GetRelativePath(file->name(), GetJSMessageFilename(file->name())); | ||
| out->Print("var $module_alias$ = require('$file_path$');\n", "module_alias", | ||
| ModuleAlias(file->name()), "file_path", file_path); | ||
| } | ||
|
|
||
| bool imports_wkt = false; | ||
| for (int i = 0; i < file->dependency_count(); i++) { | ||
| if (params.runtime == "es" && file->dependency(i)->name().find("google/protobuf") == 0) { | ||
| // WKTs are provided by the runtime from a single location. | ||
| if (!imports_wkt) { | ||
| out->Print("var wkt = require('@bufbuild/protobuf/wkt');"); | ||
| imports_wkt = true; | ||
| } | ||
| continue; | ||
| } | ||
| grpc::string file_path = GetRelativePath( | ||
| file->name(), GetJSMessageFilename(file->dependency(i)->name())); | ||
| out->Print("var $module_alias$ = require('$file_path$');\n", "module_alias", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -30,6 +30,8 @@ struct Parameters { | |
| bool grpc_js; | ||
| // Omit instanceof check for messages in serialize methods | ||
| bool omit_serialize_instanceof; | ||
| // Runtime to use for protobuf serialization (default: "google-protobuf", "es" for @bufbuild/protobuf) | ||
|
||
| grpc::string runtime; | ||
| }; | ||
|
|
||
| grpc::string GenerateFile(const grpc::protobuf::FileDescriptor* file, | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.