1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // Author: kenton@google.com (Kenton Varda)
32 
33 #include <string>
34 #include <iostream>
35 
36 #include <google/protobuf/stubs/common.h>
37 #include <google/protobuf/test_util_lite.h>
38 #include <google/protobuf/unittest_lite.pb.h>
39 #include <google/protobuf/io/coded_stream.h>
40 #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
41 #include <google/protobuf/wire_format_lite.h>
42 #include <google/protobuf/wire_format_lite_inl.h>
43 
44 using namespace std;
45 
46 namespace {
47 // Helper methods to test parsing merge behavior.
ExpectMessageMerged(const google::protobuf::unittest::TestAllTypesLite & message)48 void ExpectMessageMerged(const google::protobuf::unittest::TestAllTypesLite& message) {
49   GOOGLE_CHECK(message.optional_int32() == 3);
50   GOOGLE_CHECK(message.optional_int64() == 2);
51   GOOGLE_CHECK(message.optional_string() == "hello");
52 }
53 
AssignParsingMergeMessages(google::protobuf::unittest::TestAllTypesLite * msg1,google::protobuf::unittest::TestAllTypesLite * msg2,google::protobuf::unittest::TestAllTypesLite * msg3)54 void AssignParsingMergeMessages(
55     google::protobuf::unittest::TestAllTypesLite* msg1,
56     google::protobuf::unittest::TestAllTypesLite* msg2,
57     google::protobuf::unittest::TestAllTypesLite* msg3) {
58   msg1->set_optional_int32(1);
59   msg2->set_optional_int64(2);
60   msg3->set_optional_int32(3);
61   msg3->set_optional_string("hello");
62 }
63 
SetAllTypesInEmptyMessageUnknownFields(google::protobuf::unittest::TestEmptyMessageLite * empty_message)64 void SetAllTypesInEmptyMessageUnknownFields(
65     google::protobuf::unittest::TestEmptyMessageLite* empty_message) {
66   protobuf_unittest::TestAllTypesLite message;
67   google::protobuf::TestUtilLite::ExpectClear(message);
68   google::protobuf::TestUtilLite::SetAllFields(&message);
69   string data = message.SerializeAsString();
70   empty_message->ParseFromString(data);
71 }
72 
SetSomeTypesInEmptyMessageUnknownFields(google::protobuf::unittest::TestEmptyMessageLite * empty_message)73 void SetSomeTypesInEmptyMessageUnknownFields(
74     google::protobuf::unittest::TestEmptyMessageLite* empty_message) {
75   protobuf_unittest::TestAllTypesLite message;
76   google::protobuf::TestUtilLite::ExpectClear(message);
77   message.set_optional_int32(101);
78   message.set_optional_int64(102);
79   message.set_optional_uint32(103);
80   message.set_optional_uint64(104);
81   string data = message.SerializeAsString();
82   empty_message->ParseFromString(data);
83 }
84 
85 }  // namespace
86 
main(int argc,char * argv[])87 int main(int argc, char* argv[]) {
88   string data, data2, packed_data;
89 
90   {
91     protobuf_unittest::TestAllTypesLite message, message2, message3;
92     google::protobuf::TestUtilLite::ExpectClear(message);
93     google::protobuf::TestUtilLite::SetAllFields(&message);
94     message2.CopyFrom(message);
95     data = message.SerializeAsString();
96     message3.ParseFromString(data);
97     google::protobuf::TestUtilLite::ExpectAllFieldsSet(message);
98     google::protobuf::TestUtilLite::ExpectAllFieldsSet(message2);
99     google::protobuf::TestUtilLite::ExpectAllFieldsSet(message3);
100     google::protobuf::TestUtilLite::ModifyRepeatedFields(&message);
101     google::protobuf::TestUtilLite::ExpectRepeatedFieldsModified(message);
102     message.Clear();
103     google::protobuf::TestUtilLite::ExpectClear(message);
104   }
105 
106   {
107     protobuf_unittest::TestAllExtensionsLite message, message2, message3;
108     google::protobuf::TestUtilLite::ExpectExtensionsClear(message);
109     google::protobuf::TestUtilLite::SetAllExtensions(&message);
110     message2.CopyFrom(message);
111     string extensions_data = message.SerializeAsString();
112     message3.ParseFromString(extensions_data);
113     google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message);
114     google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message2);
115     google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message3);
116     google::protobuf::TestUtilLite::ModifyRepeatedExtensions(&message);
117     google::protobuf::TestUtilLite::ExpectRepeatedExtensionsModified(message);
118     message.Clear();
119     google::protobuf::TestUtilLite::ExpectExtensionsClear(message);
120   }
121 
122   {
123     protobuf_unittest::TestPackedTypesLite message, message2, message3;
124     google::protobuf::TestUtilLite::ExpectPackedClear(message);
125     google::protobuf::TestUtilLite::SetPackedFields(&message);
126     message2.CopyFrom(message);
127     packed_data = message.SerializeAsString();
128     message3.ParseFromString(packed_data);
129     google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message);
130     google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message2);
131     google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message3);
132     google::protobuf::TestUtilLite::ModifyPackedFields(&message);
133     google::protobuf::TestUtilLite::ExpectPackedFieldsModified(message);
134     message.Clear();
135     google::protobuf::TestUtilLite::ExpectPackedClear(message);
136   }
137 
138   {
139     protobuf_unittest::TestPackedExtensionsLite message, message2, message3;
140     google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message);
141     google::protobuf::TestUtilLite::SetPackedExtensions(&message);
142     message2.CopyFrom(message);
143     string packed_extensions_data = message.SerializeAsString();
144     GOOGLE_CHECK(packed_extensions_data == packed_data);
145     message3.ParseFromString(packed_extensions_data);
146     google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message);
147     google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message2);
148     google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message3);
149     google::protobuf::TestUtilLite::ModifyPackedExtensions(&message);
150     google::protobuf::TestUtilLite::ExpectPackedExtensionsModified(message);
151     message.Clear();
152     google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message);
153   }
154 
155   {
156     // Test that if an optional or required message/group field appears multiple
157     // times in the input, they need to be merged.
158     google::protobuf::unittest::TestParsingMergeLite::RepeatedFieldsGenerator generator;
159     google::protobuf::unittest::TestAllTypesLite* msg1;
160     google::protobuf::unittest::TestAllTypesLite* msg2;
161     google::protobuf::unittest::TestAllTypesLite* msg3;
162 
163 #define ASSIGN_REPEATED_FIELD(FIELD)                \
164   msg1 = generator.add_##FIELD();                   \
165   msg2 = generator.add_##FIELD();                   \
166   msg3 = generator.add_##FIELD();                   \
167   AssignParsingMergeMessages(msg1, msg2, msg3)
168 
169     ASSIGN_REPEATED_FIELD(field1);
170     ASSIGN_REPEATED_FIELD(field2);
171     ASSIGN_REPEATED_FIELD(field3);
172     ASSIGN_REPEATED_FIELD(ext1);
173     ASSIGN_REPEATED_FIELD(ext2);
174 
175 #undef ASSIGN_REPEATED_FIELD
176 #define ASSIGN_REPEATED_GROUP(FIELD)                \
177   msg1 = generator.add_##FIELD()->mutable_field1(); \
178   msg2 = generator.add_##FIELD()->mutable_field1(); \
179   msg3 = generator.add_##FIELD()->mutable_field1(); \
180   AssignParsingMergeMessages(msg1, msg2, msg3)
181 
182     ASSIGN_REPEATED_GROUP(group1);
183     ASSIGN_REPEATED_GROUP(group2);
184 
185 #undef ASSIGN_REPEATED_GROUP
186 
187     string buffer;
188     generator.SerializeToString(&buffer);
189     google::protobuf::unittest::TestParsingMergeLite parsing_merge;
190     parsing_merge.ParseFromString(buffer);
191 
192     // Required and optional fields should be merged.
193     ExpectMessageMerged(parsing_merge.required_all_types());
194     ExpectMessageMerged(parsing_merge.optional_all_types());
195     ExpectMessageMerged(
196         parsing_merge.optionalgroup().optional_group_all_types());
197     ExpectMessageMerged(parsing_merge.GetExtension(
198         google::protobuf::unittest::TestParsingMergeLite::optional_ext));
199 
200     // Repeated fields should not be merged.
201     GOOGLE_CHECK(parsing_merge.repeated_all_types_size() == 3);
202     GOOGLE_CHECK(parsing_merge.repeatedgroup_size() == 3);
203     GOOGLE_CHECK(parsing_merge.ExtensionSize(
204         google::protobuf::unittest::TestParsingMergeLite::repeated_ext) == 3);
205   }
206 
207   // Test unknown fields support for lite messages.
208   {
209     protobuf_unittest::TestAllTypesLite message, message2;
210     protobuf_unittest::TestEmptyMessageLite empty_message;
211     google::protobuf::TestUtilLite::ExpectClear(message);
212     google::protobuf::TestUtilLite::SetAllFields(&message);
213     data = message.SerializeAsString();
214     empty_message.ParseFromString(data);
215     data.clear();
216     data = empty_message.SerializeAsString();
217     message2.ParseFromString(data);
218     data = message2.SerializeAsString();
219     google::protobuf::TestUtilLite::ExpectAllFieldsSet(message2);
220     message.Clear();
221     google::protobuf::TestUtilLite::ExpectClear(message);
222   }
223 
224   {
225     protobuf_unittest::TestAllExtensionsLite message, message2;
226     protobuf_unittest::TestEmptyMessageLite empty_message;
227     google::protobuf::TestUtilLite::ExpectExtensionsClear(message);
228     google::protobuf::TestUtilLite::SetAllExtensions(&message);
229     data = message.SerializeAsString();
230     empty_message.ParseFromString(data);
231     data.clear();
232     data = empty_message.SerializeAsString();
233     message2.ParseFromString(data);
234     data = message2.SerializeAsString();
235     google::protobuf::TestUtilLite::ExpectAllExtensionsSet(message2);
236     message.Clear();
237     google::protobuf::TestUtilLite::ExpectExtensionsClear(message);
238   }
239 
240   {
241     protobuf_unittest::TestPackedTypesLite message, message2;
242     protobuf_unittest::TestEmptyMessageLite empty_message;
243     google::protobuf::TestUtilLite::ExpectPackedClear(message);
244     google::protobuf::TestUtilLite::SetPackedFields(&message);
245     data = message.SerializeAsString();
246     empty_message.ParseFromString(data);
247     data.clear();
248     data = empty_message.SerializeAsString();
249     message2.ParseFromString(data);
250     data = message2.SerializeAsString();
251     google::protobuf::TestUtilLite::ExpectPackedFieldsSet(message2);
252     message.Clear();
253     google::protobuf::TestUtilLite::ExpectPackedClear(message);
254   }
255 
256   {
257     protobuf_unittest::TestPackedExtensionsLite message, message2;
258     protobuf_unittest::TestEmptyMessageLite empty_message;
259     google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message);
260     google::protobuf::TestUtilLite::SetPackedExtensions(&message);
261     data = message.SerializeAsString();
262     empty_message.ParseFromString(data);
263     data.clear();
264     data = empty_message.SerializeAsString();
265     message2.ParseFromString(data);
266     data = message2.SerializeAsString();
267     google::protobuf::TestUtilLite::ExpectPackedExtensionsSet(message2);
268     message.Clear();
269     google::protobuf::TestUtilLite::ExpectPackedExtensionsClear(message);
270   }
271 
272   {
273     // Test Unknown fields swap
274     protobuf_unittest::TestEmptyMessageLite empty_message, empty_message2;
275     SetAllTypesInEmptyMessageUnknownFields(&empty_message);
276     SetSomeTypesInEmptyMessageUnknownFields(&empty_message2);
277     data = empty_message.SerializeAsString();
278     data2 = empty_message2.SerializeAsString();
279     empty_message.Swap(&empty_message2);
280     GOOGLE_CHECK_EQ(data, empty_message2.SerializeAsString());
281     GOOGLE_CHECK_EQ(data2, empty_message.SerializeAsString());
282   }
283 
284   {
285     // Test unknown fields swap with self
286     protobuf_unittest::TestEmptyMessageLite empty_message;
287     SetAllTypesInEmptyMessageUnknownFields(&empty_message);
288     data = empty_message.SerializeAsString();
289     empty_message.Swap(&empty_message);
290     GOOGLE_CHECK_EQ(data, empty_message.SerializeAsString());
291   }
292 
293   {
294     // Test MergeFrom with unknown fields
295     protobuf_unittest::TestAllTypesLite message, message2;
296     protobuf_unittest::TestEmptyMessageLite empty_message, empty_message2;
297     message.set_optional_int32(101);
298     message.add_repeated_int32(201);
299     message.set_optional_nested_enum(google::protobuf::unittest::TestAllTypesLite::BAZ);
300     message2.set_optional_int64(102);
301     message2.add_repeated_int64(202);
302     message2.set_optional_foreign_enum(google::protobuf::unittest::FOREIGN_LITE_BAZ);
303 
304     data = message.SerializeAsString();
305     empty_message.ParseFromString(data);
306     data = message2.SerializeAsString();
307     empty_message2.ParseFromString(data);
308     message.MergeFrom(message2);
309     empty_message.MergeFrom(empty_message2);
310 
311     data = empty_message.SerializeAsString();
312     message2.ParseFromString(data);
313     // We do not compare the serialized output of a normal message and a lite
314     // message because the order of fields do not match. We convert lite message
315     // back into normal message, then compare.
316     GOOGLE_CHECK_EQ(message.SerializeAsString(), message2.SerializeAsString());
317   }
318 
319   {
320     // Test unknown enum value
321     protobuf_unittest::TestAllTypesLite message;
322     string buffer;
323     {
324       google::protobuf::io::StringOutputStream output_stream(&buffer);
325       google::protobuf::io::CodedOutputStream coded_output(&output_stream);
326       google::protobuf::internal::WireFormatLite::WriteTag(
327           protobuf_unittest::TestAllTypesLite::kOptionalNestedEnumFieldNumber,
328           google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT, &coded_output);
329       coded_output.WriteVarint32(10);
330       google::protobuf::internal::WireFormatLite::WriteTag(
331           protobuf_unittest::TestAllTypesLite::kRepeatedNestedEnumFieldNumber,
332           google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT, &coded_output);
333       coded_output.WriteVarint32(20);
334     }
335     message.ParseFromString(buffer);
336     data = message.SerializeAsString();
337     GOOGLE_CHECK_EQ(data, buffer);
338   }
339 
340   {
341     // Test Clear with unknown fields
342     protobuf_unittest::TestEmptyMessageLite empty_message;
343     SetAllTypesInEmptyMessageUnknownFields(&empty_message);
344     empty_message.Clear();
345     GOOGLE_CHECK_EQ(0, empty_message.unknown_fields().size());
346   }
347 
348   cout << "PASS" << endl;
349   return 0;
350 }
351