فهرست منبع

Merge pull request #5099 from oqton/feature/issue-5806

Fixes JSON Loading of Any messages with Unknown Fields  in C++
Feng Xiao 7 سال پیش
والد
کامیت
37b5617d42

+ 13 - 1
src/google/protobuf/util/internal/protostream_objectwriter.cc

@@ -73,6 +73,18 @@ ProtoStreamObjectWriter::ProtoStreamObjectWriter(
   set_use_lower_camel_for_enums(options_.use_lower_camel_for_enums);
 }
 
+ProtoStreamObjectWriter::ProtoStreamObjectWriter(
+    const TypeInfo* typeinfo, const google::protobuf::Type& type,
+    strings::ByteSink* output, ErrorListener* listener,
+    const ProtoStreamObjectWriter::Options& options)
+    : ProtoWriter(typeinfo, type, output, listener),
+      master_type_(type),
+      current_(nullptr),
+      options_(options) {
+  set_ignore_unknown_fields(options_.ignore_unknown_fields);
+  set_use_lower_camel_for_enums(options.use_lower_camel_for_enums);
+}
+
 ProtoStreamObjectWriter::ProtoStreamObjectWriter(
     const TypeInfo* typeinfo, const google::protobuf::Type& type,
     strings::ByteSink* output, ErrorListener* listener)
@@ -342,7 +354,7 @@ void ProtoStreamObjectWriter::AnyWriter::StartAny(const DataPiece& value) {
   // Create our object writer and initialize it with the first StartObject
   // call.
   ow_.reset(new ProtoStreamObjectWriter(parent_->typeinfo(), *type, &output_,
-                                        parent_->listener()));
+                                        parent_->listener(), parent_->options_));
 
   // Don't call StartObject() for well-known types yet. Depending on the
   // type of actual data, we may not need to call StartObject(). For

+ 5 - 0
src/google/protobuf/util/internal/protostream_objectwriter.h

@@ -323,6 +323,11 @@ class LIBPROTOBUF_EXPORT ProtoStreamObjectWriter : public ProtoWriter {
                           const google::protobuf::Type& type,
                           strings::ByteSink* output, ErrorListener* listener);
 
+ ProtoStreamObjectWriter(const TypeInfo* typeinfo,
+                          const google::protobuf::Type& type,
+                          strings::ByteSink* output, ErrorListener* listener,
+                          const ProtoStreamObjectWriter::Options& options);
+
   // Returns true if the field is a map.
   inline bool IsMap(const google::protobuf::Field& field);
 

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

@@ -56,6 +56,7 @@ using proto3::TestEnumValue;
 using proto3::TestMap;
 using proto3::TestMessage;
 using proto3::TestOneof;
+using proto3::TestAny;
 
 static const char kTypeUrlPrefix[] = "type.googleapis.com";
 
@@ -357,6 +358,28 @@ TEST_F(JsonUtilTest, TestDynamicMessage) {
   EXPECT_EQ(ToJson(generated, options), ToJson(*message, options));
 }
 
+TEST_F(JsonUtilTest, TestParsingUnknownAnyFields) {
+  string input =
+      "{\n"
+      "  \"value\": {\n"
+      "    \"@type\": \"type.googleapis.com/proto3.TestMessage\",\n"
+      "    \"unknown_field\": \"UNKOWN_VALUE\",\n"
+      "    \"string_value\": \"expected_value\"\n"
+      "  }\n"
+      "}";
+      
+  TestAny m;
+  JsonParseOptions options;
+  EXPECT_FALSE(FromJson(input, &m, options));
+
+  options.ignore_unknown_fields = true;
+  EXPECT_TRUE(FromJson(input, &m, options));
+
+  TestMessage t;
+  EXPECT_TRUE(m.value().UnpackTo(&t));
+  EXPECT_EQ("expected_value", t.string_value());
+}
+
 TEST_F(JsonUtilTest, TestParsingUnknownEnumsProto2) {
   string input =
       "{\n"