aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar stone4774 <stone4774@qq.com>2018-03-19 15:57:07 +0800
committerGravatar stone4774 <stone4774@qq.com>2018-03-19 15:57:07 +0800
commit773d8c3329d1a28732d9f9c4b21c02e302052e4f (patch)
treeed014e4978d3ea968d2a1861707cdc87d9e09f4a /src
parenta48d58df9643781947da57bdc13a23ac8d868346 (diff)
Fix bug: whether always_print_enums_as_ints is true or false, it always print the default value of enums as strings
Diffstat (limited to 'src')
-rw-r--r--src/google/protobuf/util/internal/default_value_objectwriter.cc31
-rw-r--r--src/google/protobuf/util/internal/default_value_objectwriter.h20
-rw-r--r--src/google/protobuf/util/json_format_proto3.proto6
-rw-r--r--src/google/protobuf/util/json_util.cc2
-rw-r--r--src/google/protobuf/util/json_util_test.cc24
5 files changed, 66 insertions, 17 deletions
diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.cc b/src/google/protobuf/util/internal/default_value_objectwriter.cc
index 95b3a17d..32e2429b 100644
--- a/src/google/protobuf/util/internal/default_value_objectwriter.cc
+++ b/src/google/protobuf/util/internal/default_value_objectwriter.cc
@@ -66,6 +66,7 @@ DefaultValueObjectWriter::DefaultValueObjectWriter(
root_(NULL),
suppress_empty_list_(false),
preserve_proto_field_names_(false),
+ use_ints_for_enums_(false),
field_scrub_callback_(NULL),
ow_(ow) {}
@@ -200,10 +201,10 @@ DefaultValueObjectWriter::Node* DefaultValueObjectWriter::CreateNewNode(
DefaultValueObjectWriter::Node* DefaultValueObjectWriter::CreateNewNode(
const string& name, const google::protobuf::Type* type, NodeKind kind,
const DataPiece& data, bool is_placeholder, const std::vector<string>& path,
- bool suppress_empty_list, bool preserve_proto_field_names,
+ bool suppress_empty_list, bool preserve_proto_field_names, bool use_ints_for_enums,
FieldScrubCallBack* field_scrub_callback) {
return new Node(name, type, kind, data, is_placeholder, path,
- suppress_empty_list, preserve_proto_field_names,
+ suppress_empty_list, preserve_proto_field_names, use_ints_for_enums,
field_scrub_callback);
}
@@ -220,12 +221,13 @@ DefaultValueObjectWriter::Node::Node(
path_(path),
suppress_empty_list_(suppress_empty_list),
preserve_proto_field_names_(false),
+ use_ints_for_enums_(false),
field_scrub_callback_(field_scrub_callback) {}
DefaultValueObjectWriter::Node::Node(
const string& name, const google::protobuf::Type* type, NodeKind kind,
const DataPiece& data, bool is_placeholder, const std::vector<string>& path,
- bool suppress_empty_list, bool preserve_proto_field_names,
+ bool suppress_empty_list, bool preserve_proto_field_names, bool use_ints_for_enums,
FieldScrubCallBack* field_scrub_callback)
: name_(name),
type_(type),
@@ -236,6 +238,7 @@ DefaultValueObjectWriter::Node::Node(
path_(path),
suppress_empty_list_(suppress_empty_list),
preserve_proto_field_names_(preserve_proto_field_names),
+ use_ints_for_enums_(use_ints_for_enums),
field_scrub_callback_(field_scrub_callback) {}
DefaultValueObjectWriter::Node* DefaultValueObjectWriter::Node::FindChild(
@@ -408,9 +411,9 @@ void DefaultValueObjectWriter::Node::PopulateChildren(
google::protobuf::scoped_ptr<Node> child(new Node(
preserve_proto_field_names_ ? field.name() : field.json_name(),
field_type, kind,
- kind == PRIMITIVE ? CreateDefaultDataPieceForField(field, typeinfo)
+ kind == PRIMITIVE ? CreateDefaultDataPieceForField(field, typeinfo, use_ints_for_enums_)
: DataPiece::NullData(),
- true, path, suppress_empty_list_, preserve_proto_field_names_,
+ true, path, suppress_empty_list_, preserve_proto_field_names_, use_ints_for_enums_,
field_scrub_callback_));
new_children.push_back(child.release());
}
@@ -435,7 +438,7 @@ void DefaultValueObjectWriter::MaybePopulateChildrenOfAny(Node* node) {
}
DataPiece DefaultValueObjectWriter::FindEnumDefault(
- const google::protobuf::Field& field, const TypeInfo* typeinfo) {
+ const google::protobuf::Field& field, const TypeInfo* typeinfo, bool use_ints_for_enums) {
if (!field.default_value().empty())
return DataPiece(field.default_value(), true);
@@ -448,12 +451,12 @@ DataPiece DefaultValueObjectWriter::FindEnumDefault(
}
// We treat the first value as the default if none is specified.
return enum_type->enumvalue_size() > 0
- ? DataPiece(enum_type->enumvalue(0).name(), true)
+ ? (use_ints_for_enums ? DataPiece(0) : DataPiece(enum_type->enumvalue(0).name(), true))
: DataPiece::NullData();
}
DataPiece DefaultValueObjectWriter::CreateDefaultDataPieceForField(
- const google::protobuf::Field& field, const TypeInfo* typeinfo) {
+ const google::protobuf::Field& field, const TypeInfo* typeinfo, bool use_ints_for_enums) {
switch (field.kind()) {
case google::protobuf::Field_Kind_TYPE_DOUBLE: {
return DataPiece(ConvertTo<double>(
@@ -496,7 +499,7 @@ DataPiece DefaultValueObjectWriter::CreateDefaultDataPieceForField(
field.default_value(), &DataPiece::ToUint32, static_cast<uint32>(0)));
}
case google::protobuf::Field_Kind_TYPE_ENUM: {
- return FindEnumDefault(field, typeinfo);
+ return FindEnumDefault(field, typeinfo, use_ints_for_enums);
}
default: { return DataPiece::NullData(); }
}
@@ -508,7 +511,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject(
std::vector<string> path;
root_.reset(CreateNewNode(string(name), &type_, OBJECT,
DataPiece::NullData(), false, path,
- suppress_empty_list_, preserve_proto_field_names_,
+ suppress_empty_list_, preserve_proto_field_names_, use_ints_for_enums_,
field_scrub_callback_.get()));
root_->PopulateChildren(typeinfo_);
current_ = root_.get();
@@ -526,7 +529,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject(
: NULL),
OBJECT, DataPiece::NullData(), false,
child == NULL ? current_->path() : child->path(),
- suppress_empty_list_, preserve_proto_field_names_,
+ suppress_empty_list_, preserve_proto_field_names_, use_ints_for_enums_,
field_scrub_callback_.get()));
child = node.get();
current_->AddChild(node.release());
@@ -559,7 +562,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartList(
std::vector<string> path;
root_.reset(CreateNewNode(string(name), &type_, LIST, DataPiece::NullData(),
false, path, suppress_empty_list_,
- preserve_proto_field_names_,
+ preserve_proto_field_names_, use_ints_for_enums_,
field_scrub_callback_.get()));
current_ = root_.get();
return this;
@@ -570,7 +573,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartList(
google::protobuf::scoped_ptr<Node> node(
CreateNewNode(string(name), NULL, LIST, DataPiece::NullData(), false,
child == NULL ? current_->path() : child->path(),
- suppress_empty_list_, preserve_proto_field_names_,
+ suppress_empty_list_, preserve_proto_field_names_, use_ints_for_enums_,
field_scrub_callback_.get()));
child = node.get();
current_->AddChild(node.release());
@@ -632,7 +635,7 @@ void DefaultValueObjectWriter::RenderDataPiece(StringPiece name,
google::protobuf::scoped_ptr<Node> node(
CreateNewNode(string(name), NULL, PRIMITIVE, data, false,
child == NULL ? current_->path() : child->path(),
- suppress_empty_list_, preserve_proto_field_names_,
+ suppress_empty_list_, preserve_proto_field_names_, use_ints_for_enums_,
field_scrub_callback_.get()));
current_->AddChild(node.release());
} else {
diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.h b/src/google/protobuf/util/internal/default_value_objectwriter.h
index 09c6d23f..59f508cd 100644
--- a/src/google/protobuf/util/internal/default_value_objectwriter.h
+++ b/src/google/protobuf/util/internal/default_value_objectwriter.h
@@ -131,6 +131,12 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
preserve_proto_field_names_ = value;
}
+ // If set to true, enums are rendered as ints from output when default values
+ // are written.
+ void set_print_enums_as_ints(bool value) {
+ use_ints_for_enums_ = value;
+ }
+
protected:
enum NodeKind {
PRIMITIVE = 0,
@@ -150,7 +156,7 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
Node(const string& name, const google::protobuf::Type* type, NodeKind kind,
const DataPiece& data, bool is_placeholder,
const std::vector<string>& path, bool suppress_empty_list,
- bool preserve_proto_field_names,
+ bool preserve_proto_field_names, bool use_ints_for_enums,
FieldScrubCallBack* field_scrub_callback);
virtual ~Node() {
for (int i = 0; i < children_.size(); ++i) {
@@ -233,6 +239,9 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
// Whether to preserve original proto field names
bool preserve_proto_field_names_;
+ // Whether to always print enums as ints
+ bool use_ints_for_enums_;
+
// Pointer to function for determining whether a field needs to be scrubbed
// or not. This callback is owned by the creator of this node.
FieldScrubCallBack* field_scrub_callback_;
@@ -256,11 +265,12 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
const std::vector<string>& path,
bool suppress_empty_list,
bool preserve_proto_field_names,
+ bool use_ints_for_enums,
FieldScrubCallBack* field_scrub_callback);
// Creates a DataPiece containing the default value of the type of the field.
static DataPiece CreateDefaultDataPieceForField(
- const google::protobuf::Field& field, const TypeInfo* typeinfo);
+ const google::protobuf::Field& field, const TypeInfo* typeinfo, bool use_ints_for_enums);
protected:
// Returns a pointer to current Node in tree.
@@ -282,7 +292,8 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
// there is no default. For proto3, where we cannot specify an explicit
// default, a zero value will always be returned.
static DataPiece FindEnumDefault(const google::protobuf::Field& field,
- const TypeInfo* typeinfo);
+ const TypeInfo* typeinfo,
+ bool use_ints_for_enums);
// Type information for all the types used in the descriptor. Used to find
// google::protobuf::Type of nested messages/enums.
@@ -307,6 +318,9 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
// Whether to preserve original proto field names
bool preserve_proto_field_names_;
+ // Whether to always print enums as ints
+ bool use_ints_for_enums_;
+
// Unique Pointer to function for determining whether a field needs to be
// scrubbed or not.
FieldScrubCallBackPtr field_scrub_callback_;
diff --git a/src/google/protobuf/util/json_format_proto3.proto b/src/google/protobuf/util/json_format_proto3.proto
index 8a0441c8..cbc3f81f 100644
--- a/src/google/protobuf/util/json_format_proto3.proto
+++ b/src/google/protobuf/util/json_format_proto3.proto
@@ -181,3 +181,9 @@ message TestCustomJsonName {
message TestExtensions {
.protobuf_unittest.TestAllExtensions extensions = 1;
}
+
+message TestEnumValue{
+ EnumType enum_value1 = 1;
+ EnumType enum_value2 = 2;
+ EnumType enum_value3 = 3;
+} \ No newline at end of file
diff --git a/src/google/protobuf/util/json_util.cc b/src/google/protobuf/util/json_util.cc
index 25e78a65..7221470d 100644
--- a/src/google/protobuf/util/json_util.cc
+++ b/src/google/protobuf/util/json_util.cc
@@ -97,6 +97,8 @@ util::Status BinaryToJsonStream(TypeResolver* resolver,
resolver, type, &json_writer);
default_value_writer.set_preserve_proto_field_names(
options.preserve_proto_field_names);
+ default_value_writer.set_print_enums_as_ints(
+ options.always_print_enums_as_ints);
return proto_source.WriteTo(&default_value_writer);
} else {
return proto_source.WriteTo(&json_writer);
diff --git a/src/google/protobuf/util/json_util_test.cc b/src/google/protobuf/util/json_util_test.cc
index 3a43ca1c..c3f820a2 100644
--- a/src/google/protobuf/util/json_util_test.cc
+++ b/src/google/protobuf/util/json_util_test.cc
@@ -54,6 +54,7 @@ using proto3::TestMessage;
using proto3::TestMap;
using proto3::TestOneof;
using google::protobuf::testing::MapIn;
+using proto3::TestEnumValue;
static const char kTypeUrlPrefix[] = "type.googleapis.com";
@@ -217,6 +218,29 @@ TEST_F(JsonUtilTest, TestAlwaysPrintEnumsAsInts) {
EXPECT_EQ(proto3::BAR, parsed.repeated_enum_value(1));
}
+TEST_F(JsonUtilTest, TestPrintEnumsAsIntsWithDefaultValue) {
+ TestEnumValue orig;
+ //orig.set_enum_value1(proto3::FOO)
+ orig.set_enum_value2(proto3::FOO);
+ orig.set_enum_value3(proto3::BAR);
+
+ JsonPrintOptions print_options;
+ print_options.always_print_enums_as_ints = true;
+ print_options.always_print_primitive_fields = true;
+
+ string expected_json = "{\"enumValue1\":0,\"enumValue2\":0,\"enumValue3\":1}";
+ EXPECT_EQ(expected_json, ToJson(orig, print_options));
+
+ TestEnumValue parsed;
+ JsonParseOptions parse_options;
+ ASSERT_TRUE(FromJson(expected_json, &parsed, parse_options));
+
+ EXPECT_EQ(proto3::FOO, parsed.enum_value1());
+ EXPECT_EQ(proto3::FOO, parsed.enum_value2());
+ EXPECT_EQ(proto3::BAR, parsed.enum_value3());
+
+}
+
TEST_F(JsonUtilTest, ParseMessage) {
// Some random message but good enough to verify that the parsing warpper
// functions are working properly.