Просмотр исходного кода

Merge pull request #2867 from mojoBrendan/master

Add preserve_proto_field_names option to JsonPrintOptions
Feng Xiao 8 лет назад
Родитель
Сommit
15b60bccf8

+ 16 - 6
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(
@@ -370,10 +373,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.
@@ -470,6 +475,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();
@@ -486,7 +492,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());
   }
@@ -518,6 +525,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;
@@ -528,7 +536,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());
   }
@@ -589,7 +598,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);

+ 10 - 1
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_;

+ 7 - 1
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) {

+ 8 - 0
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_;
 

+ 4 - 0
src/google/protobuf/util/json_util.cc

@@ -83,12 +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);
   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);

+ 4 - 1
src/google/protobuf/util/json_util.h

@@ -64,10 +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 preserve proto field names
+  bool preserve_proto_field_names;
 
   JsonPrintOptions() : add_whitespace(false),
                        always_print_primitive_fields(false),
-                       always_print_enums_as_ints(false) {
+                       always_print_enums_as_ints(false),
+                       preserve_proto_field_names(false) {
   }
 };
 

+ 37 - 0
src/google/protobuf/util/json_util_test.cc

@@ -159,6 +159,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) {