[protos/objc] Include more context in deprecation messages ⚠️
For deprecated fields, identify the deprecated field and source file in the deprecation message. For deprecated files, identify the deprecated file in deprecation messages of generated interfaces. This additional context in deprecation messages will help provide developers with more context which could help them seek recommended alternatives to deprecated interfaces.
diff --git a/objectivec/GPBBootstrap.h b/objectivec/GPBBootstrap.h
index 9bce683..0ebca25 100644
--- a/objectivec/GPBBootstrap.h
+++ b/objectivec/GPBBootstrap.h
@@ -92,12 +92,23 @@
#endif
/**
- * Attribute used for Objective-C proto interface deprecations.
+ * Attribute used for Objective-C proto interface deprecations without messages.
**/
#ifndef GPB_DEPRECATED
#define GPB_DEPRECATED __attribute__((deprecated))
#endif
+/**
+ * Attribute used for Objective-C proto interface deprecations with messages.
+ **/
+#ifndef GPB_DEPRECATED_MSG
+#if __has_extension(attribute_deprecated_with_message)
+#define GPB_DEPRECATED_MSG(msg) __attribute__((deprecated(msg)))
+#else
+#define GPB_DEPRECATED_MSG(msg) __attribute__((deprecated))
+#endif
+#endif
+
// If property name starts with init we need to annotate it to get past ARC.
// http://stackoverflow.com/questions/18723226/how-do-i-annotate-an-objective-c-property-with-an-objc-method-family/18723227#18723227
//
diff --git a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
index ed7b417..e2f7024 100644
--- a/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
+++ b/src/google/protobuf/compiler/objectivec/objectivec_helpers.h
@@ -163,11 +163,22 @@
// The file is only passed when checking Messages & Enums, so those types
// get tagged. At the moment, it doesn't seem to make sense to tag every
// field or enum value with when the file is deprecated.
+ bool isFileLevelDeprecation = false;
if (!isDeprecated && file) {
- isDeprecated = file->options().deprecated();
+ isFileLevelDeprecation = file->options().deprecated();
+ isDeprecated = isFileLevelDeprecation;
}
if (isDeprecated) {
- string result = "GPB_DEPRECATED";
+ string message;
+ const FileDescriptor* sourceFile = descriptor->file();
+ if (isFileLevelDeprecation) {
+ message = sourceFile->name() + " is deprecated.";
+ } else {
+ message = descriptor->full_name() + " is deprecated (see " +
+ sourceFile->name() + ").";
+ }
+
+ string result = string("GPB_DEPRECATED_MSG(\"") + message + "\")";
if (preSpace) {
result.insert(0, " ");
}