@@ -121,9 +121,12 @@ using google::protobuf::io::win32::setmode;
121
121
using google::protobuf::io::win32::write;
122
122
#endif
123
123
124
- static const char * kDefaultDirectDependenciesViolationMsg =
124
+ constexpr absl::string_view kDefaultDirectDependenciesViolationMsg =
125
125
" File is imported but not declared in --direct_dependencies: %s" ;
126
126
127
+ constexpr absl::string_view kDefaultOptionDependenciesViolationMsg =
128
+ " File is option imported but not declared in --option_dependencies: %s" ;
129
+
127
130
// Returns true if the text begins with a Windows-style absolute path, starting
128
131
// with a drive letter. Example: "C:\foo".
129
132
static bool StartsWithWindowsAbsolutePath (absl::string_view text) {
@@ -958,7 +961,9 @@ const char* const CommandLineInterface::kPathSeparator = ":";
958
961
959
962
CommandLineInterface::CommandLineInterface ()
960
963
: direct_dependencies_violation_msg_(
961
- kDefaultDirectDependenciesViolationMsg ) {}
964
+ kDefaultDirectDependenciesViolationMsg ),
965
+ option_dependencies_violation_msg_ (
966
+ kDefaultOptionDependenciesViolationMsg ) {}
962
967
963
968
CommandLineInterface::~CommandLineInterface () = default ;
964
969
@@ -1645,6 +1650,26 @@ bool CommandLineInterface::ParseInputFiles(
1645
1650
break ;
1646
1651
}
1647
1652
}
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
+ }
1648
1673
}
1649
1674
descriptor_pool->ClearDirectInputFiles ();
1650
1675
return result;
@@ -1657,7 +1682,11 @@ void CommandLineInterface::Clear() {
1657
1682
proto_path_.clear ();
1658
1683
input_files_.clear ();
1659
1684
direct_dependencies_.clear ();
1660
- direct_dependencies_violation_msg_ = kDefaultDirectDependenciesViolationMsg ;
1685
+ direct_dependencies_violation_msg_ =
1686
+ std::string (kDefaultDirectDependenciesViolationMsg );
1687
+ option_dependencies_.clear ();
1688
+ option_dependencies_violation_msg_ =
1689
+ std::string (kDefaultOptionDependenciesViolationMsg );
1661
1690
output_directives_.clear ();
1662
1691
codec_type_.clear ();
1663
1692
descriptor_set_in_names_.clear ();
@@ -2139,7 +2168,23 @@ CommandLineInterface::InterpretArgument(const std::string& name,
2139
2168
2140
2169
} else if (name == " --direct_dependencies_violation_msg" ) {
2141
2170
direct_dependencies_violation_msg_ = value;
2171
+ } else if (name == " --option_dependencies" ) {
2172
+ if (option_dependencies_explicitly_set_) {
2173
+ std::cerr << name
2174
+ << " may only be passed once. To specify multiple "
2175
+ " option dependencies, pass them all as a single "
2176
+ " parameter separated by ':'."
2177
+ << std::endl;
2178
+ return PARSE_ARGUMENT_FAIL;
2179
+ }
2142
2180
2181
+ option_dependencies_explicitly_set_ = true ;
2182
+ std::vector<std::string> direct =
2183
+ absl::StrSplit (value, ' :' , absl::SkipEmpty ());
2184
+ ABSL_DCHECK (option_dependencies_.empty ());
2185
+ option_dependencies_.insert (direct.begin (), direct.end ());
2186
+ } else if (name == " --option_dependencies_violation_msg" ) {
2187
+ option_dependencies_violation_msg_ = value;
2143
2188
} else if (name == " --descriptor_set_in" ) {
2144
2189
if (!descriptor_set_in_names_.empty ()) {
2145
2190
std::cerr << name
@@ -2520,7 +2565,13 @@ Parse PROTO_FILES and generate output based on the options given:
2520
2565
are counted as occupied fields numbers.
2521
2566
--enable_codegen_trace Enables tracing which parts of protoc are
2522
2567
responsible for what codegen output. Not supported
2523
- by all backends or on all platforms.)" ;
2568
+ by all backends or on all platforms.
2569
+ --direct_dependencies A colon delimited list of imports that are
2570
+ allowed to be used in "import"
2571
+ declarations, when explictily provided.
2572
+ --option_dependencies A colon delimited list of imports that are
2573
+ allowed to be used in "import option"
2574
+ declarations, when explicitly provided.)" ;
2524
2575
std::cout << R"(
2525
2576
--notices Show notice file and exit.)" ;
2526
2577
if (!plugin_prefix_.empty ()) {
0 commit comments