Skip to content

Commit affadac

Browse files
mkruskal-googlecopybara-github
authored andcommitted
Add C# presence methods to proto3 oneof fields.
PiperOrigin-RevId: 514587333
1 parent f174908 commit affadac

File tree

2 files changed

+9
-23
lines changed

2 files changed

+9
-23
lines changed

src/google/protobuf/compiler/csharp/csharp_helpers.h

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -140,28 +140,16 @@ inline bool IsWrapperType(const FieldDescriptor* descriptor) {
140140
descriptor->message_type()->file()->name() == "google/protobuf/wrappers.proto";
141141
}
142142

143-
inline bool IsProto2(const FileDescriptor* descriptor) {
144-
return descriptor->syntax() == FileDescriptor::SYNTAX_PROTO2;
145-
}
146-
147143
inline bool SupportsPresenceApi(const FieldDescriptor* descriptor) {
148144
// Unlike most languages, we don't generate Has/Clear members for message
149145
// types, because they can always be set to null in C#. They're not really
150146
// needed for oneof fields in proto2 either, as everything can be done via
151-
// oneof case, but we follow the convention from other languages. Proto3
152-
// oneof fields never have Has/Clear members - but will also never have
153-
// the explicit optional keyword either.
154-
//
155-
// None of the built-in helpers (descriptor->has_presence() etc) describe
156-
// quite the behavior we want, so the rules are explicit below.
157-
158-
if (descriptor->is_repeated() ||
159-
descriptor->type() == FieldDescriptor::TYPE_MESSAGE) {
147+
// oneof case, but we follow the convention from other languages.
148+
if (descriptor->type() == FieldDescriptor::TYPE_MESSAGE) {
160149
return false;
161150
}
162-
// has_optional_keyword() has more complex rules for proto2, but that
163-
// doesn't matter given the first part of this condition.
164-
return IsProto2(descriptor->file()) || descriptor->has_optional_keyword();
151+
152+
return descriptor->has_presence();
165153
}
166154

167155
inline bool RequiresPresenceBit(const FieldDescriptor* descriptor) {

src/google/protobuf/compiler/csharp/csharp_primitive_field.cc

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,18 +67,16 @@ PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {
6767
}
6868

6969
void PrimitiveFieldGenerator::GenerateMembers(io::Printer* printer) {
70-
7170
// Note: in multiple places, this code assumes that all fields
7271
// that support presence are either nullable, or use a presence field bit.
7372
// Fields which are oneof members are not generated here; they're generated in PrimitiveOneofFieldGenerator below.
7473
// Extensions are not generated here either.
7574

76-
77-
// Proto2 allows different default values to be specified. These are retained
78-
// via static fields. They don't particularly need to be, but we don't need
79-
// to change that. In Proto3 the default value we don't generate these
80-
// fields, just using the literal instead.
81-
if (IsProto2(descriptor_->file())) {
75+
// Explicit presence allows different default values to be specified. These
76+
// are retained via static fields. They don't particularly need to be, but we
77+
// don't need to change that. Under implicit presence we don't use static
78+
// fields for default values and just use the literals instead.
79+
if (descriptor_->has_presence()) {
8280
// Note: "private readonly static" isn't as idiomatic as
8381
// "private static readonly", but changing this now would create a lot of
8482
// churn in generated code with near-to-zero benefit.

0 commit comments

Comments
 (0)