@@ -121,9 +121,12 @@ using google::protobuf::io::win32::setmode;
121121using google::protobuf::io::win32::write;
122122#endif
123123
124- static const char * kDefaultDirectDependenciesViolationMsg =
124+ constexpr absl::string_view kDefaultDirectDependenciesViolationMsg =
125125 " File is imported but not declared in --direct_dependencies: %s" ;
126126
127+ constexpr absl::string_view kDefaultOptionDependenciesViolationMsg =
128+ " File is option imported but not declared in --option_dependencies: %s" ;
129+
127130// Returns true if the text begins with a Windows-style absolute path, starting
128131// with a drive letter. Example: "C:\foo".
129132static bool StartsWithWindowsAbsolutePath (absl::string_view text) {
@@ -958,7 +961,9 @@ const char* const CommandLineInterface::kPathSeparator = ":";
958961
959962CommandLineInterface::CommandLineInterface ()
960963 : direct_dependencies_violation_msg_(
961- kDefaultDirectDependenciesViolationMsg ) {}
964+ kDefaultDirectDependenciesViolationMsg ),
965+ option_dependencies_violation_msg_ (
966+ kDefaultOptionDependenciesViolationMsg ) {}
962967
963968CommandLineInterface::~CommandLineInterface () = default ;
964969
@@ -1645,6 +1650,26 @@ bool CommandLineInterface::ParseInputFiles(
16451650 break ;
16461651 }
16471652 }
1653+
1654+ // Enforce --option_dependencies.
1655+ if (option_dependencies_explicitly_set_) {
1656+ bool indirect_option_imports = false ;
1657+ for (int i = 0 ; i < parsed_file->option_dependency_count (); ++i) {
1658+ if (option_dependencies_.find (parsed_file->option_dependency_name (i)) ==
1659+ option_dependencies_.end ()) {
1660+ indirect_option_imports = true ;
1661+ std::cerr << parsed_file->name () << " : "
1662+ << absl::StrReplaceAll (
1663+ option_dependencies_violation_msg_,
1664+ {{" %s" , parsed_file->option_dependency_name (i)}})
1665+ << std::endl;
1666+ }
1667+ }
1668+ if (indirect_option_imports) {
1669+ result = false ;
1670+ break ;
1671+ }
1672+ }
16481673 }
16491674 descriptor_pool->ClearDirectInputFiles ();
16501675 return result;
@@ -1658,6 +1683,8 @@ void CommandLineInterface::Clear() {
16581683 input_files_.clear ();
16591684 direct_dependencies_.clear ();
16601685 direct_dependencies_violation_msg_ = kDefaultDirectDependenciesViolationMsg ;
1686+ option_dependencies_.clear ();
1687+ option_dependencies_violation_msg_ = kDefaultOptionDependenciesViolationMsg ;
16611688 output_directives_.clear ();
16621689 codec_type_.clear ();
16631690 descriptor_set_in_names_.clear ();
@@ -2139,7 +2166,23 @@ CommandLineInterface::InterpretArgument(const std::string& name,
21392166
21402167 } else if (name == " --direct_dependencies_violation_msg" ) {
21412168 direct_dependencies_violation_msg_ = value;
2169+ } else if (name == " --option_dependencies" ) {
2170+ if (option_dependencies_explicitly_set_) {
2171+ std::cerr << name
2172+ << " may only be passed once. To specify multiple "
2173+ " option dependencies, pass them all as a single "
2174+ " parameter separated by ':'."
2175+ << std::endl;
2176+ return PARSE_ARGUMENT_FAIL;
2177+ }
21422178
2179+ option_dependencies_explicitly_set_ = true ;
2180+ std::vector<std::string> direct =
2181+ absl::StrSplit (value, ' :' , absl::SkipEmpty ());
2182+ ABSL_DCHECK (option_dependencies_.empty ());
2183+ option_dependencies_.insert (direct.begin (), direct.end ());
2184+ } else if (name == " --option_dependencies_violation_msg" ) {
2185+ option_dependencies_violation_msg_ = value;
21432186 } else if (name == " --descriptor_set_in" ) {
21442187 if (!descriptor_set_in_names_.empty ()) {
21452188 std::cerr << name
@@ -2520,7 +2563,13 @@ Parse PROTO_FILES and generate output based on the options given:
25202563 are counted as occupied fields numbers.
25212564 --enable_codegen_trace Enables tracing which parts of protoc are
25222565 responsible for what codegen output. Not supported
2523- by all backends or on all platforms.)" ;
2566+ by all backends or on all platforms.
2567+ --direct_dependencies A colon delimited list of imports that are
2568+ allowed to be used in "import"
2569+ declarations, when explictily provided.
2570+ --option_dependencies A colon delimited list of imports that are
2571+ allowed to be used in "import option"
2572+ declarations, when explicitly provided.)" ;
25242573 std::cout << R"(
25252574 --notices Show notice file and exit.)" ;
25262575 if (!plugin_prefix_.empty ()) {
0 commit comments