From 9f6c88cfd83d3663fe67b5a1da449fa76f05743b Mon Sep 17 00:00:00 2001 From: Dave MacLachlan Date: Wed, 22 Jan 2020 10:16:21 -0800 Subject: [PATCH] Block subclassing Add GPB_FINAL macro to block subclassing of generated ObjC classes. --- objectivec/GPBBootstrap.h | 5 +++++ objectivec/Tests/GPBMessageTests+ClassNames.m | 4 ++-- objectivec/google/protobuf/Any.pbobjc.h | 4 ++-- objectivec/google/protobuf/Api.pbobjc.h | 8 ++++---- objectivec/google/protobuf/Duration.pbobjc.h | 4 ++-- objectivec/google/protobuf/Empty.pbobjc.h | 4 ++-- objectivec/google/protobuf/FieldMask.pbobjc.h | 4 ++-- .../google/protobuf/SourceContext.pbobjc.h | 4 ++-- objectivec/google/protobuf/Struct.pbobjc.h | 8 ++++---- objectivec/google/protobuf/Timestamp.pbobjc.h | 4 ++-- objectivec/google/protobuf/Type.pbobjc.h | 12 +++++------ objectivec/google/protobuf/Wrappers.pbobjc.h | 20 +++++++++---------- .../compiler/objectivec/objectivec_file.cc | 2 +- .../compiler/objectivec/objectivec_message.cc | 2 +- 14 files changed, 45 insertions(+), 40 deletions(-) diff --git a/objectivec/GPBBootstrap.h b/objectivec/GPBBootstrap.h index a62621707b30..057644bb12e5 100644 --- a/objectivec/GPBBootstrap.h +++ b/objectivec/GPBBootstrap.h @@ -115,6 +115,11 @@ // Meant to be used internally by generated code. #define GPB_METHOD_FAMILY_NONE __attribute__((objc_method_family(none))) +// Prevent subclassing of generated proto classes. +#ifndef GPB_FINAL +#define GPB_FINAL __attribute__((objc_subclassing_restricted)) +#endif // GPB_FINAL + // ---------------------------------------------------------------------------- // These version numbers are all internal to the ObjC Protobuf runtime; they // are used to ensure compatibility between the generated sources and the diff --git a/objectivec/Tests/GPBMessageTests+ClassNames.m b/objectivec/Tests/GPBMessageTests+ClassNames.m index 31d15b534a76..b5a5c51d043c 100644 --- a/objectivec/Tests/GPBMessageTests+ClassNames.m +++ b/objectivec/Tests/GPBMessageTests+ClassNames.m @@ -38,14 +38,14 @@ #import "GPBRootObject_PackagePrivate.h" // Support classes for tests using old class name (vs classrefs) interfaces. -@interface MessageLackingClazzRoot : GPBRootObject +GPB_FINAL @interface MessageLackingClazzRoot : GPBRootObject @end @interface MessageLackingClazzRoot (DynamicMethods) + (GPBExtensionDescriptor *)ext1; @end -@interface MessageLackingClazz : GPBMessage +GPB_FINAL @interface MessageLackingClazz : GPBMessage @property(copy, nonatomic) NSString *foo; @end diff --git a/objectivec/google/protobuf/Any.pbobjc.h b/objectivec/google/protobuf/Any.pbobjc.h index f22c8c5d8efe..26cf5ab2977a 100644 --- a/objectivec/google/protobuf/Any.pbobjc.h +++ b/objectivec/google/protobuf/Any.pbobjc.h @@ -45,7 +45,7 @@ NS_ASSUME_NONNULL_BEGIN * which is a @c GPBExtensionRegistry that includes all the extensions defined by * this file and all files that it depends on. **/ -@interface GPBAnyRoot : GPBRootObject +GPB_FINAL @interface GPBAnyRoot : GPBRootObject @end #pragma mark - GPBAny @@ -136,7 +136,7 @@ typedef GPB_ENUM(GPBAny_FieldNumber) { * "value": "1.212s" * } **/ -@interface GPBAny : GPBMessage +GPB_FINAL @interface GPBAny : GPBMessage /** * A URL/resource name that uniquely identifies the type of the serialized diff --git a/objectivec/google/protobuf/Api.pbobjc.h b/objectivec/google/protobuf/Api.pbobjc.h index 99acd04dd930..044d8c9385b3 100644 --- a/objectivec/google/protobuf/Api.pbobjc.h +++ b/objectivec/google/protobuf/Api.pbobjc.h @@ -51,7 +51,7 @@ NS_ASSUME_NONNULL_BEGIN * which is a @c GPBExtensionRegistry that includes all the extensions defined by * this file and all files that it depends on. **/ -@interface GPBApiRoot : GPBRootObject +GPB_FINAL @interface GPBApiRoot : GPBRootObject @end #pragma mark - GPBApi @@ -77,7 +77,7 @@ typedef GPB_ENUM(GPBApi_FieldNumber) { * this message itself. See https://cloud.google.com/apis/design/glossary for * detailed terminology. **/ -@interface GPBApi : GPBMessage +GPB_FINAL @interface GPBApi : GPBMessage /** * The fully qualified name of this interface, including package name @@ -163,7 +163,7 @@ typedef GPB_ENUM(GPBMethod_FieldNumber) { /** * Method represents a method of an API interface. **/ -@interface GPBMethod : GPBMessage +GPB_FINAL @interface GPBMethod : GPBMessage /** The simple name of this method. */ @property(nonatomic, readwrite, copy, null_resettable) NSString *name; @@ -289,7 +289,7 @@ typedef GPB_ENUM(GPBMixin_FieldNumber) { * ... * } **/ -@interface GPBMixin : GPBMessage +GPB_FINAL @interface GPBMixin : GPBMessage /** The fully qualified name of the interface which is included. */ @property(nonatomic, readwrite, copy, null_resettable) NSString *name; diff --git a/objectivec/google/protobuf/Duration.pbobjc.h b/objectivec/google/protobuf/Duration.pbobjc.h index 111a91042c26..8ef4151bd62d 100644 --- a/objectivec/google/protobuf/Duration.pbobjc.h +++ b/objectivec/google/protobuf/Duration.pbobjc.h @@ -45,7 +45,7 @@ NS_ASSUME_NONNULL_BEGIN * which is a @c GPBExtensionRegistry that includes all the extensions defined by * this file and all files that it depends on. **/ -@interface GPBDurationRoot : GPBRootObject +GPB_FINAL @interface GPBDurationRoot : GPBRootObject @end #pragma mark - GPBDuration @@ -115,7 +115,7 @@ typedef GPB_ENUM(GPBDuration_FieldNumber) { * be expressed in JSON format as "3.000000001s", and 3 seconds and 1 * microsecond should be expressed in JSON format as "3.000001s". **/ -@interface GPBDuration : GPBMessage +GPB_FINAL @interface GPBDuration : GPBMessage /** * Signed seconds of the span of time. Must be from -315,576,000,000 diff --git a/objectivec/google/protobuf/Empty.pbobjc.h b/objectivec/google/protobuf/Empty.pbobjc.h index 5b1e7b4b678d..8642446909dc 100644 --- a/objectivec/google/protobuf/Empty.pbobjc.h +++ b/objectivec/google/protobuf/Empty.pbobjc.h @@ -45,7 +45,7 @@ NS_ASSUME_NONNULL_BEGIN * which is a @c GPBExtensionRegistry that includes all the extensions defined by * this file and all files that it depends on. **/ -@interface GPBEmptyRoot : GPBRootObject +GPB_FINAL @interface GPBEmptyRoot : GPBRootObject @end #pragma mark - GPBEmpty @@ -61,7 +61,7 @@ NS_ASSUME_NONNULL_BEGIN * * The JSON representation for `Empty` is empty JSON object `{}`. **/ -@interface GPBEmpty : GPBMessage +GPB_FINAL @interface GPBEmpty : GPBMessage @end diff --git a/objectivec/google/protobuf/FieldMask.pbobjc.h b/objectivec/google/protobuf/FieldMask.pbobjc.h index 92d504229a47..3ba932c2e32c 100644 --- a/objectivec/google/protobuf/FieldMask.pbobjc.h +++ b/objectivec/google/protobuf/FieldMask.pbobjc.h @@ -45,7 +45,7 @@ NS_ASSUME_NONNULL_BEGIN * which is a @c GPBExtensionRegistry that includes all the extensions defined by * this file and all files that it depends on. **/ -@interface GPBFieldMaskRoot : GPBRootObject +GPB_FINAL @interface GPBFieldMaskRoot : GPBRootObject @end #pragma mark - GPBFieldMask @@ -255,7 +255,7 @@ typedef GPB_ENUM(GPBFieldMask_FieldNumber) { * request should verify the included field paths, and return an * `INVALID_ARGUMENT` error if any path is unmappable. **/ -@interface GPBFieldMask : GPBMessage +GPB_FINAL @interface GPBFieldMask : GPBMessage /** The set of field mask paths. */ @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *pathsArray; diff --git a/objectivec/google/protobuf/SourceContext.pbobjc.h b/objectivec/google/protobuf/SourceContext.pbobjc.h index b2cdbba3c6c4..d34b8ffaf26e 100644 --- a/objectivec/google/protobuf/SourceContext.pbobjc.h +++ b/objectivec/google/protobuf/SourceContext.pbobjc.h @@ -45,7 +45,7 @@ NS_ASSUME_NONNULL_BEGIN * which is a @c GPBExtensionRegistry that includes all the extensions defined by * this file and all files that it depends on. **/ -@interface GPBSourceContextRoot : GPBRootObject +GPB_FINAL @interface GPBSourceContextRoot : GPBRootObject @end #pragma mark - GPBSourceContext @@ -58,7 +58,7 @@ typedef GPB_ENUM(GPBSourceContext_FieldNumber) { * `SourceContext` represents information about the source of a * protobuf element, like the file in which it is defined. **/ -@interface GPBSourceContext : GPBMessage +GPB_FINAL @interface GPBSourceContext : GPBMessage /** * The path-qualified name of the .proto file that contained the associated diff --git a/objectivec/google/protobuf/Struct.pbobjc.h b/objectivec/google/protobuf/Struct.pbobjc.h index 8a06de4d54d3..0584e6236770 100644 --- a/objectivec/google/protobuf/Struct.pbobjc.h +++ b/objectivec/google/protobuf/Struct.pbobjc.h @@ -76,7 +76,7 @@ BOOL GPBNullValue_IsValidValue(int32_t value); * which is a @c GPBExtensionRegistry that includes all the extensions defined by * this file and all files that it depends on. **/ -@interface GPBStructRoot : GPBRootObject +GPB_FINAL @interface GPBStructRoot : GPBRootObject @end #pragma mark - GPBStruct @@ -95,7 +95,7 @@ typedef GPB_ENUM(GPBStruct_FieldNumber) { * * The JSON representation for `Struct` is JSON object. **/ -@interface GPBStruct : GPBMessage +GPB_FINAL @interface GPBStruct : GPBMessage /** Unordered map of dynamically typed values. */ @property(nonatomic, readwrite, strong, null_resettable) NSMutableDictionary *fields; @@ -133,7 +133,7 @@ typedef GPB_ENUM(GPBValue_Kind_OneOfCase) { * * The JSON representation for `Value` is JSON value. **/ -@interface GPBValue : GPBMessage +GPB_FINAL @interface GPBValue : GPBMessage /** The kind of value. */ @property(nonatomic, readonly) GPBValue_Kind_OneOfCase kindOneOfCase; @@ -186,7 +186,7 @@ typedef GPB_ENUM(GPBListValue_FieldNumber) { * * The JSON representation for `ListValue` is JSON array. **/ -@interface GPBListValue : GPBMessage +GPB_FINAL @interface GPBListValue : GPBMessage /** Repeated field of dynamically typed values. */ @property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *valuesArray; diff --git a/objectivec/google/protobuf/Timestamp.pbobjc.h b/objectivec/google/protobuf/Timestamp.pbobjc.h index d351f2771258..826326dbf550 100644 --- a/objectivec/google/protobuf/Timestamp.pbobjc.h +++ b/objectivec/google/protobuf/Timestamp.pbobjc.h @@ -45,7 +45,7 @@ NS_ASSUME_NONNULL_BEGIN * which is a @c GPBExtensionRegistry that includes all the extensions defined by * this file and all files that it depends on. **/ -@interface GPBTimestampRoot : GPBRootObject +GPB_FINAL @interface GPBTimestampRoot : GPBRootObject @end #pragma mark - GPBTimestamp @@ -139,7 +139,7 @@ typedef GPB_ENUM(GPBTimestamp_FieldNumber) { * http://www.joda.org/joda-time/apidocs/org/joda/time/format/ISODateTimeFormat.html#dateTime%2D%2D * ) to obtain a formatter capable of generating timestamps in this format. **/ -@interface GPBTimestamp : GPBMessage +GPB_FINAL @interface GPBTimestamp : GPBMessage /** * Represents seconds of UTC time since Unix epoch diff --git a/objectivec/google/protobuf/Type.pbobjc.h b/objectivec/google/protobuf/Type.pbobjc.h index 5a5486364e0e..0ee1b50e07dc 100644 --- a/objectivec/google/protobuf/Type.pbobjc.h +++ b/objectivec/google/protobuf/Type.pbobjc.h @@ -183,7 +183,7 @@ BOOL GPBField_Cardinality_IsValidValue(int32_t value); * which is a @c GPBExtensionRegistry that includes all the extensions defined by * this file and all files that it depends on. **/ -@interface GPBTypeRoot : GPBRootObject +GPB_FINAL @interface GPBTypeRoot : GPBRootObject @end #pragma mark - GPBType @@ -200,7 +200,7 @@ typedef GPB_ENUM(GPBType_FieldNumber) { /** * A protocol buffer message type. **/ -@interface GPBType : GPBMessage +GPB_FINAL @interface GPBType : GPBMessage /** The fully qualified message name. */ @property(nonatomic, readwrite, copy, null_resettable) NSString *name; @@ -260,7 +260,7 @@ typedef GPB_ENUM(GPBField_FieldNumber) { /** * A single field of a message type. **/ -@interface GPBField : GPBMessage +GPB_FINAL @interface GPBField : GPBMessage /** The field type. */ @property(nonatomic, readwrite) GPBField_Kind kind; @@ -339,7 +339,7 @@ typedef GPB_ENUM(GPBEnum_FieldNumber) { /** * Enum type definition. **/ -@interface GPBEnum : GPBMessage +GPB_FINAL @interface GPBEnum : GPBMessage /** Enum type name. */ @property(nonatomic, readwrite, copy, null_resettable) NSString *name; @@ -387,7 +387,7 @@ typedef GPB_ENUM(GPBEnumValue_FieldNumber) { /** * Enum value definition. **/ -@interface GPBEnumValue : GPBMessage +GPB_FINAL @interface GPBEnumValue : GPBMessage /** Enum value name. */ @property(nonatomic, readwrite, copy, null_resettable) NSString *name; @@ -413,7 +413,7 @@ typedef GPB_ENUM(GPBOption_FieldNumber) { * A protocol buffer option, which can be attached to a message, field, * enumeration, etc. **/ -@interface GPBOption : GPBMessage +GPB_FINAL @interface GPBOption : GPBMessage /** * The option's name. For protobuf built-in options (options defined in diff --git a/objectivec/google/protobuf/Wrappers.pbobjc.h b/objectivec/google/protobuf/Wrappers.pbobjc.h index a9d3646e3169..7f97b0ad1f23 100644 --- a/objectivec/google/protobuf/Wrappers.pbobjc.h +++ b/objectivec/google/protobuf/Wrappers.pbobjc.h @@ -45,7 +45,7 @@ NS_ASSUME_NONNULL_BEGIN * which is a @c GPBExtensionRegistry that includes all the extensions defined by * this file and all files that it depends on. **/ -@interface GPBWrappersRoot : GPBRootObject +GPB_FINAL @interface GPBWrappersRoot : GPBRootObject @end #pragma mark - GPBDoubleValue @@ -59,7 +59,7 @@ typedef GPB_ENUM(GPBDoubleValue_FieldNumber) { * * The JSON representation for `DoubleValue` is JSON number. **/ -@interface GPBDoubleValue : GPBMessage +GPB_FINAL @interface GPBDoubleValue : GPBMessage /** The double value. */ @property(nonatomic, readwrite) double value; @@ -77,7 +77,7 @@ typedef GPB_ENUM(GPBFloatValue_FieldNumber) { * * The JSON representation for `FloatValue` is JSON number. **/ -@interface GPBFloatValue : GPBMessage +GPB_FINAL @interface GPBFloatValue : GPBMessage /** The float value. */ @property(nonatomic, readwrite) float value; @@ -95,7 +95,7 @@ typedef GPB_ENUM(GPBInt64Value_FieldNumber) { * * The JSON representation for `Int64Value` is JSON string. **/ -@interface GPBInt64Value : GPBMessage +GPB_FINAL @interface GPBInt64Value : GPBMessage /** The int64 value. */ @property(nonatomic, readwrite) int64_t value; @@ -113,7 +113,7 @@ typedef GPB_ENUM(GPBUInt64Value_FieldNumber) { * * The JSON representation for `UInt64Value` is JSON string. **/ -@interface GPBUInt64Value : GPBMessage +GPB_FINAL @interface GPBUInt64Value : GPBMessage /** The uint64 value. */ @property(nonatomic, readwrite) uint64_t value; @@ -131,7 +131,7 @@ typedef GPB_ENUM(GPBInt32Value_FieldNumber) { * * The JSON representation for `Int32Value` is JSON number. **/ -@interface GPBInt32Value : GPBMessage +GPB_FINAL @interface GPBInt32Value : GPBMessage /** The int32 value. */ @property(nonatomic, readwrite) int32_t value; @@ -149,7 +149,7 @@ typedef GPB_ENUM(GPBUInt32Value_FieldNumber) { * * The JSON representation for `UInt32Value` is JSON number. **/ -@interface GPBUInt32Value : GPBMessage +GPB_FINAL @interface GPBUInt32Value : GPBMessage /** The uint32 value. */ @property(nonatomic, readwrite) uint32_t value; @@ -167,7 +167,7 @@ typedef GPB_ENUM(GPBBoolValue_FieldNumber) { * * The JSON representation for `BoolValue` is JSON `true` and `false`. **/ -@interface GPBBoolValue : GPBMessage +GPB_FINAL @interface GPBBoolValue : GPBMessage /** The bool value. */ @property(nonatomic, readwrite) BOOL value; @@ -185,7 +185,7 @@ typedef GPB_ENUM(GPBStringValue_FieldNumber) { * * The JSON representation for `StringValue` is JSON string. **/ -@interface GPBStringValue : GPBMessage +GPB_FINAL @interface GPBStringValue : GPBMessage /** The string value. */ @property(nonatomic, readwrite, copy, null_resettable) NSString *value; @@ -203,7 +203,7 @@ typedef GPB_ENUM(GPBBytesValue_FieldNumber) { * * The JSON representation for `BytesValue` is JSON string. **/ -@interface GPBBytesValue : GPBMessage +GPB_FINAL @interface GPBBytesValue : GPBMessage /** The bytes value. */ @property(nonatomic, readwrite, copy, null_resettable) NSData *value; diff --git a/src/google/protobuf/compiler/objectivec/objectivec_file.cc b/src/google/protobuf/compiler/objectivec/objectivec_file.cc index 8258acb1896d..b17e3e7b81d6 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_file.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_file.cc @@ -303,7 +303,7 @@ void FileGenerator::GenerateHeader(io::Printer *printer) { " * which is a @c GPBExtensionRegistry that includes all the extensions defined by\n" " * this file and all files that it depends on.\n" " **/\n" - "@interface $root_class_name$ : GPBRootObject\n" + "GPB_FINAL @interface $root_class_name$ : GPBRootObject\n" "@end\n" "\n", "root_class_name", root_class_name_); diff --git a/src/google/protobuf/compiler/objectivec/objectivec_message.cc b/src/google/protobuf/compiler/objectivec/objectivec_message.cc index 5ab5fd5b55f4..b5d8128a999c 100644 --- a/src/google/protobuf/compiler/objectivec/objectivec_message.cc +++ b/src/google/protobuf/compiler/objectivec/objectivec_message.cc @@ -334,7 +334,7 @@ void MessageGenerator::GenerateMessageHeader(io::Printer* printer) { } printer->Print( - "$comments$$deprecated_attribute$@interface $classname$ : GPBMessage\n\n", + "$comments$$deprecated_attribute$GPB_FINAL @interface $classname$ : GPBMessage\n\n", "classname", class_name_, "deprecated_attribute", deprecated_attribute_, "comments", message_comments);