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