diff --git a/google/protobuf/descriptor.proto b/google/protobuf/descriptor.proto index deb8f6894de3..d29fdec5e5d4 100644 --- a/google/protobuf/descriptor.proto +++ b/google/protobuf/descriptor.proto @@ -217,10 +217,21 @@ message FieldDescriptorProto { // If true, this is a proto3 "optional". When a proto3 field is optional, it // tracks presence regardless of field type. // - // For message fields this doesn't create any semantic change, since - // non-repeated message fields always track presence. However it still + // When proto3_optional is true, this field must be belong to a oneof to + // signal to old proto3 clients that presence is tracked for this field. This + // oneof is known as a "synthetic" oneof, and this field must be its sole + // member (each proto3 optional field gets its own synthetic oneof). Synthetic + // oneofs exist in the descriptor only, and do not generate any API. Synthetic + // oneofs must be ordered after all "real" oneofs. + // + // For message fields, proto3_optional doesn't create any semantic change, + // since non-repeated message fields always track presence. However it still // indicates the semantic detail of whether the user wrote "optional" or not. - // This can be useful for round-tripping the .proto file. + // This can be useful for round-tripping the .proto file. For consistency we + // give message fields a synthetic oneof also, even though it is not required + // to track presence. This is especially important because the parser can't + // tell if a field is a message or an enum, so it must always create a + // synthetic oneof. // // Proto2 optional fields do not set this flag, because they already indicate // optional with `LABEL_OPTIONAL`.