• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# C++ APIs for Edition Zero
2
3**Author:** [@mcy](https://github.com/mcy)
4
5**Approved:** 2022-06-27
6
7## Overview
8
9As recorded in *FileDescriptor::syntaxAudit Report* (not available externally),
10there are significant uses of `FileDescriptor::syntax()` in internal Google
11repositories that Edition Zero will break; for example, existing usage checks
12`syntax() == PROTO3` to determine if enums are open.
13
14Because we expect to make everything that callers are querying be controlled by
15individual edition-gated features, the cleanest way forward is to enrich the
16`Descriptor` types with focused APIs that serve current usages, followed by a
17migration to them.
18
19Tier 1 proposal:
20
21## Proposed API
22
23This proposal adds the following code to `descriptor.h:`
24
25```
26class FileDescriptor {
27  // Copies package, syntax, edition, dependencies, and file-level options.
28  void CopyHeadingTo(FileDescriptorProto*) const;
29};
30class FieldDescriptor {
31  // Returns whether this field has a proto3-like zero default value.
32  bool has_zero_default_value() const;
33  // Returns whether this is a string field that enforces UTF-8 in the codec.
34  bool enforces_utf8() const;
35};
36class EnumDescriptor {
37  // Returns whether this enum is a proto2-style closed enum.
38  bool is_closed() const;
39};
40```
41
42This covers everything not already covered by existing accessors.
43`CopyHeadingTo` is intended to simplify the common, easy-to-get-wrong pattern of
44copying the heading of a proto file before doing custom manipulation of
45descriptors within.
46
47Additionally, we propose generating `unknown_fields()` and
48`mutable_unknown_fields()` for all protos unconditionally.
49
50## Migration
51
52In addition to the above functions, we'll use `FieldDescriptor::has_presence()`
53and `FieldDescriptor::is_packed()` to migrate callers performing comparisons to
54`syntax()`. Users can migrate to the new functions by:
55
561.  Searching for calls to `syntax()`.
572.  Identifying what proto2/proto3 distinction is being picked up on, among the
58    following:
59    1.  UTF-8 verification on parse (use new API).
60    2.  Closed/open enum (use new API).
61    3.  Packed-ness (use existing API instead of guessing from `syntax`).
62    4.  Whether fields have hasbits (use `has_presence()`).
633.  Migrate to the new API.
64
65The volume of such changes in google3 is small enough that it's probably easiest
66to create a giant CL that fixes every instance of a particular misuse and then
67hand it to Rosie for splitting up.
68
69Once all the "easy" usages are migrated, we will mark `syntax()` as
70`ABSL_DEPRECATED`. `syntax()` will return a new special value,
71`Syntax::EDITIONS`, intended to explicitly break caller expectations about what
72this function returns. Virtually all cases not covered by this proposal are
73using `syntax()` to reject one of the two existing syntaxes, or produce an error
74when encountering an unknown `Syntax` value, so they will continue to work as
75expected (i.e. fail on `editions` protos).
76
77A number of existing tools are hostile to proto2 or proto3. Once the migration
78plan is approved, we should reach out to them individually to coordinate either
79updating or deprecating their tool.
80