Skip to content

Commit 3d273a9

Browse files
Document new C-function based Objective-C proto extension generation syntax.
PiperOrigin-RevId: 875249988
1 parent 33338d9 commit 3d273a9

1 file changed

Lines changed: 67 additions & 0 deletions

File tree

content/reference/objective-c/objective-c-generated.md

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
11431153
Given a message with an
11441154
[extension range](/programming-guides/proto2#extensions):
11451155

@@ -1221,3 +1231,60 @@ NSAssert([[fooMsg getExtension:[Test2Root repeatedFoo]] count] == 2);
12211231
NSAssert(![fooMsg hasExtension:[Test2Root foo]]);
12221232
NSAssert(![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

Comments
 (0)