Skip to content

Commit 5bb14dc

Browse files
authored
docs: document extensions (#14)
1 parent 25eec8b commit 5bb14dc

File tree

1 file changed

+75
-8
lines changed

1 file changed

+75
-8
lines changed

samples/protoc-gen-extensions/README.md

Lines changed: 75 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,87 @@
22

33
This sample shows how to use proto3 extensions (`MethodOptions` more specifically) and the `protogen.Registry` to resolve messages.
44

5-
## Run
5+
## How to access extensionn values
66

7-
For a plugin that uses extensions the extension needs to be generated first using the official protoc python compiler.
8-
This is necessary for the corresponding options that use e.g. in `samples/protos/acme/library/v1/library.proto` to be present and accessible for the example plugin.
9-
Generate python code for at least the file where the extension resides in and all its dependencies with the official Python protoc plugin.
7+
This example works with the following `MethodOption` extension that can be found in [../protos/acme/longrunning/operations.proto](../protos/acme/longrunning/operations.proto):
8+
9+
```proto
10+
extend google.protobuf.MethodOptions { OperationInfo operation_info = 1049; }
11+
12+
message Operation {
13+
string name = 1;
14+
acme.protobuf.Any metadata = 2;
15+
bool done = 3;
16+
oneof result {
17+
string error = 4;
18+
acme.protobuf.Any response = 5;
19+
}
20+
}
21+
22+
message OperationInfo {
23+
string response_type = 1;
24+
string metadata_type = 2;
25+
}
26+
```
27+
28+
Note that the extension is a `MethodOption` extension and that field number `1049` was assigned to it.
29+
The extension is used on methods like this, see [../protos/acme/library/v1/library.proto](../protos/acme/library/v1/library.proto):
30+
31+
```proto
32+
service Library {
33+
rpc WriteBook(WriteBookRequest) returns (acme.longrunning.Operation) {
34+
option (acme.longrunning.operation_info) = {
35+
response_type : "WriteBookResponse"
36+
metadata_type : "acme.protobuf.Empty"
37+
};
38+
}
39+
}
40+
````
41+
42+
For a plugin that should recognize this extensions the extension proto file and its dependencies need to be generated first using the official protoc python compiler.
43+
Generate python code for at least the file where the extension resides in and all its dependencies with the official Python protoc plugin:
1044
1145
```sh
1246
protoc --proto_path=samples/protos --python_out=. samples/protos/acme/longrunning/operations.proto samples/protos/acme/protobuf/any.proto
13-
``
47+
```
1448

15-
Ensure a folder called `output_root` exists:
49+
This will generate several files, including `acme/longrunning/operations_pb2.py` that holds the definition of the `OperationInfo` extension.
50+
51+
```python
52+
OPERATION_INFO_FIELD_NUMBER = 1049
53+
operation_info = _descriptor.FieldDescriptor(
54+
name='operation_info', full_name='trainai.longrunning.operation_info', index=0,
55+
number=1049, type=11, cpp_type=10, label=1,
56+
has_default_value=False, default_value=None,
57+
message_type=None, enum_type=None, containing_type=None,
58+
is_extension=True, extension_scope=None,
59+
serialized_options=None, file=DESCRIPTOR, create_key=_descriptor._internal_create_key)
60+
```
1661

62+
In the plugin, import the Python module that defines the extension.
63+
This should happen before the request from protoc is read (place it somewhere in the beginning of your plugin to be on the safe side).
64+
65+
```python
66+
import acme.longrunning.operations_pb2
67+
68+
# Somewhere after run your plugin.
69+
protogen.Options(...).run(_generate)
1770
```
71+
72+
The import will cause the registration of the extension in the proto type registry of the offical `protobuf` lib.
73+
With that the extension values can be accessed by the plugin.
74+
Each option added to a proto Method will be present as a field its `Method.proto.options`.
75+
Each `Method.proto.option` has a `number` field that corresponds to the field number that was assigned to the extension.
76+
This way one can identify to which extension a `Method.proto.option` belongs.
77+
See [Line 24 and 25](./plugin.py#L24-L25) in the example plugin.
78+
79+
The mechanism to access options for proto Messages, Fields etc. is similar.
80+
81+
## Run the plugin
82+
83+
Ensure a folder called `output_root` exists:
84+
85+
```sh
1886
mkdir output_root
1987
rm -r output_root/acme
2088
```
@@ -23,5 +91,4 @@ Then run plugin.
2391

2492
```sh
2593
protoc --plugin=protoc-gen-extensions=samples/protoc-gen-extensions/plugin.py --extensions_out=output_root -I samples/protos samples/protos/acme/**/*.proto
26-
``
27-
94+
```

0 commit comments

Comments
 (0)