objective-c: Add `objc_class_prefix` generation option.

pull/9105/head
Dimitris Koutsogiorgas 3 years ago committed by Thomas Van Lenten
parent 9ebb31726c
commit b5ab0b7a18
  1. 10
      objectivec/README.md
  2. 14
      src/google/protobuf/compiler/objectivec/objectivec_generator.cc
  3. 17
      src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
  4. 4
      src/google/protobuf/compiler/objectivec/objectivec_helpers.h

@ -133,8 +133,8 @@ This options allow you to provide a custom prefix for all the symbols generated
from a proto file (classes (from message), enums, the Root for extension
support).
If not set, the generation option `use_package_as_prefix` (documented below)
controls what is used instead. Since Objective C uses a global namespace for all
If not set, the generation options `default_objc_class_prefix` and `use_package_as_prefix`
(documented below) control what is used instead. Since Objective C uses a global namespace for all
of its classes, there can be collisions. `use_package_as_prefix=yes` should
avoid collisions since proto package are used to scope/name things in other
languages, but this option can be used to get shorter names instead. Convention
@ -182,6 +182,12 @@ supported keys are:
having to add the runtime directory to the header search path since the
generate `#import` will be more complete.
* `default_objc_class_prefix`: The default ObjC prefix value to use when
generating sources. The generator will use this if the `objc_class_prefix`
file option is not set. This option can be useful if multiple iOS apps
consume the same proto file but wish to use a different prefix for their
generated sources.
* `use_package_as_prefix` and `proto_package_prefix_exceptions_path`: The
`value` for `use_package_as_prefix` can be `yes` or `no`, and indicates
if a prefix should be derived from the proto package for all the symbols

@ -190,10 +190,20 @@ bool ObjectiveCGenerator::GenerateAll(
// header search path since the generate #import will be more complete.
generation_options.runtime_import_prefix =
StripSuffixString(options[i].second, "/");
} else if (options[i].first == "default_objc_class_prefix") {
// The default objc class prefix to use if specified by the command line
// invocation. The file option is always honored first if one is present.
std::string value = options[i].second;
if (value.empty()) {
*error = "error: default_objc_class_prefix cannot be empty.";
return false;
}
SetDefaultObjcClassPrefix(value);
} else if (options[i].first == "use_package_as_prefix") {
// Controls how the symbols should be prefixed to avoid symbols
// collisions. The objc_class_prefix file option is always honored, this
// is just what to do if that isn't set. The available options are:
// collisions. The objc_class_prefix file option is always honored first
// followed by the default_objc_class_prefix generator option. This is is just
// what to do if either of these options are not set. The available options are:
// "no": Not prefixed (the existing mode).
// "yes": Make a prefix out of the proto package.
bool value = false;

@ -99,6 +99,9 @@ class PrefixModeStorage {
public:
PrefixModeStorage();
const std::string default_objc_class_prefix() const { return default_objc_class_prefix_; }
void set_default_objc_class_prefix(const std::string& default_objc_class_prefix) { default_objc_class_prefix_ = default_objc_class_prefix; }
bool use_package_name() const { return use_package_name_; }
void set_use_package_name(bool on_or_off) { use_package_name_ = on_or_off; }
@ -116,13 +119,14 @@ class PrefixModeStorage {
private:
bool use_package_name_;
std::string default_objc_class_prefix_;
std::string exception_path_;
std::string forced_prefix_;
std::unordered_set<std::string> exceptions_;
};
PrefixModeStorage::PrefixModeStorage() {
// Even thought there are generation options, have an env back door since some
// Even though there are generation options, have an env back door since some
// of these helpers could be used in other plugins.
use_package_name_ = BoolFromEnvVar("GPB_OBJC_USE_PACKAGE_AS_PREFIX", false);
@ -169,6 +173,10 @@ PrefixModeStorage g_prefix_mode;
} // namespace
void SetDefaultObjcClassPrefix(const std::string& default_objc_class_prefix) {
g_prefix_mode.set_default_objc_class_prefix(default_objc_class_prefix);
}
bool UseProtoPackageAsDefaultPrefix() {
return g_prefix_mode.use_package_name();
}
@ -526,11 +534,16 @@ std::string BaseFileName(const FileDescriptor* file) {
}
std::string FileClassPrefix(const FileDescriptor* file) {
// Always honor the file option.
// Always honor the file option first.
if (file->options().has_objc_class_prefix()) {
return file->options().objc_class_prefix();
}
// If a default prefix is passed through objc_opt then accept it.
if (!g_prefix_mode.default_objc_class_prefix().empty()) {
return g_prefix_mode.default_objc_class_prefix();
}
// If package prefix isn't enabled, done.
if (!g_prefix_mode.use_package_name()) {
return "";

@ -47,6 +47,9 @@ namespace protobuf {
namespace compiler {
namespace objectivec {
// Set the default objc class prefix that should be used. This method is used only
// when default_objc_class_prefix is passed through objc_opt.
void PROTOC_EXPORT SetDefaultObjcClassPrefix(const std::string& objc_class_prefix);
// Get/Set if the proto package should be used to make the default prefix for
// symbols. This will then impact most of the type naming apis below. It is done
// as a global to not break any other generator reusing the methods since they
@ -68,6 +71,7 @@ struct Options {
std::string generate_for_named_framework;
std::string named_framework_to_proto_path_mappings_path;
std::string runtime_import_prefix;
std::string default_objc_class_prefix;
bool prefixes_must_be_registered;
bool require_prefixes;
};

Loading…
Cancel
Save