Add two new generation options around objc prefix usage.

- `require_prefixes`: Fail generation if a file doesn't have the option.
- `prefixes_must_be_registered`: If a prefix is in a file, it must be registered
  in the expected file. There is a grey space here for files without packages as
  there is no way to register it, so these case will still warn at the moment.
pull/9017/head
Thomas Van Lenten 3 years ago
parent b75bb09551
commit c4e0deddb9
  1. 35
      src/google/protobuf/compiler/objectivec/objectivec_generator.cc
  2. 24
      src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
  3. 2
      src/google/protobuf/compiler/objectivec/objectivec_helpers.h

@ -101,6 +101,41 @@ bool ObjectiveCGenerator::GenerateAll(
generation_options.expected_prefixes_suppressions.push_back(
std::string(split_piece));
}
} else if (options[i].first == "prefixes_must_be_registered") {
// If objc prefix file option value must be registered to be used. This
// option has no meaning if an "expected_prefixes_path" isn't set. The
// available options are:
// "no": They don't have to be registered.
// "yes": They must be registered and an error will be raised if a files
// tried to use a prefix that isn't registered.
// Default is "no".
std::string upper_value(options[i].second);
UpperString(&upper_value);
if (upper_value == "NO") {
generation_options.prefixes_must_be_registered = false;
} else if (upper_value == "YES") {
generation_options.prefixes_must_be_registered = true;
} else {
*error = "error: Unknown value for prefixes_must_be_registered: " + options[i].second;
return false;
}
} else if (options[i].first == "require_prefixes") {
// If every file must have an objc prefix file option to be used. The
// available options are:
// "no": Files can be generated without the prefix option.
// "yes": Files must have the objc prefix option, and an error will be
// raised if a files doesn't have one.
// Default is "no".
std::string upper_value(options[i].second);
UpperString(&upper_value);
if (upper_value == "NO") {
generation_options.require_prefixes = false;
} else if (upper_value == "YES") {
generation_options.require_prefixes = true;
} else {
*error = "error: Unknown value for require_prefixes: " + options[i].second;
return false;
}
} else if (options[i].first == "generate_for_named_framework") {
// The name of the framework that protos are being generated for. This
// will cause the #import statements to be framework based using this

@ -178,6 +178,8 @@ Options::Options() {
expected_prefixes_suppressions =
Split(suppressions, ";", true);
}
prefixes_must_be_registered = false;
require_prefixes = false;
}
namespace {
@ -1227,6 +1229,7 @@ bool LoadExpectedPackagePrefixes(const Options& generation_options,
bool ValidateObjCClassPrefix(
const FileDescriptor* file, const std::string& expected_prefixes_path,
const std::map<std::string, std::string>& expected_package_prefixes,
bool prefixes_must_be_registered, bool require_prefixes,
std::string* out_error) {
// Reminder: An explicit prefix option of "" is valid in case the default
// prefixing is set to use the proto package and a file needs to be generated
@ -1265,6 +1268,12 @@ bool ValidateObjCClassPrefix(
// If there was no prefix option, we're done at this point.
if (!has_prefix) {
if (require_prefixes) {
*out_error =
"error: '" + file->name() + "' does not have a required 'option" +
" objc_class_prefix'.";
return false;
}
return true;
}
@ -1344,9 +1353,18 @@ bool ValidateObjCClassPrefix(
std::cerr.flush();
}
// Check: Warning - If the given package/prefix pair wasn't expected, issue a
// warning suggesting it gets added to the file.
// Check: Error/Warning - If the given package/prefix pair wasn't expected,
// issue a error/warning to added to the file.
if (have_expected_prefix_file) {
if (prefixes_must_be_registered) {
*out_error =
"error: '" + file->name() + "' has 'option objc_class_prefix = \"" +
prefix + "\";', but it is not registered; add it to the expected" +
" prefixes file (" + expected_prefixes_path + ") for the package" +
"'" + package + "'.";
return false;
}
std::cerr
<< "protoc:0: warning: Found unexpected 'option objc_class_prefix = \""
<< prefix << "\";' in '" << file->name() << "';"
@ -1391,6 +1409,8 @@ bool ValidateObjCClassPrefixes(const std::vector<const FileDescriptor*>& files,
ValidateObjCClassPrefix(files[i],
generation_options.expected_prefixes_path,
expected_package_prefixes,
generation_options.prefixes_must_be_registered,
generation_options.require_prefixes,
out_error);
if (!is_valid) {
return false;

@ -67,6 +67,8 @@ struct Options {
std::string generate_for_named_framework;
std::string named_framework_to_proto_path_mappings_path;
std::string runtime_import_prefix;
bool prefixes_must_be_registered;
bool require_prefixes;
};
// Escape C++ trigraphs by escaping question marks to "\?".

Loading…
Cancel
Save