Commit aa1d7e7c authored by Dave MacLachlan's avatar Dave MacLachlan Committed by Thomas Van Lenten

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.
parent 39f42408
......@@ -144,8 +144,8 @@ typedef struct GPBExtensionRange {
} 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;
......@@ -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
......
......@@ -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 @@ typedef struct GPBApi__storage_ {
},
{
.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 @@ typedef struct GPBApi__storage_ {
},
{
.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 @@ typedef struct GPBApi__storage_ {
},
{
.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 @@ typedef struct GPBApi__storage_ {
},
{
.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 @@ typedef struct GPBMethod__storage_ {
},
{
.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),
......
......@@ -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 @@ typedef struct GPBStruct__storage_ {
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 @@ typedef struct GPBValue__storage_ {
},
{
.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 @@ typedef struct GPBValue__storage_ {
},
{
.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 @@ typedef struct GPBListValue__storage_ {
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),
......
......@@ -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 @@ typedef struct GPBType__storage_ {
},
{
.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 @@ typedef struct GPBType__storage_ {
},
{
.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 @@ typedef struct GPBType__storage_ {
},
{
.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 @@ typedef struct GPBField__storage_ {
},
{
.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 @@ typedef struct GPBEnum__storage_ {
},
{
.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 @@ typedef struct GPBEnum__storage_ {
},
{
.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 @@ typedef struct GPBEnum__storage_ {
},
{
.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 @@ typedef struct GPBEnumValue__storage_ {
},
{
.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 @@ typedef struct GPBOption__storage_ {
},
{
.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),
......
......@@ -85,7 +85,7 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization(
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 @@ void ExtensionGenerator::GenerateStaticVariablesInitialization(
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::GenerateStaticVariablesInitialization(
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));
}
}
......
......@@ -432,12 +432,10 @@ void FileGenerator::GenerateSource(io::Printer *printer) {
"\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);
......
......@@ -585,17 +585,12 @@ string OneofNameCapitalized(const OneofDescriptor* descriptor) {
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) {
......
......@@ -120,12 +120,11 @@ string PROTOC_EXPORT OneofNameCapitalized(const OneofDescriptor* descriptor);
// 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;
......
......@@ -177,7 +177,7 @@ void MapFieldGenerator::DetermineObjectiveCClassDefinitions(
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")));
}
}
......
......@@ -254,7 +254,7 @@ void MessageGenerator::DetermineObjectiveCClassDefinitions(std::set<string>* fwd
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 @@ void MessageGenerator::GenerateSource(io::Printer* printer) {
}
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);
......
......@@ -52,8 +52,7 @@ void SetMessageVariables(const FieldDescriptor* descriptor,
(*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::DetermineForwardDeclarations(
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::DetermineForwardDeclarations(
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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment