From 403a11151a81fd4c93dc539ec8268f92aee0ebfc Mon Sep 17 00:00:00 2001 From: Sri Krishna Date: Thu, 4 Sep 2025 08:04:25 +0530 Subject: [PATCH 1/4] Support bufbuild-protobuf Signed-off-by: Sri Krishna --- .../helloworld/static_codegen_es/README.md | 7 ++ .../static_codegen_es/greeter_client.js | 50 ++++++++++++ .../static_codegen_es/greeter_server.js | 48 +++++++++++ .../static_codegen_es/helloworld_grpc_pb.js | 73 +++++++++++++++++ .../static_codegen_es/helloworld_pb.js | 56 +++++++++++++ packages/grpc-tools/src/node_generator.cc | 79 ++++++++++++++++--- packages/grpc-tools/src/node_generator.h | 2 + packages/grpc-tools/src/node_plugin.cc | 3 + 8 files changed, 309 insertions(+), 9 deletions(-) create mode 100644 examples/helloworld/static_codegen_es/README.md create mode 100644 examples/helloworld/static_codegen_es/greeter_client.js create mode 100644 examples/helloworld/static_codegen_es/greeter_server.js create mode 100644 examples/helloworld/static_codegen_es/helloworld_grpc_pb.js create mode 100644 examples/helloworld/static_codegen_es/helloworld_pb.js diff --git a/examples/helloworld/static_codegen_es/README.md b/examples/helloworld/static_codegen_es/README.md new file mode 100644 index 000000000..59b88efe7 --- /dev/null +++ b/examples/helloworld/static_codegen_es/README.md @@ -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 +``` diff --git a/examples/helloworld/static_codegen_es/greeter_client.js b/examples/helloworld/static_codegen_es/greeter_client.js new file mode 100644 index 000000000..668a3f8e4 --- /dev/null +++ b/examples/helloworld/static_codegen_es/greeter_client.js @@ -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(); diff --git a/examples/helloworld/static_codegen_es/greeter_server.js b/examples/helloworld/static_codegen_es/greeter_server.js new file mode 100644 index 000000000..ae2ab949d --- /dev/null +++ b/examples/helloworld/static_codegen_es/greeter_server.js @@ -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(); diff --git a/examples/helloworld/static_codegen_es/helloworld_grpc_pb.js b/examples/helloworld/static_codegen_es/helloworld_grpc_pb.js new file mode 100644 index 000000000..c95a9a0af --- /dev/null +++ b/examples/helloworld/static_codegen_es/helloworld_grpc_pb.js @@ -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) { + 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'); diff --git a/examples/helloworld/static_codegen_es/helloworld_pb.js b/examples/helloworld/static_codegen_es/helloworld_pb.js new file mode 100644 index 000000000..ac6db1324 --- /dev/null +++ b/examples/helloworld/static_codegen_es/helloworld_pb.js @@ -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; diff --git a/packages/grpc-tools/src/node_generator.cc b/packages/grpc-tools/src/node_generator.cc index 2bea5b504..ca29d3676 100644 --- a/packages/grpc-tools/src/node_generator.cc +++ b/packages/grpc-tools/src/node_generator.cc @@ -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) { 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 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 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 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", diff --git a/packages/grpc-tools/src/node_generator.h b/packages/grpc-tools/src/node_generator.h index 389fe0274..23719d467 100644 --- a/packages/grpc-tools/src/node_generator.h +++ b/packages/grpc-tools/src/node_generator.h @@ -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, diff --git a/packages/grpc-tools/src/node_plugin.cc b/packages/grpc-tools/src/node_plugin.cc index f703ba5eb..0981e5625 100644 --- a/packages/grpc-tools/src/node_plugin.cc +++ b/packages/grpc-tools/src/node_plugin.cc @@ -40,6 +40,7 @@ class NodeGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { generator_parameters.generate_package_definition = false; generator_parameters.grpc_js = false; generator_parameters.omit_serialize_instanceof = false; + generator_parameters.runtime = "google-protobuf"; if (!parameter.empty()) { std::vector parameters_list = grpc_generator::tokenize(parameter, ","); @@ -51,6 +52,8 @@ class NodeGrpcGenerator : public grpc::protobuf::compiler::CodeGenerator { generator_parameters.grpc_js = true; } else if (*parameter_string == "omit_serialize_instanceof") { generator_parameters.omit_serialize_instanceof = true; + } else if (parameter_string->find("runtime=") == 0) { + generator_parameters.runtime = parameter_string->substr(8); } } } From fc392e920f4fa2618041857945407378dea3fecf Mon Sep 17 00:00:00 2001 From: Timo Stamm Date: Tue, 9 Sep 2025 13:02:37 +0200 Subject: [PATCH 2/4] Fix example --- .../helloworld/static_codegen_es/greeter_client.js | 10 ++++++---- .../helloworld/static_codegen_es/greeter_server.js | 6 ++++-- examples/package.json | 1 + 3 files changed, 11 insertions(+), 6 deletions(-) diff --git a/examples/helloworld/static_codegen_es/greeter_client.js b/examples/helloworld/static_codegen_es/greeter_client.js index 668a3f8e4..70a7dfc3b 100644 --- a/examples/helloworld/static_codegen_es/greeter_client.js +++ b/examples/helloworld/static_codegen_es/greeter_client.js @@ -21,6 +21,7 @@ var messages = require('./helloworld_pb'); var services = require('./helloworld_grpc_pb'); var grpc = require('@grpc/grpc-js'); +var { create } = require('@bufbuild/protobuf'); function main() { var argv = parseArgs(process.argv.slice(2), { @@ -34,16 +35,17 @@ function main() { } var client = new services.GreeterClient(target, grpc.credentials.createInsecure()); - var request = new messages.HelloRequest(); var user; if (argv._.length > 0) { - user = argv._[0]; + user = argv._[0]; } else { user = 'world'; } - request.setName(user); + var request = create(messages.HelloRequestSchema, { + name: user, + }); client.sayHello(request, function(err, response) { - console.log('Greeting:', response.getMessage()); + console.log('Greeting:', response.message); }); } diff --git a/examples/helloworld/static_codegen_es/greeter_server.js b/examples/helloworld/static_codegen_es/greeter_server.js index ae2ab949d..0cf8422ff 100644 --- a/examples/helloworld/static_codegen_es/greeter_server.js +++ b/examples/helloworld/static_codegen_es/greeter_server.js @@ -20,13 +20,15 @@ var messages = require('./helloworld_pb'); var services = require('./helloworld_grpc_pb'); var grpc = require('@grpc/grpc-js'); +var { create } = require('@bufbuild/protobuf'); /** * Implements the SayHello RPC method. */ function sayHello(call, callback) { - var reply = new messages.HelloReply(); - reply.setMessage('Hello ' + call.request.getName()); + var reply = create(messages.HelloReplySchema, { + message: 'Hello ' + call.request.name, + }); callback(null, reply); } diff --git a/examples/package.json b/examples/package.json index 6e717dadb..78ac1fa34 100644 --- a/examples/package.json +++ b/examples/package.json @@ -5,6 +5,7 @@ "@grpc/proto-loader": "^0.6.0", "async": "^1.5.2", "google-protobuf": "^3.0.0", + "@bufbuild/protobuf": "^2.7.0", "@grpc/grpc-js": "^1.10.2", "@grpc/grpc-js-xds": "^1.10.0", "@grpc/reflection": "^1.0.0", From 40b50ff3b01ac211000fc0929185d4cf1f6c0d1b Mon Sep 17 00:00:00 2001 From: Sri Krishna Date: Wed, 10 Sep 2025 19:57:56 +0530 Subject: [PATCH 3/4] Use `bufbuild-protobuf` Signed-off-by: Sri Krishna --- packages/grpc-tools/src/node_generator.cc | 10 +++++----- packages/grpc-tools/src/node_generator.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/grpc-tools/src/node_generator.cc b/packages/grpc-tools/src/node_generator.cc index ca29d3676..daf8b78fa 100644 --- a/packages/grpc-tools/src/node_generator.cc +++ b/packages/grpc-tools/src/node_generator.cc @@ -114,12 +114,12 @@ grpc::string MessageIdentifierName(const grpc::string& name) { grpc::string NodeObjectPath(const Descriptor* descriptor, const grpc::string& runtime) { grpc::string module_alias = ModuleAlias(descriptor->file()->name()); - if (runtime == "es" && descriptor->file()->name().find("google/protobuf") == 0) { + if (runtime == "bufbuild-protobuf" && 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") { + if (runtime == "bufbuild-protobuf") { name += "Schema"; } return module_alias + "." + name; @@ -196,7 +196,7 @@ void PrintBufbuildProtobufMessageTransformer(const Descriptor* descriptor, Print // Prints out the message serializer and deserializer functions void PrintMessageTransformer(const Descriptor* descriptor, Printer* out, const Parameters& params) { - if (params.runtime == "es") { + if (params.runtime == "bufbuild-protobuf") { PrintBufbuildProtobufMessageTransformer(descriptor, out, params); } else { PrintGoogleProtobufMessageTransformer(descriptor, out, params); @@ -268,7 +268,7 @@ 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") { + if (params.runtime == "bufbuild-protobuf") { out->Print("var proto = require('@bufbuild/protobuf');\n"); } if (file->message_type_count() > 0) { @@ -279,7 +279,7 @@ void PrintImports(const FileDescriptor* file, Printer* out, } 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) { + if (params.runtime == "bufbuild-protobuf" && 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');"); diff --git a/packages/grpc-tools/src/node_generator.h b/packages/grpc-tools/src/node_generator.h index 23719d467..a294c4626 100644 --- a/packages/grpc-tools/src/node_generator.h +++ b/packages/grpc-tools/src/node_generator.h @@ -30,7 +30,7 @@ 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) + // Runtime to use for protobuf serialization (default: "google-protobuf", "bufbuild-protobuf" for @bufbuild/protobuf) grpc::string runtime; }; From 34f253276593a511e8ea7be0c75065de6bbc3daa Mon Sep 17 00:00:00 2001 From: Sri Krishna Date: Wed, 10 Sep 2025 21:16:58 +0530 Subject: [PATCH 4/4] Fix example readme Signed-off-by: Sri Krishna --- examples/helloworld/static_codegen_es/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/helloworld/static_codegen_es/README.md b/examples/helloworld/static_codegen_es/README.md index 59b88efe7..c3a4289e5 100644 --- a/examples/helloworld/static_codegen_es/README.md +++ b/examples/helloworld/static_codegen_es/README.md @@ -3,5 +3,5 @@ This is the static code generation variant of the Hello World. Code in these exa ```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 +grpc_tools_node_protoc --es_out=target=js,js_import_style=legacy_commonjs:../helloworld/static_codegen_es/ --grpc_out=grpc_js,runtime=bufbuild-protobuf:../helloworld/static_codegen_es/ helloworld.proto ```