@@ -1140,6 +1140,16 @@ of the appropriate type).
11401140
11411141## Extensions (proto2 and editions only) {#extensions}
11421142
1143+ You can control the generation of extensions by using the
1144+ ` extension_generation_mode ` option. There are three modes:
1145+
1146+ * ` class_based ` : Generates Objective-C classes and methods for extensions
1147+ (Legacy).
1148+ * ` c_function ` : Generates C functions for extensions (New).
1149+ * ` migration ` : Generates both.
1150+
1151+ ### Class-based (Legacy) {#extensions-legacy}
1152+
11431153Given a message with an
11441154[ extension range] ( /programming-guides/proto2#extensions ) :
11451155
@@ -1221,3 +1231,60 @@ NSAssert([[fooMsg getExtension:[Test2Root repeatedFoo]] count] == 2);
12211231NSAssert(![fooMsg hasExtension:[Test2Root foo]]);
12221232NSAssert(![fooMsg hasExtension:[Test2Root repeatedFoo]]);
12231233```
1234+
1235+ ### C-functions (New) {#extensions-c-functions}
1236+
1237+ When using ` c_function ` mode, C functions are generated instead of Objective-C
1238+ classes. This reduces binary size and avoids name conflicts.
1239+
1240+ The naming convention for the generated functions involves the proto package and
1241+ the extension name. If an ` objc_class_prefix ` is defined, it is prepended.
1242+
1243+ * File-scoped registry: ` <Prefix><Package>_<File>_Registry() `
1244+ * File-scoped extension: ` <Prefix><Package>_extension_<Field>() `
1245+ * Message-scoped extension:
1246+ ` <Prefix><Package>_<ScopeMessage>_extension_<Field>() `
1247+
1248+ (Note: ` Package ` is the CamelCased proto package name. ` File ` is the file name.
1249+ ` ScopeMessage ` is the message containing the extension definition.)
1250+
1251+ Using the same example as above, but assuming ` package my.package; ` and file
1252+ ` test2.proto ` :
1253+
1254+ The compiler generates C functions declared in the header:
1255+
1256+ ``` objc
1257+ // Registry function for the file.
1258+ GPBExtensionRegistry *MyPackage_Test2_Registry (void);
1259+
1260+ // File-scoped extensions.
1261+ GPBExtensionDescriptor * MyPackage_extension_Foo(void);
1262+ GPBExtensionDescriptor * MyPackage_extension_RepeatedFoo(void);
1263+
1264+ // Message-scoped extensions (scoped to Bar).
1265+ GPBExtensionDescriptor * MyPackage_Bar_extension_Bar(void);
1266+ GPBExtensionDescriptor * MyPackage_Bar_extension_RepeatedBar(void);
1267+ ```
1268+
1269+ To get and set these extension fields:
1270+
1271+ ```objc
1272+ Foo *fooMsg = [[Foo alloc] init];
1273+
1274+ // Set the single field extensions
1275+ [fooMsg setExtension:MyPackage_extension_Foo() value:@5];
1276+ NSAssert([fooMsg hasExtension:MyPackage_extension_Foo()]);
1277+ NSAssert([[fooMsg getExtension:MyPackage_extension_Foo()] intValue] == 5);
1278+
1279+ // Add two things to the repeated extension:
1280+ [fooMsg addExtension:MyPackage_extension_RepeatedFoo() value:@1];
1281+ [fooMsg addExtension:MyPackage_extension_RepeatedFoo() value:@2];
1282+ NSAssert([fooMsg hasExtension:MyPackage_extension_RepeatedFoo()]);
1283+ NSAssert([[fooMsg getExtension:MyPackage_extension_RepeatedFoo()] count] == 2);
1284+
1285+ // Clearing
1286+ [fooMsg clearExtension:MyPackage_extension_Foo()];
1287+ [fooMsg clearExtension:MyPackage_extension_RepeatedFoo()];
1288+ NSAssert(![fooMsg hasExtension:MyPackage_extension_Foo()]);
1289+ NSAssert(![fooMsg hasExtension:MyPackage_extension_RepeatedFoo()]);
1290+ ```
0 commit comments