Don't generate Has/Clear members for proto2 message fields.
This is a breaking change in terms of proto2 code generation: users who were previously using these members will have to change to null checks for message fields. After toying with removing Has/Clear for proto2 oneof fields, I've left them alone in this commit, for consistency with other languages. The inconsistency between proto2 and proto3 won't come up here, because proto3 oneof fields can never be explicitly optional. Fixes #7395.
This commit is contained in:
parent
02f182e829
commit
9d74aafbe1
@ -159,24 +159,23 @@ inline bool IsProto2(const FileDescriptor* descriptor) {
|
||||
}
|
||||
|
||||
inline bool SupportsPresenceApi(const FieldDescriptor* descriptor) {
|
||||
// We don't use descriptor->is_singular_with_presence() as C# has slightly
|
||||
// different behavior to other languages.
|
||||
|
||||
if (IsProto2(descriptor->file())) {
|
||||
// We generate Has/Clear for oneof fields in C#, as well as for messages.
|
||||
// It's possible that we shouldn't, but stopping doing so would be a
|
||||
// breaking change for proto2. Fortunately the decision is moot for
|
||||
// onoeof in proto3: you can't use "optional" inside a oneof.
|
||||
// Proto2: every singular field has presence. (Even fields in oneofs.)
|
||||
return !descriptor->is_repeated();
|
||||
} else {
|
||||
// Proto3: only for explictly-optional fields that aren't messages.
|
||||
// (Repeated fields can never be explicitly optional, so we don't need
|
||||
// to check for that.) Currently we can't get at proto3_optional directly,
|
||||
// but we can use has_optional_keyword() as a surrogate check.
|
||||
return descriptor->has_optional_keyword() &&
|
||||
descriptor->type() != FieldDescriptor::TYPE_MESSAGE;
|
||||
// Unlike most languages, we don't generate Has/Clear members for message
|
||||
// types, because they can always be set to null in C#. They're not really
|
||||
// needed for oneof fields in proto2 either, as everything can be done via
|
||||
// oneof case, but we follow the convention from other languages. Proto3
|
||||
// oneof fields never have Has/Clear members - but will also never have
|
||||
// the explicit optional keyword either.
|
||||
//
|
||||
// None of the built-in helpers (descriptor->has_presence() etc) describe
|
||||
// quite the behavior we want, so the rules are explicit below.
|
||||
|
||||
if (descriptor->is_repeated() ||
|
||||
descriptor->type() == FieldDescriptor::TYPE_MESSAGE) {
|
||||
return false;
|
||||
}
|
||||
// has_optional_keyword() has more complex rules for proto2, but that
|
||||
// doesn't matter given the first part of this condition.
|
||||
return IsProto2(descriptor->file()) || descriptor->has_optional_keyword();
|
||||
}
|
||||
|
||||
inline bool RequiresPresenceBit(const FieldDescriptor* descriptor) {
|
||||
|
Loading…
Reference in New Issue
Block a user