2828#include < string>
2929#include < utility>
3030#include < vector>
31+
32+ #include " google/protobuf/compiler/plugin.h"
3133#ifdef major
3234#undef major
3335#endif
@@ -320,7 +322,7 @@ void CommandLineInterface::GetTransitiveDependencies(
320322 const FileDescriptor* file,
321323 absl::flat_hash_set<const FileDescriptor*>* already_seen,
322324 RepeatedPtrField<FileDescriptorProto>* output,
323- const TransitiveDependencyOptions& options) {
325+ const TransitiveDependencyOptions& options) const {
324326 if (!already_seen->insert (file).second ) {
325327 // Already saw this file. Skip.
326328 return ;
@@ -2733,30 +2735,8 @@ bool CommandLineInterface::GenerateOutput(
27332735 }
27342736 } else {
27352737 // Regular generator.
2736- std::string parameters = output_directive.parameter ;
2737- if (!generator_parameters_[output_directive.name ].empty ()) {
2738- if (!parameters.empty ()) {
2739- parameters.append (" ," );
2740- }
2741- parameters.append (generator_parameters_[output_directive.name ]);
2742- }
2743- if (!EnforceProto3OptionalSupport (
2744- output_directive.name ,
2745- output_directive.generator ->GetSupportedFeatures (), parsed_files)) {
2746- return false ;
2747- }
2748-
2749- if (!EnforceEditionsSupport (
2750- output_directive.name ,
2751- output_directive.generator ->GetSupportedFeatures (),
2752- output_directive.generator ->GetMinimumEdition (),
2753- output_directive.generator ->GetMaximumEdition (), parsed_files)) {
2754- return false ;
2755- }
2756-
2757- if (!output_directive.generator ->GenerateAll (parsed_files, parameters,
2758- generator_context, &error)) {
2759- // Generator returned an error.
2738+ if (!GenerateBuiltInOutput (parsed_files, output_directive,
2739+ generator_context, &error)) {
27602740 std::cerr << output_directive.name << " : " << error << std::endl;
27612741 return false ;
27622742 }
@@ -2846,22 +2826,16 @@ bool CommandLineInterface::GenerateDependencyManifestFile(
28462826 return true ;
28472827}
28482828
2849- bool CommandLineInterface::GeneratePluginOutput (
2850- const std::vector<const FileDescriptor*>& parsed_files,
2851- const std::string& plugin_name, const std::string& parameter,
2852- GeneratorContext* generator_context, std::string* error) {
2829+ CodeGeneratorRequest CommandLineInterface::CreateCodeGeneratorRequest (
2830+ std::vector<const FileDescriptor*> parsed_files, std::string parameter,
2831+ bool copy_json_name, bool bootstrap) const {
28532832 CodeGeneratorRequest request;
2854- CodeGeneratorResponse response;
2855- std::string processed_parameter = parameter;
2856-
2857- bool bootstrap = GetBootstrapParam (processed_parameter);
28582833
28592834 // Build the request.
2860- if (!processed_parameter .empty ()) {
2861- request.set_parameter (processed_parameter );
2835+ if (!parameter .empty ()) {
2836+ request.set_parameter (parameter );
28622837 }
28632838
2864-
28652839 absl::flat_hash_set<const FileDescriptor*> already_seen;
28662840 for (const FileDescriptor* file : parsed_files) {
28672841 request.add_file_to_generate (file->name ());
@@ -2877,9 +2851,6 @@ bool CommandLineInterface::GeneratePluginOutput(
28772851 const DescriptorPool* pool = parsed_files[0 ]->pool ();
28782852 absl::flat_hash_set<std::string> files_to_generate (input_files_.begin (),
28792853 input_files_.end ());
2880- static const auto builtin_plugins = new absl::flat_hash_set<std::string>(
2881- {" protoc-gen-cpp" , " protoc-gen-java" , " protoc-gen-mutable_java" ,
2882- " protoc-gen-python" });
28832854 for (FileDescriptorProto& file_proto : *request.mutable_proto_file ()) {
28842855 if (files_to_generate.contains (file_proto.name ())) {
28852856 const FileDescriptor* file = pool->FindFileByName (file_proto.name ());
@@ -2889,8 +2860,7 @@ bool CommandLineInterface::GeneratePluginOutput(
28892860 if (!bootstrap) {
28902861 file->CopySourceCodeInfoTo (&file_proto);
28912862
2892- // The built-in code generators didn't use the json names.
2893- if (!builtin_plugins->contains (plugin_name)) {
2863+ if (copy_json_name) {
28942864 file->CopyJsonNameTo (&file_proto);
28952865 }
28962866 }
@@ -2905,21 +2875,12 @@ bool CommandLineInterface::GeneratePluginOutput(
29052875 version->set_patch (PROTOBUF_VERSION % 1000 );
29062876 version->set_suffix (PROTOBUF_VERSION_SUFFIX);
29072877
2908- // Invoke the plugin.
2909- Subprocess subprocess;
2910-
2911- if (plugins_.count (plugin_name) > 0 ) {
2912- subprocess.Start (plugins_[plugin_name], Subprocess::EXACT_NAME);
2913- } else {
2914- subprocess.Start (plugin_name, Subprocess::SEARCH_PATH);
2915- }
2916-
2917- std::string communicate_error;
2918- if (!subprocess.Communicate (request, &response, &communicate_error)) {
2919- *error = absl::Substitute (" $0: $1" , plugin_name, communicate_error);
2920- return false ;
2921- }
2878+ return request;
2879+ }
29222880
2881+ bool CommandLineInterface::GenerateCodeFromResponse (
2882+ const CodeGeneratorResponse& response, GeneratorContext* generator_context,
2883+ bool bootstrap, std::string plugin_name, std::string* error) {
29232884 // Write the files. We do this even if there was a generator error in order
29242885 // to match the behavior of a compiled-in generator.
29252886 std::unique_ptr<io::ZeroCopyOutputStream> current_output;
@@ -2956,6 +2917,46 @@ bool CommandLineInterface::GeneratePluginOutput(
29562917 writer.WriteString (output_file.content ());
29572918 }
29582919
2920+ return true ;
2921+ }
2922+
2923+ bool CommandLineInterface::GeneratePluginOutput (
2924+ const std::vector<const FileDescriptor*>& parsed_files,
2925+ const std::string& plugin_name, const std::string& parameter,
2926+ GeneratorContext* generator_context, std::string* error) {
2927+ // TODO Remove these special-cases and send json names to all
2928+ // plugins.
2929+ static const auto builtin_plugins = new absl::flat_hash_set<std::string>(
2930+ {" protoc-gen-cpp" , " protoc-gen-java" , " protoc-gen-mutable_java" ,
2931+ " protoc-gen-python" });
2932+
2933+ bool bootstrap = GetBootstrapParam (parameter);
2934+ CodeGeneratorRequest request = CreateCodeGeneratorRequest (
2935+ parsed_files, parameter,
2936+ // The built-in code generators didn't use the json names.
2937+ /* copy_json_name=*/ !builtin_plugins->contains (plugin_name), bootstrap);
2938+ CodeGeneratorResponse response;
2939+
2940+ // Invoke the plugin.
2941+ Subprocess subprocess;
2942+
2943+ if (plugins_.count (plugin_name) > 0 ) {
2944+ subprocess.Start (plugins_[plugin_name], Subprocess::EXACT_NAME);
2945+ } else {
2946+ subprocess.Start (plugin_name, Subprocess::SEARCH_PATH);
2947+ }
2948+
2949+ std::string communicate_error;
2950+ if (!subprocess.Communicate (request, &response, &communicate_error)) {
2951+ *error = absl::Substitute (" $0: $1" , plugin_name, communicate_error);
2952+ return false ;
2953+ }
2954+
2955+ if (!GenerateCodeFromResponse (response, generator_context, bootstrap,
2956+ plugin_name, error)) {
2957+ return false ;
2958+ }
2959+
29592960 // Check for errors.
29602961 bool success = true ;
29612962 if (!EnforceProto3OptionalSupport (plugin_name, response.supported_features (),
@@ -2977,6 +2978,51 @@ bool CommandLineInterface::GeneratePluginOutput(
29772978 return success;
29782979}
29792980
2981+ bool CommandLineInterface::GenerateBuiltInOutput (
2982+ const std::vector<const FileDescriptor*>& parsed_files,
2983+ const OutputDirective& output_directive,
2984+ GeneratorContext* generator_context, std::string* error) {
2985+ std::string parameters = output_directive.parameter ;
2986+ if (!generator_parameters_[output_directive.name ].empty ()) {
2987+ if (!parameters.empty ()) {
2988+ parameters.append (" ," );
2989+ }
2990+ parameters.append (generator_parameters_[output_directive.name ]);
2991+ }
2992+ if (!EnforceProto3OptionalSupport (
2993+ output_directive.name ,
2994+ output_directive.generator ->GetSupportedFeatures (), parsed_files)) {
2995+ return false ;
2996+ }
2997+
2998+ if (!EnforceEditionsSupport (
2999+ output_directive.name ,
3000+ output_directive.generator ->GetSupportedFeatures (),
3001+ output_directive.generator ->GetMinimumEdition (),
3002+ output_directive.generator ->GetMaximumEdition (), parsed_files)) {
3003+ return false ;
3004+ }
3005+
3006+ CodeGeneratorRequest request =
3007+ CreateCodeGeneratorRequest (parsed_files, parameters);
3008+ CodeGeneratorResponse response;
3009+ if (!GenerateCode (request, *output_directive.generator , &response, error)) {
3010+ return false ;
3011+ }
3012+ if (response.has_error ()) {
3013+ *error = response.error ();
3014+ return false ;
3015+ }
3016+
3017+ if (!GenerateCodeFromResponse (response, generator_context,
3018+ /* bootstrap=*/ false , output_directive.name ,
3019+ error)) {
3020+ return false ;
3021+ }
3022+
3023+ return true ;
3024+ }
3025+
29803026bool CommandLineInterface::EncodeOrDecode (const DescriptorPool* pool) {
29813027 // Look up the type.
29823028 const Descriptor* type = pool->FindMessageTypeByName (codec_type_);
0 commit comments