From 98835fb8f8a8f144f2a1eac0b833ff83f4a05f54 Mon Sep 17 00:00:00 2001 From: Bo Yang Date: Mon, 19 Sep 2016 13:45:07 -0700 Subject: Integrate internal changes --- src/google/protobuf/compiler/command_line_interface.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/google/protobuf/compiler/command_line_interface.h') diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h index 32084567..c38e65a3 100644 --- a/src/google/protobuf/compiler/command_line_interface.h +++ b/src/google/protobuf/compiler/command_line_interface.h @@ -352,6 +352,11 @@ class LIBPROTOC_EXPORT CommandLineInterface { vector > proto_path_; // Search path for proto files. vector input_files_; // Names of the input proto files. + // Names of proto files which are allowed to be imported. Used by build + // systems to enforce depend-on-what-you-import. + set direct_dependencies_; + bool direct_dependencies_explicitly_set_; + // output_directives_ lists all the files we are supposed to output and what // generator to use for each. struct OutputDirective { -- cgit v1.2.3 From 59cd5d0e26c180117d9d5fe16be536e63d29e332 Mon Sep 17 00:00:00 2001 From: Jisi Liu Date: Tue, 25 Oct 2016 17:43:59 -0700 Subject: Support extra parameters for plugins. --- .../protobuf/compiler/command_line_interface.cc | 44 ++++++++++++++++++---- .../protobuf/compiler/command_line_interface.h | 25 ++++++++---- .../compiler/command_line_interface_unittest.cc | 38 +++++++++++++++++++ 3 files changed, 91 insertions(+), 16 deletions(-) (limited to 'src/google/protobuf/compiler/command_line_interface.h') diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index 79d2dd66..584175bf 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -262,6 +262,10 @@ void AddDefaultProtoPaths(vector >* paths) { return; } } + +string PluginName(const string& plugin_prefix, const string& directive) { + return plugin_prefix + "gen-" + directive.substr(2, directive.size() - 6); +} } // namespace // A MultiFileErrorCollector that prints errors to stderr. @@ -1007,6 +1011,18 @@ CommandLineInterface::ParseArguments(int argc, const char* const argv[]) { return status; } + // Make sure each plugin option has a matching plugin output. + for (map::const_iterator i = plugin_parameters_.begin(); + i != plugin_parameters_.end(); ++i) { + if (plugins_.find(i->first) == plugins_.end()) { + std::cerr << "Unknown flag: " + // strip prefix + "gen-" and add back "_opt" + << "--" + i->first.substr(plugin_prefix_.size() + 4) + "_opt" + << std::endl; + return PARSE_ARGUMENT_FAIL; + } + } + // If no --proto_path was given, use the current working directory. if (proto_path_.empty()) { // Don't use make_pair as the old/default standard library on Solaris @@ -1335,15 +1351,22 @@ CommandLineInterface::InterpretArgument(const string& name, (plugin_prefix_.empty() || !HasSuffixString(name, "_out"))) { // Check if it's a generator option flag. generator_info = FindOrNull(generators_by_option_name_, name); - if (generator_info == NULL) { - std::cerr << "Unknown flag: " << name << std::endl; - return PARSE_ARGUMENT_FAIL; - } else { + if (generator_info != NULL) { string* parameters = &generator_parameters_[generator_info->flag_name]; if (!parameters->empty()) { parameters->append(","); } parameters->append(value); + } else if (HasPrefixString(name, "--") && HasSuffixString(name, "_opt")) { + string* parameters = + &plugin_parameters_[PluginName(plugin_prefix_, name)]; + if (!parameters->empty()) { + parameters->append(","); + } + parameters->append(value); + } else { + std::cerr << "Unknown flag: " << name << std::endl; + return PARSE_ARGUMENT_FAIL; } } else { // It's an output flag. Add it to the output directives. @@ -1463,11 +1486,16 @@ bool CommandLineInterface::GenerateOutput( << "Bad name for plugin generator: " << output_directive.name; // Strip the "--" and "_out" and add the plugin prefix. - string plugin_name = plugin_prefix_ + "gen-" + - output_directive.name.substr(2, output_directive.name.size() - 6); - + string plugin_name = PluginName(plugin_prefix_ , output_directive.name); + string parameters = output_directive.parameter; + if (!plugin_parameters_[plugin_name].empty()) { + if (!parameters.empty()) { + parameters.append(","); + } + parameters.append(plugin_parameters_[plugin_name]); + } if (!GeneratePluginOutput(parsed_files, plugin_name, - output_directive.parameter, + parameters, generator_context, &error)) { std::cerr << output_directive.name << ": " << error << std::endl; return false; diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h index c38e65a3..d779fc87 100644 --- a/src/google/protobuf/compiler/command_line_interface.h +++ b/src/google/protobuf/compiler/command_line_interface.h @@ -146,14 +146,14 @@ class LIBPROTOC_EXPORT CommandLineInterface { // plugin [--out=OUTDIR] [--parameter=PARAMETER] PROTO_FILES < DESCRIPTORS // --out indicates the output directory (as passed to the --foo_out // parameter); if omitted, the current directory should be used. --parameter - // gives the generator parameter, if any was provided. The PROTO_FILES list - // the .proto files which were given on the compiler command-line; these are - // the files for which the plugin is expected to generate output code. - // Finally, DESCRIPTORS is an encoded FileDescriptorSet (as defined in - // descriptor.proto). This is piped to the plugin's stdin. The set will - // include descriptors for all the files listed in PROTO_FILES as well as - // all files that they import. The plugin MUST NOT attempt to read the - // PROTO_FILES directly -- it must use the FileDescriptorSet. + // gives the generator parameter, if any was provided (see below). The + // PROTO_FILES list the .proto files which were given on the compiler + // command-line; these are the files for which the plugin is expected to + // generate output code. Finally, DESCRIPTORS is an encoded FileDescriptorSet + // (as defined in descriptor.proto). This is piped to the plugin's stdin. + // The set will include descriptors for all the files listed in PROTO_FILES as + // well as all files that they import. The plugin MUST NOT attempt to read + // the PROTO_FILES directly -- it must use the FileDescriptorSet. // // The plugin should generate whatever files are necessary, as code generators // normally do. It should write the names of all files it generates to @@ -161,6 +161,13 @@ class LIBPROTOC_EXPORT CommandLineInterface { // names or relative to the current directory. If any errors occur, error // messages should be written to stderr. If an error is fatal, the plugin // should exit with a non-zero exit code. + // + // Plugins can have generator parameters similar to normal built-in + // generators. Extra generator parameters can be passed in via a matching + // "_opt" parameter. For example: + // protoc --plug_out=enable_bar:outdir --plug_opt=enable_baz + // This will pass "enable_bar,enable_baz" as the parameter to the plugin. + // void AllowPlugins(const string& exe_name_prefix); // Run the Protocol Compiler with the given command-line parameters. @@ -316,6 +323,8 @@ class LIBPROTOC_EXPORT CommandLineInterface { // protoc --foo_out=outputdir --foo_opt=enable_bar ... // Then there will be an entry ("--foo_out", "enable_bar") in this map. map generator_parameters_; + // Similar to generator_parameters_, but stores the parameters for plugins. + map plugin_parameters_; // See AllowPlugins(). If this is empty, plugins aren't allowed. string plugin_prefix_; diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc index 56a07dbf..dfbaa45a 100644 --- a/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -653,6 +653,44 @@ TEST_F(CommandLineInterfaceTest, ExtraGeneratorParameters) { "test_generator", "baz,foo1,foo2,foo3", "foo.proto", "Foo", "b"); } +TEST_F(CommandLineInterfaceTest, ExtraPluginParameters) { + // Test that generator parameters specified with the option flag are + // correctly passed to the code generator. + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + // Create the "a" and "b" sub-directories. + CreateTempDir("a"); + CreateTempDir("b"); + + Run("protocol_compiler " + "--plug_opt=foo1 " + "--plug_out=bar:$tmpdir/a " + "--plug_opt=foo2 " + "--plug_out=baz:$tmpdir/b " + "--plug_opt=foo3 " + "--proto_path=$tmpdir foo.proto"); + + ExpectNoErrors(); + ExpectGenerated( + "test_plugin", "bar,foo1,foo2,foo3", "foo.proto", "Foo", "a"); + ExpectGenerated( + "test_plugin", "baz,foo1,foo2,foo3", "foo.proto", "Foo", "b"); +} + +TEST_F(CommandLineInterfaceTest, UnrecognizedExtraParameters) { + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n" + "message Foo {}\n"); + + Run("protocol_compiler --plug_out=TestParameter:$tmpdir " + "--unknown_plug_opt=Foo " + "--proto_path=$tmpdir foo.proto"); + + ExpectErrorSubstring("Unknown flag: --unknown_plug_opt"); +} + TEST_F(CommandLineInterfaceTest, Insert) { // Test running a generator that inserts code into another's output. -- cgit v1.2.3