aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Brendan McCarthy <brendan@oddsoftware.net>2017-03-17 22:47:38 +1000
committerGravatar Brendan McCarthy <brendan@oddsoftware.net>2017-03-17 22:47:38 +1000
commit89eb4e51b24f7417224b47faf32503d11b6b1bc0 (patch)
tree1421c70b8eac263f872de8b37f036c3c60108541
parent1eee3202fce4953a9c0c3adbf357ed10bd71e01e (diff)
Add option to preserve original proto field names
-rw-r--r--src/google/protobuf/util/internal/default_value_objectwriter.cc22
-rw-r--r--src/google/protobuf/util/internal/default_value_objectwriter.h11
-rw-r--r--src/google/protobuf/util/internal/json_objectwriter.cc10
-rw-r--r--src/google/protobuf/util/internal/json_objectwriter.h8
-rw-r--r--src/google/protobuf/util/internal/protostream_objectsource.cc8
-rw-r--r--src/google/protobuf/util/internal/protostream_objectsource.h8
-rw-r--r--src/google/protobuf/util/json_util.cc5
-rw-r--r--src/google/protobuf/util/json_util.h6
-rw-r--r--src/google/protobuf/util/json_util_test.cc37
9 files changed, 87 insertions, 28 deletions
diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.cc b/src/google/protobuf/util/internal/default_value_objectwriter.cc
index 1772219a..6b0c5234 100644
--- a/src/google/protobuf/util/internal/default_value_objectwriter.cc
+++ b/src/google/protobuf/util/internal/default_value_objectwriter.cc
@@ -65,6 +65,7 @@ DefaultValueObjectWriter::DefaultValueObjectWriter(
current_(NULL),
root_(NULL),
suppress_empty_list_(false),
+ preserve_proto_field_names_(false),
field_scrub_callback_(NULL),
ow_(ow) {}
@@ -191,7 +192,8 @@ void DefaultValueObjectWriter::RegisterFieldScrubCallBack(
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, FieldScrubCallBack* field_scrub_callback)
+ bool suppress_empty_list, bool preserve_proto_field_names,
+ FieldScrubCallBack* field_scrub_callback)
: name_(name),
type_(type),
kind_(kind),
@@ -200,6 +202,7 @@ DefaultValueObjectWriter::Node::Node(
is_placeholder_(is_placeholder),
path_(path),
suppress_empty_list_(suppress_empty_list),
+ preserve_proto_field_names_(preserve_proto_field_names),
field_scrub_callback_(field_scrub_callback) {}
DefaultValueObjectWriter::Node* DefaultValueObjectWriter::Node::FindChild(
@@ -369,10 +372,12 @@ void DefaultValueObjectWriter::Node::PopulateChildren(
// If the child field is of primitive type, sets its data to the default
// value of its type.
google::protobuf::scoped_ptr<Node> child(new Node(
- field.json_name(), field_type, kind,
+ preserve_proto_field_names_ ? field.name() : field.json_name(),
+ field_type, kind,
kind == PRIMITIVE ? CreateDefaultDataPieceForField(field, typeinfo)
: DataPiece::NullData(),
- true, path, suppress_empty_list_, field_scrub_callback_));
+ true, path, suppress_empty_list_, preserve_proto_field_names_,
+ field_scrub_callback_));
new_children.push_back(child.release());
}
// Adds all leftover nodes in children_ to the beginning of new_child.
@@ -469,6 +474,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject(
std::vector<string> path;
root_.reset(new Node(name.ToString(), &type_, OBJECT, DataPiece::NullData(),
false, path, suppress_empty_list_,
+ preserve_proto_field_names_,
field_scrub_callback_.get()));
root_->PopulateChildren(typeinfo_);
current_ = root_.get();
@@ -485,7 +491,8 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartObject(
: NULL),
OBJECT, DataPiece::NullData(), false,
child == NULL ? current_->path() : child->path(),
- suppress_empty_list_, field_scrub_callback_.get()));
+ suppress_empty_list_, preserve_proto_field_names_,
+ field_scrub_callback_.get()));
child = node.get();
current_->AddChild(node.release());
}
@@ -517,6 +524,7 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartList(
std::vector<string> path;
root_.reset(new Node(name.ToString(), &type_, LIST, DataPiece::NullData(),
false, path, suppress_empty_list_,
+ preserve_proto_field_names_,
field_scrub_callback_.get()));
current_ = root_.get();
return this;
@@ -527,7 +535,8 @@ DefaultValueObjectWriter* DefaultValueObjectWriter::StartList(
google::protobuf::scoped_ptr<Node> node(
new Node(name.ToString(), NULL, LIST, DataPiece::NullData(), false,
child == NULL ? current_->path() : child->path(),
- suppress_empty_list_, field_scrub_callback_.get()));
+ suppress_empty_list_, preserve_proto_field_names_,
+ field_scrub_callback_.get()));
child = node.get();
current_->AddChild(node.release());
}
@@ -588,7 +597,8 @@ void DefaultValueObjectWriter::RenderDataPiece(StringPiece name,
google::protobuf::scoped_ptr<Node> node(
new Node(name.ToString(), NULL, PRIMITIVE, data, false,
child == NULL ? current_->path() : child->path(),
- suppress_empty_list_, field_scrub_callback_.get()));
+ suppress_empty_list_, preserve_proto_field_names_,
+ field_scrub_callback_.get()));
current_->AddChild(node.release());
} else {
child->set_data(data);
diff --git a/src/google/protobuf/util/internal/default_value_objectwriter.h b/src/google/protobuf/util/internal/default_value_objectwriter.h
index dc4551c9..ddf23594 100644
--- a/src/google/protobuf/util/internal/default_value_objectwriter.h
+++ b/src/google/protobuf/util/internal/default_value_objectwriter.h
@@ -126,6 +126,9 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
// are written.
void set_suppress_empty_list(bool value) { suppress_empty_list_ = value; }
+ // If set to true, original proto field names are used
+ void set_preserve_proto_field_names(bool value) { preserve_proto_field_names_ = value; }
+
private:
enum NodeKind {
PRIMITIVE = 0,
@@ -141,7 +144,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,
- FieldScrubCallBack* field_scrub_callback);
+ bool preserve_proto_field_names, FieldScrubCallBack* field_scrub_callback);
virtual ~Node() {
for (int i = 0; i < children_.size(); ++i) {
delete children_[i];
@@ -220,6 +223,9 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
// Whether to suppress empty list output.
bool suppress_empty_list_;
+ // Whether to preserve original proto field names
+ bool preserve_proto_field_names_;
+
// 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_;
@@ -268,6 +274,9 @@ class LIBPROTOBUF_EXPORT DefaultValueObjectWriter : public ObjectWriter {
// Whether to suppress output of empty lists.
bool suppress_empty_list_;
+ // Whether to preserve original proto field names
+ bool preserve_proto_field_names_;
+
// 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/internal/json_objectwriter.cc b/src/google/protobuf/util/internal/json_objectwriter.cc
index c36459a4..6e4edd88 100644
--- a/src/google/protobuf/util/internal/json_objectwriter.cc
+++ b/src/google/protobuf/util/internal/json_objectwriter.cc
@@ -176,14 +176,8 @@ void JsonObjectWriter::WritePrefix(StringPiece name) {
if (!name.empty() || empty_key_ok) {
WriteChar('"');
if (!name.empty()) {
- if (use_snake_case_for_field_names_) {
- string snake_name = ToSnakeCase(name);
- ArrayByteSource source(snake_name);
- JsonEscaping::Escape(&source, &sink_);
- } else {
- ArrayByteSource source(name);
- JsonEscaping::Escape(&source, &sink_);
- }
+ ArrayByteSource source(name);
+ JsonEscaping::Escape(&source, &sink_);
}
stream_->WriteString("\":");
if (!indent_string_.empty()) WriteChar(' ');
diff --git a/src/google/protobuf/util/internal/json_objectwriter.h b/src/google/protobuf/util/internal/json_objectwriter.h
index fbef5461..31edc292 100644
--- a/src/google/protobuf/util/internal/json_objectwriter.h
+++ b/src/google/protobuf/util/internal/json_objectwriter.h
@@ -94,7 +94,6 @@ class LIBPROTOBUF_EXPORT JsonObjectWriter : public StructuredObjectWriter {
sink_(out),
indent_string_(indent_string.ToString()),
use_websafe_base64_for_bytes_(false),
- use_snake_case_for_field_names_(false),
empty_name_ok_for_next_key_(false) {}
virtual ~JsonObjectWriter();
@@ -119,10 +118,6 @@ class LIBPROTOBUF_EXPORT JsonObjectWriter : public StructuredObjectWriter {
use_websafe_base64_for_bytes_ = value;
}
- void set_use_snake_case_for_field_names(bool value) {
- use_snake_case_for_field_names_ = value;
- }
-
// Whether empty strings should be rendered for the next JSON key. This
// setting is only valid until the next key is rendered, after which it gets
// reset to false.
@@ -222,9 +217,6 @@ class LIBPROTOBUF_EXPORT JsonObjectWriter : public StructuredObjectWriter {
// to regular base64 encoding.
bool use_websafe_base64_for_bytes_;
- // Whether to use snake_case or lowerCamelCase for field names
- bool use_snake_case_for_field_names_;
-
// Whether empty strings should be rendered for the next JSON key. This
// setting is only valid until the next key is rendered, after which it gets
// reset to false.
diff --git a/src/google/protobuf/util/internal/protostream_objectsource.cc b/src/google/protobuf/util/internal/protostream_objectsource.cc
index f9fd7b01..61491af0 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource.cc
+++ b/src/google/protobuf/util/internal/protostream_objectsource.cc
@@ -121,6 +121,7 @@ ProtoStreamObjectSource::ProtoStreamObjectSource(
type_(type),
use_lower_camel_for_enums_(false),
use_ints_for_enums_(false),
+ preserve_proto_field_names_(false),
recursion_depth_(0),
max_recursion_depth_(kDefaultMaxRecursionDepth),
render_unknown_fields_(false),
@@ -137,6 +138,7 @@ ProtoStreamObjectSource::ProtoStreamObjectSource(
type_(type),
use_lower_camel_for_enums_(false),
use_ints_for_enums_(false),
+ preserve_proto_field_names_(false),
recursion_depth_(0),
max_recursion_depth_(kDefaultMaxRecursionDepth),
render_unknown_fields_(false),
@@ -200,7 +202,11 @@ Status ProtoStreamObjectSource::WriteMessage(const google::protobuf::Type& type,
last_tag = tag;
field = FindAndVerifyField(type, tag);
if (field != NULL) {
- field_name = field->json_name();
+ if (preserve_proto_field_names_) {
+ field_name = field->name();
+ } else {
+ field_name = field->json_name();
+ }
}
}
if (field == NULL) {
diff --git a/src/google/protobuf/util/internal/protostream_objectsource.h b/src/google/protobuf/util/internal/protostream_objectsource.h
index 63d5f455..5f443d9d 100644
--- a/src/google/protobuf/util/internal/protostream_objectsource.h
+++ b/src/google/protobuf/util/internal/protostream_objectsource.h
@@ -116,6 +116,11 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource {
use_ints_for_enums_ = value;
}
+ // Sets whether to use original proto field names
+ void set_preserve_proto_field_names(bool value) {
+ preserve_proto_field_names_ = 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.
@@ -294,6 +299,9 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectSource : public ObjectSource {
// Whether to render enums as ints always. Defaults to false.
bool use_ints_for_enums_;
+ // Whether to preserve proto field names
+ bool preserve_proto_field_names_;
+
// Tracks current recursion depth.
mutable int recursion_depth_;
diff --git a/src/google/protobuf/util/json_util.cc b/src/google/protobuf/util/json_util.cc
index c86cb8cb..8595a881 100644
--- a/src/google/protobuf/util/json_util.cc
+++ b/src/google/protobuf/util/json_util.cc
@@ -83,13 +83,16 @@ util::Status BinaryToJsonStream(TypeResolver* resolver,
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);
+ proto_source.set_preserve_proto_field_names(
+ options.preserve_proto_field_names);
io::CodedOutputStream out_stream(json_output);
converter::JsonObjectWriter json_writer(options.add_whitespace ? " " : "",
&out_stream);
- json_writer.set_use_snake_case_for_field_names(options.use_snake_case_for_field_names);
if (options.always_print_primitive_fields) {
converter::DefaultValueObjectWriter default_value_writer(
resolver, type, &json_writer);
+ default_value_writer.set_preserve_proto_field_names(
+ options.preserve_proto_field_names);
return proto_source.WriteTo(&default_value_writer);
} else {
return proto_source.WriteTo(&json_writer);
diff --git a/src/google/protobuf/util/json_util.h b/src/google/protobuf/util/json_util.h
index 439d137f..dd9a736f 100644
--- a/src/google/protobuf/util/json_util.h
+++ b/src/google/protobuf/util/json_util.h
@@ -64,13 +64,13 @@ struct JsonPrintOptions {
// Whether to always print enums as ints. By default they are rendered as
// strings.
bool always_print_enums_as_ints;
- // Whether to convert field names to snake case
- bool use_snake_case_for_field_names;
+ // Whether to preserve proto field names
+ bool preserve_proto_field_names;
JsonPrintOptions() : add_whitespace(false),
always_print_primitive_fields(false),
always_print_enums_as_ints(false),
- use_snake_case_for_field_names(false) {
+ preserve_proto_field_names(false) {
}
};
diff --git a/src/google/protobuf/util/json_util_test.cc b/src/google/protobuf/util/json_util_test.cc
index b0c2f494..ecbed747 100644
--- a/src/google/protobuf/util/json_util_test.cc
+++ b/src/google/protobuf/util/json_util_test.cc
@@ -158,6 +158,43 @@ TEST_F(JsonUtilTest, TestDefaultValues) {
"\"repeatedMessageValue\":[]"
"}",
ToJson(m, options));
+
+ options.preserve_proto_field_names = true;
+ m.set_string_value("i am a test string value");
+ m.set_bytes_value("i am a test bytes value");
+ EXPECT_EQ(
+ "{\"bool_value\":false,"
+ "\"int32_value\":0,"
+ "\"int64_value\":\"0\","
+ "\"uint32_value\":0,"
+ "\"uint64_value\":\"0\","
+ "\"float_value\":0,"
+ "\"double_value\":0,"
+ "\"string_value\":\"i am a test string value\","
+ "\"bytes_value\":\"aSBhbSBhIHRlc3QgYnl0ZXMgdmFsdWU=\","
+ "\"enum_value\":\"FOO\","
+ "\"repeated_bool_value\":[],"
+ "\"repeated_int32_value\":[],"
+ "\"repeated_int64_value\":[],"
+ "\"repeated_uint32_value\":[],"
+ "\"repeated_uint64_value\":[],"
+ "\"repeated_float_value\":[],"
+ "\"repeated_double_value\":[],"
+ "\"repeated_string_value\":[],"
+ "\"repeated_bytes_value\":[],"
+ "\"repeated_enum_value\":[],"
+ "\"repeated_message_value\":[]"
+ "}",
+ ToJson(m, options));
+}
+
+TEST_F(JsonUtilTest, TestPreserveProtoFieldNames) {
+ TestMessage m;
+ m.mutable_message_value();
+
+ JsonPrintOptions options;
+ options.preserve_proto_field_names = true;
+ EXPECT_EQ("{\"message_value\":{}}", ToJson(m, options));
}
TEST_F(JsonUtilTest, TestAlwaysPrintEnumsAsInts) {