From 150644d7f4d030a0629c564fd90dc3becab77636 Mon Sep 17 00:00:00 2001 From: Anton Bobukh Date: Wed, 15 May 2024 08:17:40 -0700 Subject: [PATCH] [gRPC] Add new options to control the gRPC code generation. (#8298) The new options are: - `--grpc-filename-suffix` controls the suffix of the generated files; - `--grpc-use-system-headers` controls the type of C++ includes generated; - `--grpc-search-path` controls the directory that contains gRPC runtime; - `--grpc-additional-header` allows to provide additional dependencies for the generated code. --- grpc/src/compiler/cpp_generator.cc | 6 ++--- grpc/src/compiler/cpp_generator.h | 2 ++ include/flatbuffers/idl.h | 11 +++++++++- src/flatc.cpp | 31 ++++++++++++++++++++++++++ src/idl_gen_grpc.cpp | 35 ++++++++++++++++++++++++------ 5 files changed, 73 insertions(+), 12 deletions(-) diff --git a/grpc/src/compiler/cpp_generator.cc b/grpc/src/compiler/cpp_generator.cc index fd635f2fa5e..21a94acf545 100644 --- a/grpc/src/compiler/cpp_generator.cc +++ b/grpc/src/compiler/cpp_generator.cc @@ -8,8 +8,6 @@ namespace grpc_cpp_generator { namespace { -static grpc::string service_header_ext() { return ".grpc.fb.h"; } - template static grpc::string as_string(T x) { std::ostringstream out; @@ -1137,7 +1135,7 @@ grpc::string GetSourcePrologue(grpc_generator::File *file, vars["filename"] = file->filename(); vars["filename_base"] = file->filename_without_ext(); vars["message_header_ext"] = params.message_header_extension; - vars["service_header_ext"] = service_header_ext(); + vars["service_header_ext"] = params.service_header_extension; printer->Print(vars, "// Generated by the gRPC C++ plugin.\n"); printer->Print(vars, @@ -1557,7 +1555,7 @@ grpc::string GetMockPrologue(grpc_generator::File *file, vars["filename"] = file->filename(); vars["filename_base"] = file->filename_without_ext(); vars["message_header_ext"] = params.message_header_extension; - vars["service_header_ext"] = service_header_ext(); + vars["service_header_ext"] = params.service_header_extension; printer->Print(vars, "// Generated by the gRPC C++ plugin.\n"); printer->Print(vars, diff --git a/grpc/src/compiler/cpp_generator.h b/grpc/src/compiler/cpp_generator.h index a9af1a6794f..98e37df97ad 100644 --- a/grpc/src/compiler/cpp_generator.h +++ b/grpc/src/compiler/cpp_generator.h @@ -35,6 +35,8 @@ struct Parameters { bool generate_mock_code; // By default, use "_generated.h" std::string message_header_extension; + // Default: ".grpc.fb.h" + std::string service_header_extension; }; // Return the prologue of the generated header file. diff --git a/include/flatbuffers/idl.h b/include/flatbuffers/idl.h index a08db9bb658..cb3b2123c43 100644 --- a/include/flatbuffers/idl.h +++ b/include/flatbuffers/idl.h @@ -22,6 +22,7 @@ #include #include #include +#include #include "flatbuffers/base.h" #include "flatbuffers/flatbuffers.h" @@ -759,6 +760,12 @@ struct IDLOptions { // make the flatbuffer more compact. bool set_empty_vectors_to_null; + /*********************************** gRPC ***********************************/ + std::string grpc_filename_suffix; + bool grpc_use_system_headers; + std::string grpc_search_path; + std::vector grpc_additional_headers; + IDLOptions() : gen_jvmstatic(false), use_flexbuffers(false), @@ -829,7 +836,9 @@ struct IDLOptions { rust_module_root_file(false), lang_to_generate(0), set_empty_strings_to_null(true), - set_empty_vectors_to_null(true) {} + set_empty_vectors_to_null(true), + grpc_filename_suffix(".fb"), + grpc_use_system_headers(true) {} }; // This encapsulates where the parser is in the current source file. diff --git a/src/flatc.cpp b/src/flatc.cpp index f29d1092646..398fc77976b 100644 --- a/src/flatc.cpp +++ b/src/flatc.cpp @@ -258,6 +258,13 @@ const static FlatCOption flatc_options[] = { "Omit emission of namespace entrypoint file" }, { "", "file-names-only", "", "Print out generated file names without writing to the files" }, + { "", "grpc-filename-suffix", "SUFFIX", + "The suffix for the generated file names (Default is '.fb')." }, + { "", "grpc-additional-header", "", + "Additional headers to prepend to the generated files." }, + { "", "grpc-use-system-headers", "", + "Use <> for headers included from the generated code." }, + { "", "grpc-search-path", "PATH", "Prefix to any gRPC includes." }, }; auto cmp = [](FlatCOption a, FlatCOption b) { return a.long_opt < b.long_opt; }; @@ -674,6 +681,30 @@ FlatCOptions FlatCompiler::ParseFromCommandLineArguments(int argc, } else if (arg == "--file-names-only") { // TODO (khhn): Provide 2 implementation options.file_names_only = true; + } else if (arg == "--grpc-filename-suffix") { + if (++argi >= argc) Error("missing gRPC filename suffix: " + arg, true); + opts.grpc_filename_suffix = argv[argi]; + } else if (arg.rfind("--grpc-filename-suffix=", 0) == 0) { + opts.grpc_filename_suffix = + arg.substr(std::string("--grpc-filename-suffix=").size()); + } else if (arg == "--grpc-additional-header") { + if (++argi >= argc) Error("missing include following: " + arg, true); + opts.grpc_additional_headers.push_back(argv[argi]); + } else if (arg.rfind("--grpc-additional-header=", 0) == 0) { + opts.grpc_additional_headers.push_back( + arg.substr(std::string("--grpc-additional-header=").size())); + } else if (arg == "--grpc-search-path") { + if (++argi >= argc) Error("missing gRPC search path: " + arg, true); + opts.grpc_search_path = argv[argi]; + } else if (arg.rfind("--grpc-search-path=", 0) == 0) { + opts.grpc_search_path = + arg.substr(std::string("--grpc-search-path=").size()); + } else if (arg == "--grpc-use-system-headers" || + arg == "--grpc-use-system-headers=true") { + opts.grpc_use_system_headers = true; + } else if (arg == "--no-grpc-use-system-headers" || + arg == "--grpc-use-system-headers=false") { + opts.grpc_use_system_headers = false; } else { if (arg == "--proto") { opts.proto_mode = true; } diff --git a/src/idl_gen_grpc.cpp b/src/idl_gen_grpc.cpp index 2be24e71a27..e7c3753effc 100644 --- a/src/idl_gen_grpc.cpp +++ b/src/idl_gen_grpc.cpp @@ -16,6 +16,8 @@ // independent from idl_parser, since this code is not needed for most clients +#include + #include "flatbuffers/code_generators.h" #include "flatbuffers/flatbuffers.h" #include "flatbuffers/idl.h" @@ -253,6 +255,15 @@ class FlatBufFile : public grpc_generator::File { std::string additional_headers() const { switch (language_) { case kLanguageCpp: { + if (!parser_.opts.grpc_additional_headers.empty()) { + std::string result = ""; + for (const std::string &header : + parser_.opts.grpc_additional_headers) { + if (!result.empty()) result += "\n"; + result += "#include \"" + header + "\""; + } + return result; + } return "#include \"flatbuffers/grpc.h\"\n"; } case kLanguageGo: { @@ -356,10 +367,16 @@ bool GenerateCppGRPC(const Parser &parser, const std::string &path, grpc_cpp_generator::Parameters generator_parameters; // TODO(wvo): make the other parameters in this struct configurable. - generator_parameters.use_system_headers = true; + generator_parameters.use_system_headers = opts.grpc_use_system_headers; generator_parameters.message_header_extension = suffix; - - FlatBufFile fbfile(parser, file_name, FlatBufFile::kLanguageCpp); + generator_parameters.service_header_extension = + ".grpc" + opts.grpc_filename_suffix + ".h"; + generator_parameters.grpc_search_path = opts.grpc_search_path; + std::string filename = flatbuffers::StripExtension(parser.file_being_parsed_); + if (!opts.keep_prefix) { + filename = flatbuffers::StripPath(filename); + } + FlatBufFile fbfile(parser, filename, FlatBufFile::kLanguageCpp); std::string header_code = grpc_cpp_generator::GetHeaderPrologue(&fbfile, generator_parameters) + @@ -373,10 +390,14 @@ bool GenerateCppGRPC(const Parser &parser, const std::string &path, grpc_cpp_generator::GetSourceServices(&fbfile, generator_parameters) + grpc_cpp_generator::GetSourceEpilogue(&fbfile, generator_parameters); - return flatbuffers::SaveFile((path + file_name + ".grpc.fb.h").c_str(), - header_code, false) && - flatbuffers::SaveFile((path + file_name + ".grpc.fb.cc").c_str(), - source_code, false); + return flatbuffers::SaveFile( + (path + file_name + ".grpc" + opts.grpc_filename_suffix + ".h") + .c_str(), + header_code, false) && + flatbuffers::SaveFile( + (path + file_name + ".grpc" + opts.grpc_filename_suffix + ".cc") + .c_str(), + source_code, false); } class JavaGRPCGenerator : public flatbuffers::BaseGenerator {