46
46
#include < google/protobuf/io/zero_copy_stream_impl.h>
47
47
#include < google/protobuf/io/zero_copy_stream_impl_lite.h>
48
48
#include < google/protobuf/descriptor.h>
49
+ #include < google/protobuf/dynamic_message.h>
49
50
#include < google/protobuf/wire_format_lite.h>
50
51
#include < google/protobuf/testing/googletest.h>
51
52
#include < google/protobuf/stubs/logging.h>
@@ -585,41 +586,72 @@ TEST(WireFormatTest, ParseMessageSet) {
585
586
EXPECT_EQ (message_set.DebugString (), dynamic_message_set.DebugString ());
586
587
}
587
588
588
- TEST (WireFormatTest, ParseMessageSetWithReverseTagOrder) {
589
+ namespace {
590
+ std::string BuildMessageSetItemStart () {
589
591
std::string data;
590
592
{
591
- unittest::TestMessageSetExtension1 message;
592
- message.set_i (123 );
593
- // Build a MessageSet manually with its message content put before its
594
- // type_id.
595
593
io::StringOutputStream output_stream (&data);
596
594
io::CodedOutputStream coded_output (&output_stream);
597
595
coded_output.WriteTag (WireFormatLite::kMessageSetItemStartTag );
596
+ }
597
+ return data;
598
+ }
599
+ std::string BuildMessageSetItemEnd () {
600
+ std::string data;
601
+ {
602
+ io::StringOutputStream output_stream (&data);
603
+ io::CodedOutputStream coded_output (&output_stream);
604
+ coded_output.WriteTag (WireFormatLite::kMessageSetItemEndTag );
605
+ }
606
+ return data;
607
+ }
608
+ std::string BuildMessageSetTestExtension1 (int value = 123 ) {
609
+ std::string data;
610
+ {
611
+ unittest::TestMessageSetExtension1 message;
612
+ message.set_i (value);
613
+ io::StringOutputStream output_stream (&data);
614
+ io::CodedOutputStream coded_output (&output_stream);
598
615
// Write the message content first.
599
616
WireFormatLite::WriteTag (WireFormatLite::kMessageSetMessageNumber ,
600
617
WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
601
618
&coded_output);
602
619
coded_output.WriteVarint32 (message.ByteSizeLong ());
603
620
message.SerializeWithCachedSizes (&coded_output);
604
- // Write the type id.
605
- uint32 type_id = message.GetDescriptor ()->extension (0 )->number ();
621
+ }
622
+ return data;
623
+ }
624
+ std::string BuildMessageSetItemTypeId (int extension_number) {
625
+ std::string data;
626
+ {
627
+ io::StringOutputStream output_stream (&data);
628
+ io::CodedOutputStream coded_output (&output_stream);
606
629
WireFormatLite::WriteUInt32 (WireFormatLite::kMessageSetTypeIdNumber ,
607
- type_id, &coded_output);
608
- coded_output.WriteTag (WireFormatLite::kMessageSetItemEndTag );
630
+ extension_number, &coded_output);
609
631
}
632
+ return data;
633
+ }
634
+ void ValidateTestMessageSet (const std::string& test_case,
635
+ const std::string& data) {
636
+ SCOPED_TRACE (test_case);
610
637
{
611
- proto2_wireformat_unittest::TestMessageSet message_set;
638
+ :: proto2_wireformat_unittest::TestMessageSet message_set;
612
639
ASSERT_TRUE (message_set.ParseFromString (data));
613
640
614
641
EXPECT_EQ (123 ,
615
642
message_set
616
643
.GetExtension (
617
644
unittest::TestMessageSetExtension1::message_set_extension)
618
645
.i ());
646
+
647
+ // Make sure it does not contain anything else.
648
+ message_set.ClearExtension (
649
+ unittest::TestMessageSetExtension1::message_set_extension);
650
+ EXPECT_EQ (message_set.SerializeAsString (), " " );
619
651
}
620
652
{
621
653
// Test parse the message via Reflection.
622
- proto2_wireformat_unittest::TestMessageSet message_set;
654
+ :: proto2_wireformat_unittest::TestMessageSet message_set;
623
655
io::CodedInputStream input (reinterpret_cast <const uint8*>(data.data ()),
624
656
data.size ());
625
657
EXPECT_TRUE (WireFormat::ParseAndMergePartial (&input, &message_set));
@@ -631,6 +663,61 @@ TEST(WireFormatTest, ParseMessageSetWithReverseTagOrder) {
631
663
unittest::TestMessageSetExtension1::message_set_extension)
632
664
.i ());
633
665
}
666
+ {
667
+ // Test parse the message via DynamicMessage.
668
+ DynamicMessageFactory factory;
669
+ std::unique_ptr<Message> msg (
670
+ factory
671
+ .GetPrototype (
672
+ ::proto2_wireformat_unittest::TestMessageSet::descriptor ())
673
+ ->New());
674
+ msg->ParseFromString (data);
675
+ auto * reflection = msg->GetReflection ();
676
+ std::vector<const FieldDescriptor*> fields;
677
+ reflection->ListFields (*msg, &fields);
678
+ ASSERT_EQ (fields.size (), 1 );
679
+ const auto & sub = reflection->GetMessage (*msg, fields[0 ]);
680
+ reflection = sub.GetReflection ();
681
+ EXPECT_EQ (123 , reflection->GetInt32 (
682
+ sub, sub.GetDescriptor ()->FindFieldByName (" i" )));
683
+ }
684
+ }
685
+ } // namespace
686
+
687
+ TEST (WireFormatTest, ParseMessageSetWithAnyTagOrder) {
688
+ std::string start = BuildMessageSetItemStart ();
689
+ std::string end = BuildMessageSetItemEnd ();
690
+ std::string id = BuildMessageSetItemTypeId (
691
+ unittest::TestMessageSetExtension1::descriptor ()->extension (0 )->number ());
692
+ std::string message = BuildMessageSetTestExtension1 ();
693
+
694
+ ValidateTestMessageSet (" id + message" , start + id + message + end);
695
+ ValidateTestMessageSet (" message + id" , start + message + id + end);
696
+ }
697
+
698
+ TEST (WireFormatTest, ParseMessageSetWithDuplicateTags) {
699
+ std::string start = BuildMessageSetItemStart ();
700
+ std::string end = BuildMessageSetItemEnd ();
701
+ std::string id = BuildMessageSetItemTypeId (
702
+ unittest::TestMessageSetExtension1::descriptor ()->extension (0 )->number ());
703
+ std::string other_id = BuildMessageSetItemTypeId (123456 );
704
+ std::string message = BuildMessageSetTestExtension1 ();
705
+ std::string other_message = BuildMessageSetTestExtension1 (321 );
706
+
707
+ // Double id
708
+ ValidateTestMessageSet (" id + other_id + message" ,
709
+ start + id + other_id + message + end);
710
+ ValidateTestMessageSet (" id + message + other_id" ,
711
+ start + id + message + other_id + end);
712
+ ValidateTestMessageSet (" message + id + other_id" ,
713
+ start + message + id + other_id + end);
714
+ // Double message
715
+ ValidateTestMessageSet (" id + message + other_message" ,
716
+ start + id + message + other_message + end);
717
+ ValidateTestMessageSet (" message + id + other_message" ,
718
+ start + message + id + other_message + end);
719
+ ValidateTestMessageSet (" message + other_message + id" ,
720
+ start + message + other_message + id + end);
634
721
}
635
722
636
723
void SerializeReverseOrder (
0 commit comments