aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Sanchay Harneja <sanchay.h@gmail.com>2017-02-18 16:57:26 -0800
committerGravatar Sanchay Harneja <sanchay.h@gmail.com>2017-02-18 17:06:43 -0800
commit172e0a6423742a2a2ca9d64917d63d5352a52e3d (patch)
tree4253ddb58a0c625f34a088fe9a45386c22f5fdf5
parenta9ab38c17178fcedd9b46c09fa33f94d1a6335c3 (diff)
Add an option to always print enums as ints in Json API
-rw-r--r--src/google/protobuf/util/internal/protostream_objectsource.cc8
-rw-r--r--src/google/protobuf/util/internal/protostream_objectsource.h9
-rw-r--r--src/google/protobuf/util/internal/protostream_objectsource_test.cc17
-rw-r--r--src/google/protobuf/util/json_util.cc1
-rw-r--r--src/google/protobuf/util/json_util.h6
-rw-r--r--src/google/protobuf/util/json_util_test.cc23
6 files changed, 63 insertions, 1 deletions
diff --git a/src/google/protobuf/util/internal/protostream_objectsource.cc b/src/google/protobuf/util/internal/protostream_objectsource.cc
index 3591febf..f9fd7b01 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource.cc
+++ b/src/google/protobuf/util/internal/protostream_objectsource.cc
@@ -120,6 +120,7 @@ ProtoStreamObjectSource::ProtoStreamObjectSource(
own_typeinfo_(true),
type_(type),
use_lower_camel_for_enums_(false),
+ use_ints_for_enums_(false),
recursion_depth_(0),
max_recursion_depth_(kDefaultMaxRecursionDepth),
render_unknown_fields_(false),
@@ -135,6 +136,7 @@ ProtoStreamObjectSource::ProtoStreamObjectSource(
own_typeinfo_(false),
type_(type),
use_lower_camel_for_enums_(false),
+ use_ints_for_enums_(false),
recursion_depth_(0),
max_recursion_depth_(kDefaultMaxRecursionDepth),
render_unknown_fields_(false),
@@ -858,6 +860,12 @@ Status ProtoStreamObjectSource::RenderNonMessageField(
break;
}
+ // No need to lookup enum type if we need to render int.
+ if (use_ints_for_enums_) {
+ ow->RenderInt32(field_name, buffer32);
+ break;
+ }
+
// Get the nested enum type for this field.
// TODO(skarvaje): Avoid string manipulation. Find ways to speed this
// up.
diff --git a/src/google/protobuf/util/internal/protostream_objectsource.h b/src/google/protobuf/util/internal/protostream_objectsource.h
index 88ca652b..63d5f455 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource.h
+++ b/src/google/protobuf/util/internal/protostream_objectsource.h
@@ -110,6 +110,12 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource {
use_lower_camel_for_enums_ = value;
}
+ // Sets whether to always output enums as ints, by default this is off, and
+ // enums are rendered as strings.
+ void set_use_ints_for_enums(bool value) {
+ use_ints_for_enums_ = value;
+ }
+
// Sets the max recursion depth of proto message to be deserialized. Proto
// messages over this depth will fail to be deserialized.
// Default value is 64.
@@ -285,6 +291,9 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource {
// Whether to render enums using lowerCamelCase. Defaults to false.
bool use_lower_camel_for_enums_;
+ // Whether to render enums as ints always. Defaults to false.
+ bool use_ints_for_enums_;
+
// Tracks current recursion depth.
mutable int recursion_depth_;
diff --git a/src/google/protobuf/util/internal/protostream_objectsource_test.cc b/src/google/protobuf/util/internal/protostream_objectsource_test.cc
index 1286bdb9..e215c4ab 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource_test.cc
+++ b/src/google/protobuf/util/internal/protostream_objectsource_test.cc
@@ -102,6 +102,7 @@ class ProtostreamObjectSourceTest
mock_(),
ow_(&mock_),
use_lower_camel_for_enums_(false),
+ use_ints_for_enums_(false),
add_trailing_zeros_(false) {
helper_.ResetTypeInfo(Book::descriptor(), Proto3Message::descriptor());
}
@@ -123,6 +124,7 @@ class ProtostreamObjectSourceTest
google::protobuf::scoped_ptr<ProtoStreamObjectSource> os(
helper_.NewProtoSource(&in_stream, GetTypeUrl(descriptor)));
if (use_lower_camel_for_enums_) os->set_use_lower_camel_for_enums(true);
+ if (use_ints_for_enums_) os->set_use_ints_for_enums(true);
os->set_max_recursion_depth(64);
return os->WriteTo(&mock_);
}
@@ -270,6 +272,8 @@ class ProtostreamObjectSourceTest
void UseLowerCamelForEnums() { use_lower_camel_for_enums_ = true; }
+ void UseIntsForEnums() { use_ints_for_enums_ = true; }
+
void AddTrailingZeros() { add_trailing_zeros_ = true; }
testing::TypeInfoTestHelper helper_;
@@ -277,6 +281,7 @@ class ProtostreamObjectSourceTest
::testing::NiceMock<MockObjectWriter> mock_;
ExpectingObjectWriter ow_;
bool use_lower_camel_for_enums_;
+ bool use_ints_for_enums_;
bool add_trailing_zeros_;
};
@@ -498,6 +503,18 @@ TEST_P(ProtostreamObjectSourceTest, EnumCaseIsUnchangedByDefault) {
DoTest(book, Book::descriptor());
}
+TEST_P(ProtostreamObjectSourceTest, UseIntsForEnumsTest) {
+ Book book;
+ book.set_type(Book::ACTION_AND_ADVENTURE);
+
+ UseIntsForEnums();
+
+ ow_.StartObject("")
+ ->RenderInt32("type", 3)
+ ->EndObject();
+ DoTest(book, Book::descriptor());
+}
+
TEST_P(ProtostreamObjectSourceTest, UnknownEnum) {
Proto3Message message;
message.set_enum_value(static_cast<Proto3Message::NestedEnum>(1234));
diff --git a/src/google/protobuf/util/json_util.cc b/src/google/protobuf/util/json_util.cc
index d7ac2dba..c65e5323 100644
--- a/src/google/protobuf/util/json_util.cc
+++ b/src/google/protobuf/util/json_util.cc
@@ -79,6 +79,7 @@ util::Status BinaryToJsonStream(TypeResolver* resolver,
google::protobuf::Type type;
RETURN_IF_ERROR(resolver->ResolveMessageType(type_url, &type));
converter::ProtoStreamObjectSource proto_source(&in_stream, resolver, type);
+ proto_source.set_use_ints_for_enums(options.always_print_enums_as_ints);
io::CodedOutputStream out_stream(json_output);
converter::JsonObjectWriter json_writer(options.add_whitespace ? " " : "",
&out_stream);
diff --git a/src/google/protobuf/util/json_util.h b/src/google/protobuf/util/json_util.h
index 6d3cee52..8dda70c3 100644
--- a/src/google/protobuf/util/json_util.h
+++ b/src/google/protobuf/util/json_util.h
@@ -61,9 +61,13 @@ struct JsonPrintOptions {
// set to 0 will be omitted. Set this flag to true will override the default
// behavior and print primitive fields regardless of their values.
bool always_print_primitive_fields;
+ // Whether to always print enums as ints. By default they are rendered as
+ // strings.
+ bool always_print_enums_as_ints;
JsonPrintOptions() : add_whitespace(false),
- always_print_primitive_fields(false) {
+ always_print_primitive_fields(false),
+ always_print_enums_as_ints(false) {
}
};
diff --git a/src/google/protobuf/util/json_util_test.cc b/src/google/protobuf/util/json_util_test.cc
index bf35ae3e..796718d5 100644
--- a/src/google/protobuf/util/json_util_test.cc
+++ b/src/google/protobuf/util/json_util_test.cc
@@ -160,6 +160,29 @@ TEST_F(JsonUtilTest, TestDefaultValues) {
ToJson(m, options));
}
+TEST_F(JsonUtilTest, TestAlwaysPrintEnumsAsInts) {
+ TestMessage orig;
+ orig.set_enum_value(proto3::EnumType::BAR);
+ orig.add_repeated_enum_value(proto3::EnumType::FOO);
+ orig.add_repeated_enum_value(proto3::EnumType::BAR);
+
+ JsonPrintOptions print_options;
+ print_options.always_print_enums_as_ints = true;
+
+ string expected_json =
+ "{\"enumValue\":1,\"repeatedEnumValue\":[0,1]}";
+ EXPECT_EQ(expected_json, ToJson(orig, print_options));
+
+ TestMessage parsed;
+ JsonParseOptions parse_options;
+ ASSERT_TRUE(FromJson(expected_json, &parsed, parse_options));
+
+ EXPECT_EQ(proto3::EnumType::BAR, parsed.enum_value());
+ EXPECT_EQ(2, parsed.repeated_enum_value_size());
+ EXPECT_EQ(proto3::EnumType::FOO, parsed.repeated_enum_value(0));
+ EXPECT_EQ(proto3::EnumType::BAR, parsed.repeated_enum_value(1));
+}
+
TEST_F(JsonUtilTest, ParseMessage) {
// Some random message but good enough to verify that the parsing warpper
// functions are working properly.