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
44using namespace std;
45
46namespace {
47// Helper methods to test parsing merge behavior.
48void 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
54void 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
64void 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
73void 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
87int 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