31 #include <google/protobuf/util/json_util.h>
37 #include <google/protobuf/io/zero_copy_stream.h>
38 #include <google/protobuf/io/zero_copy_stream_impl.h>
39 #include <google/protobuf/descriptor_database.h>
40 #include <google/protobuf/dynamic_message.h>
41 #include <google/protobuf/util/internal/testdata/maps.pb.h>
42 #include <google/protobuf/util/json_format.pb.h>
43 #include <google/protobuf/util/json_format_proto3.pb.h>
44 #include <google/protobuf/util/type_resolver.h>
45 #include <google/protobuf/util/type_resolver_util.h>
46 #include <gtest/gtest.h>
55 using proto3::TestAny;
56 using proto3::TestEnumValue;
57 using proto3::TestMap;
58 using proto3::TestMessage;
59 using proto3::TestOneof;
60 using proto_util_converter::testing::MapIn;
78 const JsonParseOptions&
options) {
83 return FromJson(json,
message, JsonParseOptions());
89 TEST_F(JsonUtilTest, TestWhitespaces) {
91 m.mutable_message_value();
98 " \"messageValue\": {}\n"
103 TEST_F(JsonUtilTest, TestDefaultValues) {
107 options.always_print_primitive_fields =
true;
109 "{\"boolValue\":false,"
111 "\"int64Value\":\"0\","
113 "\"uint64Value\":\"0\","
116 "\"stringValue\":\"\","
117 "\"bytesValue\":\"\","
118 "\"enumValue\":\"FOO\","
119 "\"repeatedBoolValue\":[],"
120 "\"repeatedInt32Value\":[],"
121 "\"repeatedInt64Value\":[],"
122 "\"repeatedUint32Value\":[],"
123 "\"repeatedUint64Value\":[],"
124 "\"repeatedFloatValue\":[],"
125 "\"repeatedDoubleValue\":[],"
126 "\"repeatedStringValue\":[],"
127 "\"repeatedBytesValue\":[],"
128 "\"repeatedEnumValue\":[],"
129 "\"repeatedMessageValue\":[]"
133 options.always_print_primitive_fields =
true;
134 m.set_string_value(
"i am a test string value");
135 m.set_bytes_value(
"i am a test bytes value");
137 "{\"boolValue\":false,"
139 "\"int64Value\":\"0\","
141 "\"uint64Value\":\"0\","
144 "\"stringValue\":\"i am a test string value\","
145 "\"bytesValue\":\"aSBhbSBhIHRlc3QgYnl0ZXMgdmFsdWU=\","
146 "\"enumValue\":\"FOO\","
147 "\"repeatedBoolValue\":[],"
148 "\"repeatedInt32Value\":[],"
149 "\"repeatedInt64Value\":[],"
150 "\"repeatedUint32Value\":[],"
151 "\"repeatedUint64Value\":[],"
152 "\"repeatedFloatValue\":[],"
153 "\"repeatedDoubleValue\":[],"
154 "\"repeatedStringValue\":[],"
155 "\"repeatedBytesValue\":[],"
156 "\"repeatedEnumValue\":[],"
157 "\"repeatedMessageValue\":[]"
161 options.preserve_proto_field_names =
true;
162 m.set_string_value(
"i am a test string value");
163 m.set_bytes_value(
"i am a test bytes value");
165 "{\"bool_value\":false,"
167 "\"int64_value\":\"0\","
168 "\"uint32_value\":0,"
169 "\"uint64_value\":\"0\","
171 "\"double_value\":0,"
172 "\"string_value\":\"i am a test string value\","
173 "\"bytes_value\":\"aSBhbSBhIHRlc3QgYnl0ZXMgdmFsdWU=\","
174 "\"enum_value\":\"FOO\","
175 "\"repeated_bool_value\":[],"
176 "\"repeated_int32_value\":[],"
177 "\"repeated_int64_value\":[],"
178 "\"repeated_uint32_value\":[],"
179 "\"repeated_uint64_value\":[],"
180 "\"repeated_float_value\":[],"
181 "\"repeated_double_value\":[],"
182 "\"repeated_string_value\":[],"
183 "\"repeated_bytes_value\":[],"
184 "\"repeated_enum_value\":[],"
185 "\"repeated_message_value\":[]"
190 TEST_F(JsonUtilTest, TestPreserveProtoFieldNames) {
192 m.mutable_message_value();
195 options.preserve_proto_field_names =
true;
199 TEST_F(JsonUtilTest, TestAlwaysPrintEnumsAsInts) {
201 orig.set_enum_value(proto3::BAR);
202 orig.add_repeated_enum_value(proto3::FOO);
203 orig.add_repeated_enum_value(proto3::BAR);
205 JsonPrintOptions print_options;
206 print_options.always_print_enums_as_ints =
true;
208 std::string expected_json =
"{\"enumValue\":1,\"repeatedEnumValue\":[0,1]}";
209 EXPECT_EQ(expected_json, ToJson(orig, print_options));
212 JsonParseOptions parse_options;
213 ASSERT_TRUE(FromJson(expected_json, &parsed, parse_options));
215 EXPECT_EQ(proto3::BAR, parsed.enum_value());
216 EXPECT_EQ(2, parsed.repeated_enum_value_size());
217 EXPECT_EQ(proto3::FOO, parsed.repeated_enum_value(0));
218 EXPECT_EQ(proto3::BAR, parsed.repeated_enum_value(1));
221 TEST_F(JsonUtilTest, TestPrintEnumsAsIntsWithDefaultValue) {
224 orig.set_enum_value2(proto3::FOO);
225 orig.set_enum_value3(proto3::BAR);
227 JsonPrintOptions print_options;
228 print_options.always_print_enums_as_ints =
true;
229 print_options.always_print_primitive_fields =
true;
232 "{\"enumValue1\":0,\"enumValue2\":0,\"enumValue3\":1}";
233 EXPECT_EQ(expected_json, ToJson(orig, print_options));
235 TestEnumValue parsed;
236 JsonParseOptions parse_options;
237 ASSERT_TRUE(FromJson(expected_json, &parsed, parse_options));
239 EXPECT_EQ(proto3::FOO, parsed.enum_value1());
240 EXPECT_EQ(proto3::FOO, parsed.enum_value2());
241 EXPECT_EQ(proto3::BAR, parsed.enum_value3());
244 TEST_F(JsonUtilTest, TestPrintProto2EnumAsIntWithDefaultValue) {
245 protobuf_unittest::TestDefaultEnumValue orig;
247 JsonPrintOptions print_options;
249 print_options.always_print_enums_as_ints =
true;
250 print_options.always_print_primitive_fields =
true;
254 EXPECT_EQ(expected_json, ToJson(orig, print_options));
256 protobuf_unittest::TestDefaultEnumValue parsed;
257 JsonParseOptions parse_options;
258 ASSERT_TRUE(FromJson(expected_json, &parsed, parse_options));
260 EXPECT_EQ(protobuf_unittest::DEFAULT, parsed.enum_value());
268 " \"int32Value\": 1024,\n"
269 " \"repeatedInt32Value\": [1, 2],\n"
270 " \"messageValue\": {\n"
273 " \"repeatedMessageValue\": [\n"
274 " {\"value\": 40}, {\"value\": 96}\n"
285 ASSERT_EQ(2,
m.repeated_message_value_size());
286 EXPECT_EQ(40,
m.repeated_message_value(0).value());
287 EXPECT_EQ(96,
m.repeated_message_value(1).value());
292 (*
message.mutable_string_map())[
"hello"] = 1234;
293 JsonPrintOptions print_options;
294 JsonParseOptions parse_options;
295 EXPECT_EQ(
"{\"stringMap\":{\"hello\":1234}}", ToJson(
message, print_options));
301 TEST_F(JsonUtilTest, ParsePrimitiveMapIn) {
303 JsonPrintOptions print_options;
304 print_options.always_print_primitive_fields =
true;
305 JsonParseOptions parse_options;
306 EXPECT_EQ(
"{\"other\":\"\",\"things\":[],\"mapInput\":{},\"mapAny\":{}}",
307 ToJson(
message, print_options));
313 TEST_F(JsonUtilTest, PrintPrimitiveOneof) {
316 options.always_print_primitive_fields =
true;
317 message.mutable_oneof_message_value();
320 message.set_oneof_int32_value(1);
324 TEST_F(JsonUtilTest, TestParseIgnoreUnknownFields) {
327 options.ignore_unknown_fields =
true;
331 TEST_F(JsonUtilTest, TestParseErrors) {
340 TEST_F(JsonUtilTest, TestDynamicMessage) {
344 " \"int32Value\": 1024,\n"
345 " \"repeatedInt32Value\": [1, 2],\n"
346 " \"messageValue\": {\n"
349 " \"repeatedMessageValue\": [\n"
350 " {\"value\": 40}, {\"value\": 96}\n"
359 std::unique_ptr<Message>
message(
360 factory.GetPrototype(
pool.FindMessageTypeByName(
"proto3.TestMessage"))
365 TestMessage generated;
367 EXPECT_EQ(1024, generated.int32_value());
368 ASSERT_EQ(2, generated.repeated_int32_value_size());
369 EXPECT_EQ(1, generated.repeated_int32_value(0));
370 EXPECT_EQ(2, generated.repeated_int32_value(1));
371 EXPECT_EQ(2048, generated.message_value().value());
372 ASSERT_EQ(2, generated.repeated_message_value_size());
373 EXPECT_EQ(40, generated.repeated_message_value(0).value());
374 EXPECT_EQ(96, generated.repeated_message_value(1).value());
380 TEST_F(JsonUtilTest, TestParsingUnknownAnyFields) {
384 " \"@type\": \"type.googleapis.com/proto3.TestMessage\",\n"
385 " \"unknown_field\": \"UNKNOWN_VALUE\",\n"
386 " \"string_value\": \"expected_value\"\n"
394 options.ignore_unknown_fields =
true;
399 EXPECT_EQ(
"expected_value",
t.string_value());
402 TEST_F(JsonUtilTest, TestParsingUnknownEnumsProto2) {
405 " \"a\": \"UNKNOWN_VALUE\"\n"
407 protobuf_unittest::TestNumbers
m;
411 options.ignore_unknown_fields =
true;
416 TEST_F(JsonUtilTest, TestParsingUnknownEnumsProto3) {
423 " \"enum_value\":\"UNKNOWN_VALUE\"\n"
425 m.set_enum_value(proto3::BAR);
429 options.ignore_unknown_fields =
true;
438 " \"enum_value\":12345\n"
440 m.set_enum_value(proto3::BAR);
444 options.ignore_unknown_fields =
true;
455 " \"enum_value\":{}\n"
457 options.ignore_unknown_fields =
true;
459 options.ignore_unknown_fields =
false;
468 " \"enum_value\":[]\n"
471 options.ignore_unknown_fields =
true;
476 TEST_F(JsonUtilTest, TestParsingEnumIgnoreCase) {
482 " \"enum_value\":\"bar\"\n"
484 m.set_enum_value(proto3::FOO);
491 options.case_insensitive_enum_parsing =
false;
494 " \"enum_value\":\"bar\"\n"
496 m.set_enum_value(proto3::FOO);
502 options.case_insensitive_enum_parsing =
true;
505 " \"enum_value\":\"bar\"\n"
507 m.set_enum_value(proto3::FOO);
513 typedef std::pair<char*, int> Segment;
517 explicit SegmentedZeroCopyOutputStream(std::list<Segment> segments)
534 void BackUp(
int length)
override {
553 TEST(ZeroCopyStreamByteSinkTest, TestAllInputOutputPatterns) {
554 static const int kOutputBufferLength = 10;
557 static const int kSkippedPatternCount = 7;
559 char buffer[kOutputBufferLength];
560 for (
int split_pattern = 0; split_pattern < (1 << (kOutputBufferLength - 1));
561 split_pattern += kSkippedPatternCount) {
563 std::list<Segment> segments;
564 int segment_start = 0;
565 for (
int i = 0;
i < kOutputBufferLength - 1; ++
i) {
566 if (split_pattern & (1 <<
i)) {
568 Segment(
buffer + segment_start,
i - segment_start + 1));
569 segment_start =
i + 1;
573 Segment(
buffer + segment_start, kOutputBufferLength - segment_start));
577 for (
int input_pattern = 0; input_pattern < (1 << (input_data.size() - 1));
578 input_pattern += kSkippedPatternCount) {
581 SegmentedZeroCopyOutputStream output_stream(segments);
582 internal::ZeroCopyStreamByteSink byte_sink(&output_stream);
584 for (
int j = 0;
j < input_data.length() - 1; ++
j) {
585 if (input_pattern & (1 <<
j)) {
586 byte_sink.Append(&input_data[
start],
j -
start + 1);
590 byte_sink.Append(&input_data[
start], input_data.length() -
start);
596 input_data =
"012345678";
597 for (
int input_pattern = 0; input_pattern < (1 << (input_data.size() - 1));
598 input_pattern += kSkippedPatternCount) {
601 SegmentedZeroCopyOutputStream output_stream(segments);
602 internal::ZeroCopyStreamByteSink byte_sink(&output_stream);
604 for (
int j = 0;
j < input_data.length() - 1; ++
j) {
605 if (input_pattern & (1 <<
j)) {
606 byte_sink.Append(&input_data[
start],
j -
start + 1);
610 byte_sink.Append(&input_data[
start], input_data.length() -
start);
618 input_data =
"0123456789A";
619 for (
int input_pattern = 0; input_pattern < (1 << (input_data.size() - 1));
620 input_pattern += kSkippedPatternCount) {
623 SegmentedZeroCopyOutputStream output_stream(segments);
624 internal::ZeroCopyStreamByteSink byte_sink(&output_stream);
626 for (
int j = 0;
j < input_data.length() - 1; ++
j) {
627 if (input_pattern & (1 <<
j)) {
628 byte_sink.Append(&input_data[
start],
j -
start + 1);
632 byte_sink.Append(&input_data[
start], input_data.length() -
start);
634 EXPECT_EQ(input_data.substr(0, kOutputBufferLength),
640 TEST_F(JsonUtilTest, TestWrongJsonInput) {
641 const char json[] =
"{\"unknown_field\":\"some_value\"}";
642 io::ArrayInputStream input_stream(json, strlen(json));
643 char proto_buffer[10000];
644 io::ArrayOutputStream output_stream(proto_buffer,
sizeof(proto_buffer));
650 &input_stream, &output_stream);
658 TEST_F(JsonUtilTest, HtmlEscape) {
660 m.set_string_value(
"</script>");