Add an option to always print enums as ints in Json API
https://github.com/google/protobuf/issues/2735
This commit is contained in:
parent
a9ab38c171
commit
172e0a6423
@ -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.
|
||||
|
@ -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_;
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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) {
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user