| # C++ APIs for Edition Zero |
| |
| **Author:** [@mcy](https://github.com/mcy) |
| |
| **Approved:** 2022-06-27 |
| |
| ## Overview |
| |
| As recorded in *FileDescriptor::syntaxAudit Report* (not available externally), |
| there are significant uses of `FileDescriptor::syntax()` in internal Google |
| repositories that Edition Zero will break; for example, existing usage checks |
| `syntax() == PROTO3` to determine if enums are open. |
| |
| Because we expect to make everything that callers are querying be controlled by |
| individual edition-gated features, the cleanest way forward is to enrich the |
| `Descriptor` types with focused APIs that serve current usages, followed by a |
| migration to them. |
| |
| Tier 1 proposal: |
| |
| ## Proposed API |
| |
| This proposal adds the following code to `descriptor.h:` |
| |
| ``` |
| class FileDescriptor { |
| // Copies package, syntax, edition, dependencies, and file-level options. |
| void CopyHeadingTo(FileDescriptorProto*) const; |
| }; |
| class FieldDescriptor { |
| // Returns whether this field has a proto3-like zero default value. |
| bool has_zero_default_value() const; |
| // Returns whether this is a string field that enforces UTF-8 in the codec. |
| bool enforces_utf8() const; |
| }; |
| class EnumDescriptor { |
| // Returns whether this enum is a proto2-style closed enum. |
| bool is_closed() const; |
| }; |
| ``` |
| |
| This covers everything not already covered by existing accessors. |
| `CopyHeadingTo` is intended to simplify the common, easy-to-get-wrong pattern of |
| copying the heading of a proto file before doing custom manipulation of |
| descriptors within. |
| |
| Additionally, we propose generating `unknown_fields()` and |
| `mutable_unknown_fields()` for all protos unconditionally. |
| |
| ## Migration |
| |
| In addition to the above functions, we'll use `FieldDescriptor::has_presence()` |
| and `FieldDescriptor::is_packed()` to migrate callers performing comparisons to |
| `syntax()`. Users can migrate to the new functions by: |
| |
| 1. Searching for calls to `syntax()`. |
| 2. Identifying what proto2/proto3 distinction is being picked up on, among the |
| following: |
| 1. UTF-8 verification on parse (use new API). |
| 2. Closed/open enum (use new API). |
| 3. Packed-ness (use existing API instead of guessing from `syntax`). |
| 4. Whether fields have hasbits (use `has_presence()`). |
| 3. Migrate to the new API. |
| |
| The volume of such changes in google3 is small enough that it's probably easiest |
| to create a giant CL that fixes every instance of a particular misuse and then |
| hand it to Rosie for splitting up. |
| |
| Once all the "easy" usages are migrated, we will mark `syntax()` as |
| `ABSL_DEPRECATED`. `syntax()` will return a new special value, |
| `Syntax::EDITIONS`, intended to explicitly break caller expectations about what |
| this function returns. Virtually all cases not covered by this proposal are |
| using `syntax()` to reject one of the two existing syntaxes, or produce an error |
| when encountering an unknown `Syntax` value, so they will continue to work as |
| expected (i.e. fail on `editions` protos). |
| |
| A number of existing tools are hostile to proto2 or proto3. Once the migration |
| plan is approved, we should reach out to them individually to coordinate either |
| updating or deprecating their tool. |