Commit 0a27430b authored by Paul Yang's avatar Paul Yang

Merge pull request #500 from TeBoring/temp

Implement parsing for proto3 primitive repeated fields.
parents ec7bbc76 a269a6d3
...@@ -2932,7 +2932,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) { ...@@ -2932,7 +2932,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
"commontag", SimpleItoa(WireFormat::MakeTag(field))); "commontag", SimpleItoa(WireFormat::MakeTag(field)));
if (need_label || if (need_label ||
(field->is_repeated() && !field->options().packed() && !loops)) { (field->is_repeated() && !field->is_packed() && !loops)) {
printer->Print( printer->Print(
" parse_$name$:\n", " parse_$name$:\n",
"name", field->name()); "name", field->name());
...@@ -2945,7 +2945,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) { ...@@ -2945,7 +2945,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
} }
printer->Indent(); printer->Indent();
if (field->options().packed()) { if (field->is_packed()) {
field_generator.GenerateMergeFromCodedStreamWithPacking(printer); field_generator.GenerateMergeFromCodedStreamWithPacking(printer);
} else { } else {
field_generator.GenerateMergeFromCodedStream(printer); field_generator.GenerateMergeFromCodedStream(printer);
...@@ -2953,7 +2953,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) { ...@@ -2953,7 +2953,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
printer->Outdent(); printer->Outdent();
// Emit code to parse unexpectedly packed or unpacked values. // Emit code to parse unexpectedly packed or unpacked values.
if (field->is_packable() && field->options().packed()) { if (field->is_packed()) {
internal::WireFormatLite::WireType wiretype = internal::WireFormatLite::WireType wiretype =
WireFormat::WireTypeForFieldType(field->type()); WireFormat::WireTypeForFieldType(field->type());
printer->Print("} else if (tag == $uncommontag$) {\n", printer->Print("} else if (tag == $uncommontag$) {\n",
...@@ -2963,7 +2963,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) { ...@@ -2963,7 +2963,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
printer->Indent(); printer->Indent();
field_generator.GenerateMergeFromCodedStream(printer); field_generator.GenerateMergeFromCodedStream(printer);
printer->Outdent(); printer->Outdent();
} else if (field->is_packable() && !field->options().packed()) { } else if (field->is_packable() && !field->is_packed()) {
internal::WireFormatLite::WireType wiretype = internal::WireFormatLite::WireType wiretype =
internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED; internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
printer->Print("} else if (tag == $uncommontag$) {\n", printer->Print("} else if (tag == $uncommontag$) {\n",
...@@ -2988,7 +2988,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) { ...@@ -2988,7 +2988,7 @@ GenerateMergeFromCodedStream(io::Printer* printer) {
"if (input->ExpectTag($tag$)) goto parse_loop_$name$;\n", "if (input->ExpectTag($tag$)) goto parse_loop_$name$;\n",
"tag", SimpleItoa(WireFormat::MakeTag(field)), "tag", SimpleItoa(WireFormat::MakeTag(field)),
"name", field->name()); "name", field->name());
} else if (field->is_repeated() && !field->options().packed()) { } else if (field->is_repeated() && !field->is_packed()) {
printer->Print( printer->Print(
"if (input->ExpectTag($tag$)) goto parse_$name$;\n", "if (input->ExpectTag($tag$)) goto parse_$name$;\n",
"tag", SimpleItoa(WireFormat::MakeTag(field)), "tag", SimpleItoa(WireFormat::MakeTag(field)),
......
...@@ -290,7 +290,7 @@ class LIBPROTOBUF_EXPORT UnknownFieldSetFieldSkipper : public FieldSkipper { ...@@ -290,7 +290,7 @@ class LIBPROTOBUF_EXPORT UnknownFieldSetFieldSkipper : public FieldSkipper {
inline WireFormatLite::WireType WireFormat::WireTypeForField( inline WireFormatLite::WireType WireFormat::WireTypeForField(
const FieldDescriptor* field) { const FieldDescriptor* field) {
if (field->options().packed()) { if (field->is_packed()) {
return WireFormatLite::WIRETYPE_LENGTH_DELIMITED; return WireFormatLite::WIRETYPE_LENGTH_DELIMITED;
} else { } else {
return WireTypeForFieldType(field->type()); return WireTypeForFieldType(field->type());
......
...@@ -795,9 +795,73 @@ TEST(WireFormatTest, CompatibleTypes) { ...@@ -795,9 +795,73 @@ TEST(WireFormatTest, CompatibleTypes) {
ASSERT_EQ(static_cast<uint32>(data), msg5.data()); ASSERT_EQ(static_cast<uint32>(data), msg5.data());
} }
class Proto3PrimitiveRepeatedWireFormatTest class Proto3PrimitiveRepeatedWireFormatTest : public ::testing::Test {
: public ::testing::TestWithParam<bool> {
protected: protected:
Proto3PrimitiveRepeatedWireFormatTest()
: packedTestAllTypes_(
"\xFA\x01\x01\x01"
"\x82\x02\x01\x01"
"\x8A\x02\x01\x01"
"\x92\x02\x01\x01"
"\x9A\x02\x01\x02"
"\xA2\x02\x01\x02"
"\xAA\x02\x04\x01\x00\x00\x00"
"\xB2\x02\x08\x01\x00\x00\x00\x00\x00\x00\x00"
"\xBA\x02\x04\x01\x00\x00\x00"
"\xC2\x02\x08\x01\x00\x00\x00\x00\x00\x00\x00"
"\xCA\x02\x04\x00\x00\x80\x3f"
"\xD2\x02\x08\x00\x00\x00\x00\x00\x00\xf0\x3f"
"\xDA\x02\x01\x01"
"\x9A\x03\x01\x01",
86),
packedTestUnpackedTypes_(
"\x0A\x01\x01"
"\x12\x01\x01"
"\x1A\x01\x01"
"\x22\x01\x01"
"\x2A\x01\x02"
"\x32\x01\x02"
"\x3A\x04\x01\x00\x00\x00"
"\x42\x08\x01\x00\x00\x00\x00\x00\x00\x00"
"\x4A\x04\x01\x00\x00\x00"
"\x52\x08\x01\x00\x00\x00\x00\x00\x00\x00"
"\x5A\x04\x00\x00\x80\x3f"
"\x62\x08\x00\x00\x00\x00\x00\x00\xf0\x3f"
"\x6A\x01\x01"
"\x72\x01\x01",
72),
unpackedTestAllTypes_(
"\xF8\x01\x01"
"\x80\x02\x01"
"\x88\x02\x01"
"\x90\x02\x01"
"\x98\x02\x02"
"\xA0\x02\x02"
"\xAD\x02\x01\x00\x00\x00"
"\xB1\x02\x01\x00\x00\x00\x00\x00\x00\x00"
"\xBD\x02\x01\x00\x00\x00"
"\xC1\x02\x01\x00\x00\x00\x00\x00\x00\x00"
"\xCD\x02\x00\x00\x80\x3f"
"\xD1\x02\x00\x00\x00\x00\x00\x00\xf0\x3f"
"\xD8\x02\x01"
"\x98\x03\x01",
72),
unpackedTestUnpackedTypes_(
"\x08\x01"
"\x10\x01"
"\x18\x01"
"\x20\x01"
"\x28\x02"
"\x30\x02"
"\x3D\x01\x00\x00\x00"
"\x41\x01\x00\x00\x00\x00\x00\x00\x00"
"\x4D\x01\x00\x00\x00"
"\x51\x01\x00\x00\x00\x00\x00\x00\x00"
"\x5D\x00\x00\x80\x3f"
"\x61\x00\x00\x00\x00\x00\x00\xf0\x3f"
"\x68\x01"
"\x70\x01",
58) {}
template <class Proto> template <class Proto>
void SetProto3PrimitiveRepeatedFields(Proto* message) { void SetProto3PrimitiveRepeatedFields(Proto* message) {
message->add_repeated_int32(1); message->add_repeated_int32(1);
...@@ -837,8 +901,7 @@ class Proto3PrimitiveRepeatedWireFormatTest ...@@ -837,8 +901,7 @@ class Proto3PrimitiveRepeatedWireFormatTest
} }
template <class Proto> template <class Proto>
void TestProto3PrimitiveRepeatedFields(Proto* message, void TestSerialization(Proto* message, const string& expected) {
const string& expected) {
SetProto3PrimitiveRepeatedFields(message); SetProto3PrimitiveRepeatedFields(message);
int size = message->ByteSize(); int size = message->ByteSize();
...@@ -851,13 +914,8 @@ class Proto3PrimitiveRepeatedWireFormatTest ...@@ -851,13 +914,8 @@ class Proto3PrimitiveRepeatedWireFormatTest
message->SerializeWithCachedSizes(&output); message->SerializeWithCachedSizes(&output);
ASSERT_FALSE(output.HadError()); ASSERT_FALSE(output.HadError());
} }
EXPECT_TRUE(expected == generated_data); EXPECT_TRUE(expected == generated_data);
message->Clear();
message->ParseFromString(generated_data);
ExpectProto3PrimitiveRepeatedFieldsSet(*message);
// Serialize using the dynamic code. // Serialize using the dynamic code.
string dynamic_data; string dynamic_data;
{ {
...@@ -866,64 +924,38 @@ class Proto3PrimitiveRepeatedWireFormatTest ...@@ -866,64 +924,38 @@ class Proto3PrimitiveRepeatedWireFormatTest
WireFormat::SerializeWithCachedSizes(*message, size, &output); WireFormat::SerializeWithCachedSizes(*message, size, &output);
ASSERT_FALSE(output.HadError()); ASSERT_FALSE(output.HadError());
} }
EXPECT_TRUE(expected == dynamic_data); EXPECT_TRUE(expected == dynamic_data);
}
template <class Proto>
void TestParsing(Proto* message, const string& compatible_data) {
message->Clear();
message->ParseFromString(compatible_data);
ExpectProto3PrimitiveRepeatedFieldsSet(*message);
message->Clear(); message->Clear();
io::CodedInputStream input( io::CodedInputStream input(
reinterpret_cast<const uint8*>(dynamic_data.data()), reinterpret_cast<const uint8*>(compatible_data.data()),
dynamic_data.size()); compatible_data.size());
WireFormat::ParseAndMergePartial(&input, message); WireFormat::ParseAndMergePartial(&input, message);
ExpectProto3PrimitiveRepeatedFieldsSet(*message); ExpectProto3PrimitiveRepeatedFieldsSet(*message);
} }
const string packedTestAllTypes_;
const string packedTestUnpackedTypes_;
const string unpackedTestAllTypes_;
const string unpackedTestUnpackedTypes_;
}; };
INSTANTIATE_TEST_CASE_P(SetPacked,
Proto3PrimitiveRepeatedWireFormatTest,
::testing::Values(false, true));
TEST_P(Proto3PrimitiveRepeatedWireFormatTest, Proto3PrimitiveRepeated) { TEST_F(Proto3PrimitiveRepeatedWireFormatTest, Proto3PrimitiveRepeated) {
proto3_arena_unittest::TestAllTypes packed_message; proto3_arena_unittest::TestAllTypes packed_message;
proto3_arena_unittest::TestUnpackedTypes unpacked_message; proto3_arena_unittest::TestUnpackedTypes unpacked_message;
TestSerialization(&packed_message, packedTestAllTypes_);
const string packedExpected( TestParsing(&packed_message, packedTestAllTypes_);
"\xFA\x01\x01\x01" TestParsing(&packed_message, unpackedTestAllTypes_);
"\x82\x02\x01\x01" TestSerialization(&unpacked_message, unpackedTestUnpackedTypes_);
"\x8A\x02\x01\x01" TestParsing(&unpacked_message, packedTestUnpackedTypes_);
"\x92\x02\x01\x01" TestParsing(&unpacked_message, unpackedTestUnpackedTypes_);
"\x9A\x02\x01\x02"
"\xA2\x02\x01\x02"
"\xAA\x02\x04\x01\x00\x00\x00"
"\xB2\x02\x08\x01\x00\x00\x00\x00\x00\x00\x00"
"\xBA\x02\x04\x01\x00\x00\x00"
"\xC2\x02\x08\x01\x00\x00\x00\x00\x00\x00\x00"
"\xCA\x02\x04\x00\x00\x80\x3f"
"\xD2\x02\x08\x00\x00\x00\x00\x00\x00\xf0\x3f"
"\xDA\x02\x01\x01"
"\x9A\x03\x01\x01",
86);
const string unpackedExpected(
"\x08\x01"
"\x10\x01"
"\x18\x01"
"\x20\x01"
"\x28\x02"
"\x30\x02"
"\x3D\x01\x00\x00\x00"
"\x41\x01\x00\x00\x00\x00\x00\x00\x00"
"\x4D\x01\x00\x00\x00"
"\x51\x01\x00\x00\x00\x00\x00\x00\x00"
"\x5D\x00\x00\x80\x3f"
"\x61\x00\x00\x00\x00\x00\x00\xf0\x3f"
"\x68\x01"
"\x70\x01",
58);
if (GetParam()) {
TestProto3PrimitiveRepeatedFields(&packed_message, packedExpected);
} else {
TestProto3PrimitiveRepeatedFields(&unpacked_message, unpackedExpected);
}
} }
class WireFormatInvalidInputTest : public testing::Test { class WireFormatInvalidInputTest : public testing::Test {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment