diff options
author | Sanchay Harneja <sanchay.h@gmail.com> | 2017-02-18 16:57:26 -0800 |
---|---|---|
committer | Sanchay Harneja <sanchay.h@gmail.com> | 2017-02-18 17:06:43 -0800 |
commit | 172e0a6423742a2a2ca9d64917d63d5352a52e3d (patch) | |
tree | 4253ddb58a0c625f34a088fe9a45386c22f5fdf5 | |
parent | a9ab38c17178fcedd9b46c09fa33f94d1a6335c3 (diff) |
Add an option to always print enums as ints in Json API
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. |