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