Add C# presence methods to proto3 oneof fields.

PiperOrigin-RevId: 514587333
pull/12129/head
Mike Kruskal 2 years ago committed by Copybara-Service
parent f174908946
commit affadac847
  1. 20
      src/google/protobuf/compiler/csharp/csharp_helpers.h
  2. 12
      src/google/protobuf/compiler/csharp/csharp_primitive_field.cc

@ -140,28 +140,16 @@ inline bool IsWrapperType(const FieldDescriptor* descriptor) {
descriptor->message_type()->file()->name() == "google/protobuf/wrappers.proto";
}
inline bool IsProto2(const FileDescriptor* descriptor) {
return descriptor->syntax() == FileDescriptor::SYNTAX_PROTO2;
}
inline bool SupportsPresenceApi(const FieldDescriptor* descriptor) {
// 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) {
// oneof case, but we follow the convention from other languages.
if (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();
return descriptor->has_presence();
}
inline bool RequiresPresenceBit(const FieldDescriptor* descriptor) {

@ -67,18 +67,16 @@ PrimitiveFieldGenerator::~PrimitiveFieldGenerator() {
}
void PrimitiveFieldGenerator::GenerateMembers(io::Printer* printer) {
// Note: in multiple places, this code assumes that all fields
// that support presence are either nullable, or use a presence field bit.
// Fields which are oneof members are not generated here; they're generated in PrimitiveOneofFieldGenerator below.
// Extensions are not generated here either.
// Proto2 allows different default values to be specified. These are retained
// via static fields. They don't particularly need to be, but we don't need
// to change that. In Proto3 the default value we don't generate these
// fields, just using the literal instead.
if (IsProto2(descriptor_->file())) {
// Explicit presence allows different default values to be specified. These
// are retained via static fields. They don't particularly need to be, but we
// don't need to change that. Under implicit presence we don't use static
// fields for default values and just use the literals instead.
if (descriptor_->has_presence()) {
// Note: "private readonly static" isn't as idiomatic as
// "private static readonly", but changing this now would create a lot of
// churn in generated code with near-to-zero benefit.

Loading…
Cancel
Save