Change Objective C class references to using macros.
Allows easy replacing of class names in generated code using #define to redefine class names at compile time.
diff --git a/objectivec/GPBRuntimeTypes.h b/objectivec/GPBRuntimeTypes.h
index b269f1d..9c1083a 100644
--- a/objectivec/GPBRuntimeTypes.h
+++ b/objectivec/GPBRuntimeTypes.h
@@ -144,8 +144,8 @@
} GPBExtensionRange;
/**
- A type to represent a reference to an Objective C class.
+ A type to represent an Objective C class.
This is actually an `objc_class` but the runtime headers will not allow us to
- reference `objc_class`.
+ reference `objc_class`, so we have defined our own.
*/
-typedef struct GPBObjcClassReference GPBObjcClassReference;
+typedef struct GPBObjcClass_t GPBObjcClass_t;
diff --git a/objectivec/GPBUtilities_PackagePrivate.h b/objectivec/GPBUtilities_PackagePrivate.h
index 336a745..80d423d 100644
--- a/objectivec/GPBUtilities_PackagePrivate.h
+++ b/objectivec/GPBUtilities_PackagePrivate.h
@@ -35,14 +35,23 @@
#import "GPBDescriptor_PackagePrivate.h"
// Macros for stringifying library symbols. These are used in the generated
-// PB descriptor classes wherever a library symbol name is represented as a
-// string. See README.google for more information.
+// GPB descriptor classes wherever a library symbol name is represented as a
+// string.
#define GPBStringify(S) #S
#define GPBStringifySymbol(S) GPBStringify(S)
#define GPBNSStringify(S) @#S
#define GPBNSStringifySymbol(S) GPBNSStringify(S)
+// Macros for generating a Class from a class name. These are used in
+// the generated GPB descriptor classes wherever an Objective C class
+// reference is needed for a generated class.
+#define GPBObjCClassSymbol(name) OBJC_CLASS_$_##name
+#define GPBObjCClass(name) \
+ ((__bridge Class)&(GPBObjCClassSymbol(name)))
+#define GPBObjCClassDeclaration(name) \
+ extern const GPBObjcClass_t GPBObjCClassSymbol(name)
+
// Constant to internally mark when there is no has bit.
#define GPBNoHasBit INT32_MAX
diff --git a/objectivec/google/protobuf/Api.pbobjc.m b/objectivec/google/protobuf/Api.pbobjc.m
index 1463f0d..b9d644e 100644
--- a/objectivec/google/protobuf/Api.pbobjc.m
+++ b/objectivec/google/protobuf/Api.pbobjc.m
@@ -28,16 +28,14 @@
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#pragma clang diagnostic ignored "-Wdollar-in-identifier-extension"
-#pragma mark - Objective C Class references
-// This somewhat arcane code forces linkage of classes from static archives by
-// adding a concrete reference to the classes.
-// We don't use `[Foo class]` because we need a static value for our initializer.
-// This also has the added benefit of reducing size in that we don't have to
-// encode the class names and look them up at runtime.
-extern const GPBObjcClassReference OBJC_CLASS_$_GPBMethod;
-extern const GPBObjcClassReference OBJC_CLASS_$_GPBMixin;
-extern const GPBObjcClassReference OBJC_CLASS_$_GPBOption;
-extern const GPBObjcClassReference OBJC_CLASS_$_GPBSourceContext;
+#pragma mark - Objective C Class declarations
+// Forward declarations of Objective C classes that we can use as
+// static values in struct initializers.
+// We don't use [Foo class] because it is not a static value.
+GPBObjCClassDeclaration(GPBMethod);
+GPBObjCClassDeclaration(GPBMixin);
+GPBObjCClassDeclaration(GPBOption);
+GPBObjCClassDeclaration(GPBSourceContext);
#pragma mark - GPBApiRoot
@@ -103,7 +101,7 @@
},
{
.name = "methodsArray",
- .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBMethod),
+ .dataTypeSpecific.clazz = GPBObjCClass(GPBMethod),
.number = GPBApi_FieldNumber_MethodsArray,
.hasIndex = GPBNoHasBit,
.offset = (uint32_t)offsetof(GPBApi__storage_, methodsArray),
@@ -112,7 +110,7 @@
},
{
.name = "optionsArray",
- .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBOption),
+ .dataTypeSpecific.clazz = GPBObjCClass(GPBOption),
.number = GPBApi_FieldNumber_OptionsArray,
.hasIndex = GPBNoHasBit,
.offset = (uint32_t)offsetof(GPBApi__storage_, optionsArray),
@@ -130,7 +128,7 @@
},
{
.name = "sourceContext",
- .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBSourceContext),
+ .dataTypeSpecific.clazz = GPBObjCClass(GPBSourceContext),
.number = GPBApi_FieldNumber_SourceContext,
.hasIndex = 2,
.offset = (uint32_t)offsetof(GPBApi__storage_, sourceContext),
@@ -139,7 +137,7 @@
},
{
.name = "mixinsArray",
- .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBMixin),
+ .dataTypeSpecific.clazz = GPBObjCClass(GPBMixin),
.number = GPBApi_FieldNumber_MixinsArray,
.hasIndex = GPBNoHasBit,
.offset = (uint32_t)offsetof(GPBApi__storage_, mixinsArray),
@@ -260,7 +258,7 @@
},
{
.name = "optionsArray",
- .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBOption),
+ .dataTypeSpecific.clazz = GPBObjCClass(GPBOption),
.number = GPBMethod_FieldNumber_OptionsArray,
.hasIndex = GPBNoHasBit,
.offset = (uint32_t)offsetof(GPBMethod__storage_, optionsArray),
diff --git a/objectivec/google/protobuf/Struct.pbobjc.m b/objectivec/google/protobuf/Struct.pbobjc.m
index e8e181b..d36be9c 100644
--- a/objectivec/google/protobuf/Struct.pbobjc.m
+++ b/objectivec/google/protobuf/Struct.pbobjc.m
@@ -27,15 +27,13 @@
#pragma clang diagnostic ignored "-Wdirect-ivar-access"
#pragma clang diagnostic ignored "-Wdollar-in-identifier-extension"
-#pragma mark - Objective C Class references
-// This somewhat arcane code forces linkage of classes from static archives by
-// adding a concrete reference to the classes.
-// We don't use `[Foo class]` because we need a static value for our initializer.
-// This also has the added benefit of reducing size in that we don't have to
-// encode the class names and look them up at runtime.
-extern const GPBObjcClassReference OBJC_CLASS_$_GPBListValue;
-extern const GPBObjcClassReference OBJC_CLASS_$_GPBStruct;
-extern const GPBObjcClassReference OBJC_CLASS_$_GPBValue;
+#pragma mark - Objective C Class declarations
+// Forward declarations of Objective C classes that we can use as
+// static values in struct initializers.
+// We don't use [Foo class] because it is not a static value.
+GPBObjCClassDeclaration(GPBListValue);
+GPBObjCClassDeclaration(GPBStruct);
+GPBObjCClassDeclaration(GPBValue);
#pragma mark - GPBStructRoot
@@ -113,7 +111,7 @@
static GPBMessageFieldDescription fields[] = {
{
.name = "fields",
- .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBValue),
+ .dataTypeSpecific.clazz = GPBObjCClass(GPBValue),
.number = GPBStruct_FieldNumber_Fields,
.hasIndex = GPBNoHasBit,
.offset = (uint32_t)offsetof(GPBStruct__storage_, fields),
@@ -204,7 +202,7 @@
},
{
.name = "structValue",
- .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBStruct),
+ .dataTypeSpecific.clazz = GPBObjCClass(GPBStruct),
.number = GPBValue_FieldNumber_StructValue,
.hasIndex = -1,
.offset = (uint32_t)offsetof(GPBValue__storage_, structValue),
@@ -213,7 +211,7 @@
},
{
.name = "listValue",
- .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBListValue),
+ .dataTypeSpecific.clazz = GPBObjCClass(GPBListValue),
.number = GPBValue_FieldNumber_ListValue,
.hasIndex = -1,
.offset = (uint32_t)offsetof(GPBValue__storage_, listValue),
@@ -281,7 +279,7 @@
static GPBMessageFieldDescription fields[] = {
{
.name = "valuesArray",
- .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBValue),
+ .dataTypeSpecific.clazz = GPBObjCClass(GPBValue),
.number = GPBListValue_FieldNumber_ValuesArray,
.hasIndex = GPBNoHasBit,
.offset = (uint32_t)offsetof(GPBListValue__storage_, valuesArray),
diff --git a/objectivec/google/protobuf/Type.pbobjc.m b/objectivec/google/protobuf/Type.pbobjc.m
index 0c48e6b..da04392 100644
--- a/objectivec/google/protobuf/Type.pbobjc.m
+++ b/objectivec/google/protobuf/Type.pbobjc.m
@@ -30,17 +30,15 @@
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#pragma clang diagnostic ignored "-Wdollar-in-identifier-extension"
-#pragma mark - Objective C Class references
-// This somewhat arcane code forces linkage of classes from static archives by
-// adding a concrete reference to the classes.
-// We don't use `[Foo class]` because we need a static value for our initializer.
-// This also has the added benefit of reducing size in that we don't have to
-// encode the class names and look them up at runtime.
-extern const GPBObjcClassReference OBJC_CLASS_$_GPBAny;
-extern const GPBObjcClassReference OBJC_CLASS_$_GPBEnumValue;
-extern const GPBObjcClassReference OBJC_CLASS_$_GPBField;
-extern const GPBObjcClassReference OBJC_CLASS_$_GPBOption;
-extern const GPBObjcClassReference OBJC_CLASS_$_GPBSourceContext;
+#pragma mark - Objective C Class declarations
+// Forward declarations of Objective C classes that we can use as
+// static values in struct initializers.
+// We don't use [Foo class] because it is not a static value.
+GPBObjCClassDeclaration(GPBAny);
+GPBObjCClassDeclaration(GPBEnumValue);
+GPBObjCClassDeclaration(GPBField);
+GPBObjCClassDeclaration(GPBOption);
+GPBObjCClassDeclaration(GPBSourceContext);
#pragma mark - GPBTypeRoot
@@ -139,7 +137,7 @@
},
{
.name = "fieldsArray",
- .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBField),
+ .dataTypeSpecific.clazz = GPBObjCClass(GPBField),
.number = GPBType_FieldNumber_FieldsArray,
.hasIndex = GPBNoHasBit,
.offset = (uint32_t)offsetof(GPBType__storage_, fieldsArray),
@@ -157,7 +155,7 @@
},
{
.name = "optionsArray",
- .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBOption),
+ .dataTypeSpecific.clazz = GPBObjCClass(GPBOption),
.number = GPBType_FieldNumber_OptionsArray,
.hasIndex = GPBNoHasBit,
.offset = (uint32_t)offsetof(GPBType__storage_, optionsArray),
@@ -166,7 +164,7 @@
},
{
.name = "sourceContext",
- .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBSourceContext),
+ .dataTypeSpecific.clazz = GPBObjCClass(GPBSourceContext),
.number = GPBType_FieldNumber_SourceContext,
.hasIndex = 1,
.offset = (uint32_t)offsetof(GPBType__storage_, sourceContext),
@@ -312,7 +310,7 @@
},
{
.name = "optionsArray",
- .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBOption),
+ .dataTypeSpecific.clazz = GPBObjCClass(GPBOption),
.number = GPBField_FieldNumber_OptionsArray,
.hasIndex = GPBNoHasBit,
.offset = (uint32_t)offsetof(GPBField__storage_, optionsArray),
@@ -535,7 +533,7 @@
},
{
.name = "enumvalueArray",
- .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBEnumValue),
+ .dataTypeSpecific.clazz = GPBObjCClass(GPBEnumValue),
.number = GPBEnum_FieldNumber_EnumvalueArray,
.hasIndex = GPBNoHasBit,
.offset = (uint32_t)offsetof(GPBEnum__storage_, enumvalueArray),
@@ -544,7 +542,7 @@
},
{
.name = "optionsArray",
- .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBOption),
+ .dataTypeSpecific.clazz = GPBObjCClass(GPBOption),
.number = GPBEnum_FieldNumber_OptionsArray,
.hasIndex = GPBNoHasBit,
.offset = (uint32_t)offsetof(GPBEnum__storage_, optionsArray),
@@ -553,7 +551,7 @@
},
{
.name = "sourceContext",
- .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBSourceContext),
+ .dataTypeSpecific.clazz = GPBObjCClass(GPBSourceContext),
.number = GPBEnum_FieldNumber_SourceContext,
.hasIndex = 1,
.offset = (uint32_t)offsetof(GPBEnum__storage_, sourceContext),
@@ -641,7 +639,7 @@
},
{
.name = "optionsArray",
- .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBOption),
+ .dataTypeSpecific.clazz = GPBObjCClass(GPBOption),
.number = GPBEnumValue_FieldNumber_OptionsArray,
.hasIndex = GPBNoHasBit,
.offset = (uint32_t)offsetof(GPBEnumValue__storage_, optionsArray),
@@ -697,7 +695,7 @@
},
{
.name = "value",
- .dataTypeSpecific.clazz = ((__bridge Class)&OBJC_CLASS_$_GPBAny),
+ .dataTypeSpecific.clazz = GPBObjCClass(GPBAny),
.number = GPBOption_FieldNumber_Value,
.hasIndex = 1,
.offset = (uint32_t)offsetof(GPBOption__storage_, value),
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_extension.cc b/src/google/protobuf/compiler/objectivec/objectivec_extension.cc
index a67d1a2..b514b8a 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_extension.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_extension.cc
@@ -85,7 +85,7 @@
std::map<string, string> vars;
vars["root_class_and_method_name"] = root_class_and_method_name_;
const string containing_type = ClassName(descriptor_->containing_type());
- vars["extended_type"] = ObjCClassSymbolReference(containing_type);
+ vars["extended_type"] = ObjCClass(containing_type);
vars["number"] = StrCat(descriptor_->number());
std::vector<string> options;
@@ -99,7 +99,7 @@
ObjectiveCType objc_type = GetObjectiveCType(descriptor_);
if (objc_type == OBJECTIVECTYPE_MESSAGE) {
std::string message_type = ClassName(descriptor_->message_type());
- vars["type"] = ObjCClassSymbolReference(message_type);
+ vars["type"] = ObjCClass(message_type);
} else {
vars["type"] = "Nil";
}
@@ -136,11 +136,11 @@
void ExtensionGenerator::DetermineObjectiveCClassDefinitions(
std::set<string>* fwd_decls) {
string extended_type = ClassName(descriptor_->containing_type());
- fwd_decls->insert(ObjCClassSymbolDefinition(extended_type));
+ fwd_decls->insert(ObjCClassDeclaration(extended_type));
ObjectiveCType objc_type = GetObjectiveCType(descriptor_);
if (objc_type == OBJECTIVECTYPE_MESSAGE) {
string message_type = ClassName(descriptor_->message_type());
- fwd_decls->insert(ObjCClassSymbolDefinition(message_type));
+ fwd_decls->insert(ObjCClassDeclaration(message_type));
}
}
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.cc b/src/google/protobuf/compiler/objectivec/objectivec_file.cc
index c05a77d..e90b22b 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_file.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_file.cc
@@ -432,12 +432,10 @@
"\n");
if (!fwd_decls.empty()) {
printer->Print(
- "#pragma mark - Objective C Class references\n"
- "// This somewhat arcane code forces linkage of classes from static archives by\n"
- "// adding a concrete reference to the classes.\n"
- "// We don't use `[Foo class]` because we need a static value for our initializer.\n"
- "// This also has the added benefit of reducing size in that we don't have to\n"
- "// encode the class names and look them up at runtime.\n");
+ "#pragma mark - Objective C Class declarations\n"
+ "// Forward declarations of Objective C classes that we can use as\n"
+ "// static values in struct initializers.\n"
+ "// We don't use [Foo class] because it is not a static value.\n");
}
for (const auto& i : fwd_decls) {
printer->Print("$value$\n", "value", i);
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
index 97bc75b..7541898 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.cc
@@ -585,17 +585,12 @@
return result;
}
-static string ObjCClassSymbolName(const string& class_name) {
- return string("OBJC_CLASS_$_") + class_name;
+string ObjCClass(const string& class_name) {
+ return string("GPBObjCClass(") + class_name + ")";
}
-string ObjCClassSymbolReference(const string& class_name) {
- return "((__bridge Class)&" + ObjCClassSymbolName(class_name) + ")";
-}
-
-string ObjCClassSymbolDefinition(const string& class_name) {
- const string &ref = ObjCClassSymbolName(class_name);
- return "extern const GPBObjcClassReference " + ref + ";";
+string ObjCClassDeclaration(const string& class_name) {
+ return string("GPBObjCClassDeclaration(") + class_name + ");";
}
string UnCamelCaseFieldName(const string& name, const FieldDescriptor* field) {
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
index b170d98..c6a2c77 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
@@ -120,12 +120,11 @@
// Returns a symbol that can be used in C code to refer to an Objective C
// class without initializing the class.
-string PROTOC_EXPORT ObjCClassSymbolReference(const string& class_name);
+string PROTOC_EXPORT ObjCClass(const string& class_name);
-// Defines a symbol that can be used in C code to refer to an Objective C
-// class without initializing the class. Use a corresponding
-// ObjCClassSymbolReference to reference it.
-string PROTOC_EXPORT ObjCClassSymbolDefinition(const string& class_name);
+// Declares an Objective C class without initializing the class so that it can
+// be refrerred to by ObjCClass.
+string PROTOC_EXPORT ObjCClassDeclaration(const string& class_name);
inline bool HasFieldPresence(const FileDescriptor* file) {
return file->syntax() != FileDescriptor::SYNTAX_PROTO3;
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc
index 55e5bf9..3b8eaa0 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_map_field.cc
@@ -177,7 +177,7 @@
const FieldDescriptor* value_descriptor =
descriptor_->message_type()->FindFieldByName("value");
if (GetObjectiveCType(value_descriptor) == OBJECTIVECTYPE_MESSAGE) {
- fwd_decls->insert(ObjCClassSymbolDefinition(
+ fwd_decls->insert(ObjCClassDeclaration(
value_field_generator_->variable("storage_type")));
}
}
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message.cc b/src/google/protobuf/compiler/objectivec/objectivec_message.cc
index af13c14..2a0e402 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_message.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_message.cc
@@ -254,7 +254,7 @@
const Descriptor* containing_descriptor = descriptor_->containing_type();
if (containing_descriptor != NULL) {
string containing_class = ClassName(containing_descriptor);
- fwd_decls->insert(ObjCClassSymbolDefinition(containing_class));
+ fwd_decls->insert(ObjCClassDeclaration(containing_class));
}
}
@@ -582,7 +582,7 @@
}
if (descriptor_->containing_type() != NULL) {
string containing_class = ClassName(descriptor_->containing_type());
- string parent_class_ref = ObjCClassSymbolReference(containing_class);
+ string parent_class_ref = ObjCClass(containing_class);
printer->Print(
" [localDescriptor setupContainingMessageClass:$parent_class_ref$];\n",
"parent_class_ref", parent_class_ref);
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc b/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc
index 93b7557..2730e75 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc
+++ b/src/google/protobuf/compiler/objectivec/objectivec_message_field.cc
@@ -52,8 +52,7 @@
(*variables)["storage_type"] = message_type;
(*variables)["group_or_message"] =
(descriptor->type() == FieldDescriptor::TYPE_GROUP) ? "Group" : "Message";
- (*variables)["dataTypeSpecific_value"] =
- ObjCClassSymbolReference(message_type);
+ (*variables)["dataTypeSpecific_value"] = ObjCClass(message_type);
}
} // namespace
@@ -75,7 +74,7 @@
void MessageFieldGenerator::DetermineObjectiveCClassDefinitions(
std::set<string>* fwd_decls) const {
- fwd_decls->insert(ObjCClassSymbolDefinition(variable("storage_type")));
+ fwd_decls->insert(ObjCClassDeclaration(variable("storage_type")));
}
bool MessageFieldGenerator::WantsHasProperty(void) const {
@@ -108,7 +107,7 @@
void RepeatedMessageFieldGenerator::DetermineObjectiveCClassDefinitions(
std::set<string>* fwd_decls) const {
- fwd_decls->insert(ObjCClassSymbolDefinition(variable("storage_type")));
+ fwd_decls->insert(ObjCClassDeclaration(variable("storage_type")));
}
} // namespace objectivec