Support enums in DefaultValue

PiperOrigin-RevId: 596769895
pull/15326/head
Alyssa Haroldsen 1 year ago committed by Copybara-Service
parent e3d2551c8e
commit e7be866a17
  1. 1
      src/google/protobuf/compiler/rust/BUILD.bazel
  2. 17
      src/google/protobuf/compiler/rust/accessors/helpers.cc
  3. 3
      src/google/protobuf/compiler/rust/accessors/helpers.h
  4. 2
      src/google/protobuf/compiler/rust/accessors/singular_scalar.cc
  5. 2
      src/google/protobuf/compiler/rust/accessors/singular_string.cc

@ -204,6 +204,7 @@ cc_library(
strip_include_prefix = "/src",
deps = [
":context",
":naming",
"//src/google/protobuf",
"//src/google/protobuf/io:tokenizer",
"@com_google_absl//absl/log:absl_check",

@ -15,6 +15,8 @@
#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "google/protobuf/compiler/rust/context.h"
#include "google/protobuf/compiler/rust/naming.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/io/strtod.h"
@ -23,7 +25,7 @@ namespace protobuf {
namespace compiler {
namespace rust {
std::string DefaultValue(const FieldDescriptor& field) {
std::string DefaultValue(Context& ctx, const FieldDescriptor& field) {
switch (field.type()) {
case FieldDescriptor::TYPE_DOUBLE:
if (std::isfinite(field.default_value_double())) {
@ -74,9 +76,20 @@ std::string DefaultValue(const FieldDescriptor& field) {
case FieldDescriptor::TYPE_BYTES:
return absl::StrFormat("b\"%s\"",
absl::CHexEscape(field.default_value_string()));
case FieldDescriptor::TYPE_ENUM:
// `$EnumName$::default()` might seem like the right choice here, but
// it is not. The default value for the enum type isn't the same as the
// field, since in `syntax = "proto2"`, an enum field can have a default
// value other than the first listed in the enum.
//
// Even in cases where there is no custom field default, `default()` can't
// be used. This is because the vtables for field mutators store the
// default value. They are `static`s which are constructed with a `const`
// expression. Trait methods in a `const` context aren't currently stable.
return absl::StrCat(RsTypePath(ctx, field),
"::", EnumValueRsName(*field.default_value_enum()));
case FieldDescriptor::TYPE_GROUP:
case FieldDescriptor::TYPE_MESSAGE:
case FieldDescriptor::TYPE_ENUM:
ABSL_LOG(FATAL) << "Unsupported field type: " << field.type_name();
}
ABSL_LOG(FATAL) << "unreachable";

@ -10,6 +10,7 @@
#include <string>
#include "google/protobuf/compiler/rust/context.h"
#include "google/protobuf/descriptor.h"
namespace google {
@ -22,7 +23,7 @@ namespace rust {
// Both strings and bytes are represented as a byte string literal, i.e. in the
// format `b"default value here"`. It is the caller's responsibility to convert
// the byte literal to an actual string, if needed.
std::string DefaultValue(const FieldDescriptor& field);
std::string DefaultValue(Context& ctx, const FieldDescriptor& field);
} // namespace rust
} // namespace compiler

@ -25,7 +25,7 @@ void SingularScalar::InMsgImpl(Context& ctx,
{"field", field.name()},
{"Scalar", RsTypePath(ctx, field)},
{"hazzer_thunk", ThunkName(ctx, field, "has")},
{"default_value", DefaultValue(field)},
{"default_value", DefaultValue(ctx, field)},
{"getter",
[&] {
ctx.Emit({}, R"rs(

@ -68,7 +68,7 @@ void SingularString::InMsgImpl(Context& ctx,
{
{"field", field.name()},
{"proxied_type", proxied_type},
{"default_val", DefaultValue(field)},
{"default_val", DefaultValue(ctx, field)},
{"view_type", proxied_type},
{"transform_field_entry",
[&] {

Loading…
Cancel
Save