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 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
34
35 #include <google/protobuf/stubs/casts.h>
36 #include <google/protobuf/stubs/strutil.h>
37 #include <google/protobuf/test_util.h>
38 #include <google/protobuf/test_util2.h>
39 #include <google/protobuf/unittest.pb.h>
40 #include <google/protobuf/unittest_mset.pb.h>
41 #include <google/protobuf/io/coded_stream.h>
42 #include <google/protobuf/io/zero_copy_stream_impl.h>
43 #include <google/protobuf/descriptor.pb.h>
44 #include <google/protobuf/arena.h>
45 #include <google/protobuf/descriptor.h>
46 #include <google/protobuf/dynamic_message.h>
47 #include <google/protobuf/extension_set.h>
48 #include <google/protobuf/wire_format.h>
49 #include <google/protobuf/stubs/logging.h>
50 #include <google/protobuf/stubs/common.h>
51 #include <google/protobuf/testing/googletest.h>
52 #include <gtest/gtest.h>
53 #include <google/protobuf/stubs/stl_util.h>
54
55 // Must be included last.
56 #include <google/protobuf/port_def.inc>
57
58
59 namespace google {
60 namespace protobuf {
61 namespace internal {
62 namespace {
63
64 using TestUtil::EqualsToSerialized;
65
66 // This test closely mirrors net/proto2/compiler/cpp/internal/unittest.cc
67 // except that it uses extensions rather than regular fields.
68
TEST(ExtensionSetTest,Defaults)69 TEST(ExtensionSetTest, Defaults) {
70 // Check that all default values are set correctly in the initial message.
71 unittest::TestAllExtensions message;
72
73 TestUtil::ExpectExtensionsClear(message);
74
75 // Messages should return pointers to default instances until first use.
76 // (This is not checked by ExpectClear() since it is not actually true after
77 // the fields have been set and then cleared.)
78 EXPECT_EQ(&unittest::OptionalGroup_extension::default_instance(),
79 &message.GetExtension(unittest::optionalgroup_extension));
80 EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(),
81 &message.GetExtension(unittest::optional_nested_message_extension));
82 EXPECT_EQ(
83 &unittest::ForeignMessage::default_instance(),
84 &message.GetExtension(unittest::optional_foreign_message_extension));
85 EXPECT_EQ(&unittest_import::ImportMessage::default_instance(),
86 &message.GetExtension(unittest::optional_import_message_extension));
87 }
88
TEST(ExtensionSetTest,Accessors)89 TEST(ExtensionSetTest, Accessors) {
90 // Set every field to a unique value then go back and check all those
91 // values.
92 unittest::TestAllExtensions message;
93
94 TestUtil::SetAllExtensions(&message);
95 TestUtil::ExpectAllExtensionsSet(message);
96
97 TestUtil::ModifyRepeatedExtensions(&message);
98 TestUtil::ExpectRepeatedExtensionsModified(message);
99 }
100
TEST(ExtensionSetTest,Clear)101 TEST(ExtensionSetTest, Clear) {
102 // Set every field to a unique value, clear the message, then check that
103 // it is cleared.
104 unittest::TestAllExtensions message;
105
106 TestUtil::SetAllExtensions(&message);
107 message.Clear();
108 TestUtil::ExpectExtensionsClear(message);
109
110 // Unlike with the defaults test, we do NOT expect that requesting embedded
111 // messages will return a pointer to the default instance. Instead, they
112 // should return the objects that were created when mutable_blah() was
113 // called.
114 EXPECT_NE(&unittest::OptionalGroup_extension::default_instance(),
115 &message.GetExtension(unittest::optionalgroup_extension));
116 EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
117 &message.GetExtension(unittest::optional_nested_message_extension));
118 EXPECT_NE(
119 &unittest::ForeignMessage::default_instance(),
120 &message.GetExtension(unittest::optional_foreign_message_extension));
121 EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
122 &message.GetExtension(unittest::optional_import_message_extension));
123
124 // Make sure setting stuff again after clearing works. (This takes slightly
125 // different code paths since the objects are reused.)
126 TestUtil::SetAllExtensions(&message);
127 TestUtil::ExpectAllExtensionsSet(message);
128 }
129
TEST(ExtensionSetTest,ClearOneField)130 TEST(ExtensionSetTest, ClearOneField) {
131 // Set every field to a unique value, then clear one value and insure that
132 // only that one value is cleared.
133 unittest::TestAllExtensions message;
134
135 TestUtil::SetAllExtensions(&message);
136 int64 original_value =
137 message.GetExtension(unittest::optional_int64_extension);
138
139 // Clear the field and make sure it shows up as cleared.
140 message.ClearExtension(unittest::optional_int64_extension);
141 EXPECT_FALSE(message.HasExtension(unittest::optional_int64_extension));
142 EXPECT_EQ(0, message.GetExtension(unittest::optional_int64_extension));
143
144 // Other adjacent fields should not be cleared.
145 EXPECT_TRUE(message.HasExtension(unittest::optional_int32_extension));
146 EXPECT_TRUE(message.HasExtension(unittest::optional_uint32_extension));
147
148 // Make sure if we set it again, then all fields are set.
149 message.SetExtension(unittest::optional_int64_extension, original_value);
150 TestUtil::ExpectAllExtensionsSet(message);
151 }
152
TEST(ExtensionSetTest,SetAllocatedExtension)153 TEST(ExtensionSetTest, SetAllocatedExtension) {
154 unittest::TestAllExtensions message;
155 EXPECT_FALSE(
156 message.HasExtension(unittest::optional_foreign_message_extension));
157 // Add a extension using SetAllocatedExtension
158 unittest::ForeignMessage* foreign_message = new unittest::ForeignMessage();
159 message.SetAllocatedExtension(unittest::optional_foreign_message_extension,
160 foreign_message);
161 EXPECT_TRUE(
162 message.HasExtension(unittest::optional_foreign_message_extension));
163 EXPECT_EQ(foreign_message, message.MutableExtension(
164 unittest::optional_foreign_message_extension));
165 EXPECT_EQ(foreign_message, &message.GetExtension(
166 unittest::optional_foreign_message_extension));
167
168 // SetAllocatedExtension should delete the previously existing extension.
169 // (We reply on unittest to check memory leaks for this case)
170 message.SetAllocatedExtension(unittest::optional_foreign_message_extension,
171 new unittest::ForeignMessage());
172
173 // SetAllocatedExtension with a NULL parameter is equivalent to ClearExtenion.
174 message.SetAllocatedExtension(unittest::optional_foreign_message_extension,
175 NULL);
176 EXPECT_FALSE(
177 message.HasExtension(unittest::optional_foreign_message_extension));
178 }
179
TEST(ExtensionSetTest,ReleaseExtension)180 TEST(ExtensionSetTest, ReleaseExtension) {
181 proto2_wireformat_unittest::TestMessageSet message;
182 EXPECT_FALSE(message.HasExtension(
183 unittest::TestMessageSetExtension1::message_set_extension));
184 // Add a extension using SetAllocatedExtension
185 unittest::TestMessageSetExtension1* extension =
186 new unittest::TestMessageSetExtension1();
187 message.SetAllocatedExtension(
188 unittest::TestMessageSetExtension1::message_set_extension, extension);
189 EXPECT_TRUE(message.HasExtension(
190 unittest::TestMessageSetExtension1::message_set_extension));
191 // Release the extension using ReleaseExtension
192 unittest::TestMessageSetExtension1* released_extension =
193 message.ReleaseExtension(
194 unittest::TestMessageSetExtension1::message_set_extension);
195 EXPECT_EQ(extension, released_extension);
196 EXPECT_FALSE(message.HasExtension(
197 unittest::TestMessageSetExtension1::message_set_extension));
198 // ReleaseExtension will return the underlying object even after
199 // ClearExtension is called.
200 message.SetAllocatedExtension(
201 unittest::TestMessageSetExtension1::message_set_extension, extension);
202 message.ClearExtension(
203 unittest::TestMessageSetExtension1::message_set_extension);
204 released_extension = message.ReleaseExtension(
205 unittest::TestMessageSetExtension1::message_set_extension);
206 EXPECT_TRUE(released_extension != NULL);
207 delete released_extension;
208 }
209
TEST(ExtensionSetTest,ArenaUnsafeArenaSetAllocatedAndRelease)210 TEST(ExtensionSetTest, ArenaUnsafeArenaSetAllocatedAndRelease) {
211 Arena arena;
212 unittest::TestAllExtensions* message =
213 Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
214 unittest::ForeignMessage extension;
215 message->UnsafeArenaSetAllocatedExtension(
216 unittest::optional_foreign_message_extension, &extension);
217 // No copy when set.
218 unittest::ForeignMessage* mutable_extension =
219 message->MutableExtension(unittest::optional_foreign_message_extension);
220 EXPECT_EQ(&extension, mutable_extension);
221 // No copy when unsafe released.
222 unittest::ForeignMessage* released_extension =
223 message->UnsafeArenaReleaseExtension(
224 unittest::optional_foreign_message_extension);
225 EXPECT_EQ(&extension, released_extension);
226 EXPECT_FALSE(
227 message->HasExtension(unittest::optional_foreign_message_extension));
228 // Set the ownership back and let the destructors run. It should not take
229 // ownership, so this should not crash.
230 message->UnsafeArenaSetAllocatedExtension(
231 unittest::optional_foreign_message_extension, &extension);
232 }
233
TEST(ExtensionSetTest,UnsafeArenaSetAllocatedAndRelease)234 TEST(ExtensionSetTest, UnsafeArenaSetAllocatedAndRelease) {
235 unittest::TestAllExtensions message;
236 unittest::ForeignMessage* extension = new unittest::ForeignMessage();
237 message.UnsafeArenaSetAllocatedExtension(
238 unittest::optional_foreign_message_extension, extension);
239 // No copy when set.
240 unittest::ForeignMessage* mutable_extension =
241 message.MutableExtension(unittest::optional_foreign_message_extension);
242 EXPECT_EQ(extension, mutable_extension);
243 // No copy when unsafe released.
244 unittest::ForeignMessage* released_extension =
245 message.UnsafeArenaReleaseExtension(
246 unittest::optional_foreign_message_extension);
247 EXPECT_EQ(extension, released_extension);
248 EXPECT_FALSE(
249 message.HasExtension(unittest::optional_foreign_message_extension));
250 // Set the ownership back and let the destructors run. It should take
251 // ownership, so this should not leak.
252 message.UnsafeArenaSetAllocatedExtension(
253 unittest::optional_foreign_message_extension, extension);
254 }
255
TEST(ExtensionSetTest,ArenaUnsafeArenaReleaseOfHeapAlloc)256 TEST(ExtensionSetTest, ArenaUnsafeArenaReleaseOfHeapAlloc) {
257 Arena arena;
258 unittest::TestAllExtensions* message =
259 Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
260 unittest::ForeignMessage* extension = new unittest::ForeignMessage;
261 message->SetAllocatedExtension(unittest::optional_foreign_message_extension,
262 extension);
263 // The arena should maintain ownership of the heap allocated proto because we
264 // used UnsafeArenaReleaseExtension. The leak checker will ensure this.
265 unittest::ForeignMessage* released_extension =
266 message->UnsafeArenaReleaseExtension(
267 unittest::optional_foreign_message_extension);
268 EXPECT_EQ(extension, released_extension);
269 EXPECT_FALSE(
270 message->HasExtension(unittest::optional_foreign_message_extension));
271 }
272
273
TEST(ExtensionSetTest,CopyFrom)274 TEST(ExtensionSetTest, CopyFrom) {
275 unittest::TestAllExtensions message1, message2;
276
277 TestUtil::SetAllExtensions(&message1);
278 message2.CopyFrom(message1);
279 TestUtil::ExpectAllExtensionsSet(message2);
280 message2.CopyFrom(message1); // exercise copy when fields already exist
281 TestUtil::ExpectAllExtensionsSet(message2);
282 }
283
TEST(ExtensionSetTest,CopyFromPacked)284 TEST(ExtensionSetTest, CopyFromPacked) {
285 unittest::TestPackedExtensions message1, message2;
286
287 TestUtil::SetPackedExtensions(&message1);
288 message2.CopyFrom(message1);
289 TestUtil::ExpectPackedExtensionsSet(message2);
290 message2.CopyFrom(message1); // exercise copy when fields already exist
291 TestUtil::ExpectPackedExtensionsSet(message2);
292 }
293
TEST(ExtensionSetTest,CopyFromUpcasted)294 TEST(ExtensionSetTest, CopyFromUpcasted) {
295 unittest::TestAllExtensions message1, message2;
296 const Message& upcasted_message = message1;
297
298 TestUtil::SetAllExtensions(&message1);
299 message2.CopyFrom(upcasted_message);
300 TestUtil::ExpectAllExtensionsSet(message2);
301 // exercise copy when fields already exist
302 message2.CopyFrom(upcasted_message);
303 TestUtil::ExpectAllExtensionsSet(message2);
304 }
305
TEST(ExtensionSetTest,SwapWithEmpty)306 TEST(ExtensionSetTest, SwapWithEmpty) {
307 unittest::TestAllExtensions message1, message2;
308 TestUtil::SetAllExtensions(&message1);
309
310 TestUtil::ExpectAllExtensionsSet(message1);
311 TestUtil::ExpectExtensionsClear(message2);
312 message1.Swap(&message2);
313 TestUtil::ExpectAllExtensionsSet(message2);
314 TestUtil::ExpectExtensionsClear(message1);
315 }
316
TEST(ExtensionSetTest,SwapWithSelf)317 TEST(ExtensionSetTest, SwapWithSelf) {
318 unittest::TestAllExtensions message;
319 TestUtil::SetAllExtensions(&message);
320
321 TestUtil::ExpectAllExtensionsSet(message);
322 message.Swap(&message);
323 TestUtil::ExpectAllExtensionsSet(message);
324 }
325
TEST(ExtensionSetTest,SwapExtension)326 TEST(ExtensionSetTest, SwapExtension) {
327 unittest::TestAllExtensions message1;
328 unittest::TestAllExtensions message2;
329
330 TestUtil::SetAllExtensions(&message1);
331 std::vector<const FieldDescriptor*> fields;
332
333 // Swap empty fields.
334 const Reflection* reflection = message1.GetReflection();
335 reflection->SwapFields(&message1, &message2, fields);
336 TestUtil::ExpectAllExtensionsSet(message1);
337 TestUtil::ExpectExtensionsClear(message2);
338
339 // Swap two extensions.
340 fields.push_back(reflection->FindKnownExtensionByNumber(12));
341 fields.push_back(reflection->FindKnownExtensionByNumber(25));
342 reflection->SwapFields(&message1, &message2, fields);
343
344 EXPECT_TRUE(message1.HasExtension(unittest::optional_int32_extension));
345 EXPECT_FALSE(message1.HasExtension(unittest::optional_double_extension));
346 EXPECT_FALSE(message1.HasExtension(unittest::optional_cord_extension));
347
348 EXPECT_FALSE(message2.HasExtension(unittest::optional_int32_extension));
349 EXPECT_TRUE(message2.HasExtension(unittest::optional_double_extension));
350 EXPECT_TRUE(message2.HasExtension(unittest::optional_cord_extension));
351 }
352
TEST(ExtensionSetTest,SwapExtensionWithEmpty)353 TEST(ExtensionSetTest, SwapExtensionWithEmpty) {
354 unittest::TestAllExtensions message1;
355 unittest::TestAllExtensions message2;
356 unittest::TestAllExtensions message3;
357
358 TestUtil::SetAllExtensions(&message3);
359
360 const Reflection* reflection = message3.GetReflection();
361 std::vector<const FieldDescriptor*> fields;
362 reflection->ListFields(message3, &fields);
363
364 reflection->SwapFields(&message1, &message2, fields);
365
366 TestUtil::ExpectExtensionsClear(message1);
367 TestUtil::ExpectExtensionsClear(message2);
368 }
369
TEST(ExtensionSetTest,SwapExtensionBothFull)370 TEST(ExtensionSetTest, SwapExtensionBothFull) {
371 unittest::TestAllExtensions message1;
372 unittest::TestAllExtensions message2;
373
374 TestUtil::SetAllExtensions(&message1);
375 TestUtil::SetAllExtensions(&message2);
376
377 const Reflection* reflection = message1.GetReflection();
378 std::vector<const FieldDescriptor*> fields;
379 reflection->ListFields(message1, &fields);
380
381 reflection->SwapFields(&message1, &message2, fields);
382
383 TestUtil::ExpectAllExtensionsSet(message1);
384 TestUtil::ExpectAllExtensionsSet(message2);
385 }
386
TEST(ExtensionSetTest,ArenaSetAllExtension)387 TEST(ExtensionSetTest, ArenaSetAllExtension) {
388 Arena arena1;
389 unittest::TestAllExtensions* message1 =
390 Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
391 TestUtil::SetAllExtensions(message1);
392 TestUtil::ExpectAllExtensionsSet(*message1);
393 }
394
TEST(ExtensionSetTest,ArenaCopyConstructor)395 TEST(ExtensionSetTest, ArenaCopyConstructor) {
396 Arena arena1;
397 unittest::TestAllExtensions* message1 =
398 Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
399 TestUtil::SetAllExtensions(message1);
400 unittest::TestAllExtensions message2(*message1);
401 arena1.Reset();
402 TestUtil::ExpectAllExtensionsSet(message2);
403 }
404
TEST(ExtensionSetTest,ArenaMergeFrom)405 TEST(ExtensionSetTest, ArenaMergeFrom) {
406 Arena arena1;
407 unittest::TestAllExtensions* message1 =
408 Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
409 TestUtil::SetAllExtensions(message1);
410 unittest::TestAllExtensions message2;
411 message2.MergeFrom(*message1);
412 arena1.Reset();
413 TestUtil::ExpectAllExtensionsSet(message2);
414 }
415
TEST(ExtensionSetTest,ArenaSetAllocatedMessageAndRelease)416 TEST(ExtensionSetTest, ArenaSetAllocatedMessageAndRelease) {
417 Arena arena;
418 unittest::TestAllExtensions* message =
419 Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
420 EXPECT_FALSE(
421 message->HasExtension(unittest::optional_foreign_message_extension));
422 // Add a extension using SetAllocatedExtension
423 unittest::ForeignMessage* foreign_message = new unittest::ForeignMessage();
424 message->SetAllocatedExtension(unittest::optional_foreign_message_extension,
425 foreign_message);
426 // foreign_message is now owned by the arena.
427 EXPECT_EQ(foreign_message, message->MutableExtension(
428 unittest::optional_foreign_message_extension));
429
430 // Underlying message is copied, and returned.
431 unittest::ForeignMessage* released_message =
432 message->ReleaseExtension(unittest::optional_foreign_message_extension);
433 delete released_message;
434 EXPECT_FALSE(
435 message->HasExtension(unittest::optional_foreign_message_extension));
436 }
437
TEST(ExtensionSetTest,SwapExtensionBothFullWithArena)438 TEST(ExtensionSetTest, SwapExtensionBothFullWithArena) {
439 Arena arena1;
440 std::unique_ptr<Arena> arena2(new Arena());
441
442 unittest::TestAllExtensions* message1 =
443 Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
444 unittest::TestAllExtensions* message2 =
445 Arena::CreateMessage<unittest::TestAllExtensions>(arena2.get());
446
447 TestUtil::SetAllExtensions(message1);
448 TestUtil::SetAllExtensions(message2);
449 message1->SetExtension(unittest::optional_int32_extension, 1);
450 message2->SetExtension(unittest::optional_int32_extension, 2);
451 message1->Swap(message2);
452 EXPECT_EQ(2, message1->GetExtension(unittest::optional_int32_extension));
453 EXPECT_EQ(1, message2->GetExtension(unittest::optional_int32_extension));
454 // Re-set the original values so ExpectAllExtensionsSet is happy.
455 message1->SetExtension(unittest::optional_int32_extension, 101);
456 message2->SetExtension(unittest::optional_int32_extension, 101);
457 TestUtil::ExpectAllExtensionsSet(*message1);
458 TestUtil::ExpectAllExtensionsSet(*message2);
459 arena2.reset(NULL);
460 TestUtil::ExpectAllExtensionsSet(*message1);
461 // Test corner cases, when one is empty and other is not.
462 Arena arena3, arena4;
463
464 unittest::TestAllExtensions* message3 =
465 Arena::CreateMessage<unittest::TestAllExtensions>(&arena3);
466 unittest::TestAllExtensions* message4 =
467 Arena::CreateMessage<unittest::TestAllExtensions>(&arena4);
468 TestUtil::SetAllExtensions(message3);
469 message3->Swap(message4);
470 arena3.Reset();
471 TestUtil::ExpectAllExtensionsSet(*message4);
472 }
473
TEST(ExtensionSetTest,SwapFieldsOfExtensionBothFullWithArena)474 TEST(ExtensionSetTest, SwapFieldsOfExtensionBothFullWithArena) {
475 Arena arena1;
476 Arena* arena2 = new Arena();
477
478 unittest::TestAllExtensions* message1 =
479 Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
480 unittest::TestAllExtensions* message2 =
481 Arena::CreateMessage<unittest::TestAllExtensions>(arena2);
482
483 TestUtil::SetAllExtensions(message1);
484 TestUtil::SetAllExtensions(message2);
485
486 const Reflection* reflection = message1->GetReflection();
487 std::vector<const FieldDescriptor*> fields;
488 reflection->ListFields(*message1, &fields);
489 reflection->SwapFields(message1, message2, fields);
490 TestUtil::ExpectAllExtensionsSet(*message1);
491 TestUtil::ExpectAllExtensionsSet(*message2);
492 delete arena2;
493 TestUtil::ExpectAllExtensionsSet(*message1);
494 }
495
TEST(ExtensionSetTest,SwapExtensionWithSelf)496 TEST(ExtensionSetTest, SwapExtensionWithSelf) {
497 unittest::TestAllExtensions message1;
498
499 TestUtil::SetAllExtensions(&message1);
500
501 std::vector<const FieldDescriptor*> fields;
502 const Reflection* reflection = message1.GetReflection();
503 reflection->ListFields(message1, &fields);
504 reflection->SwapFields(&message1, &message1, fields);
505
506 TestUtil::ExpectAllExtensionsSet(message1);
507 }
508
TEST(ExtensionSetTest,SerializationToArray)509 TEST(ExtensionSetTest, SerializationToArray) {
510 // Serialize as TestAllExtensions and parse as TestAllTypes to insure wire
511 // compatibility of extensions.
512 //
513 // This checks serialization to a flat array by explicitly reserving space in
514 // the string and calling the generated message's
515 // SerializeWithCachedSizesToArray.
516 unittest::TestAllExtensions source;
517 unittest::TestAllTypes destination;
518 TestUtil::SetAllExtensions(&source);
519 size_t size = source.ByteSizeLong();
520 std::string data;
521 data.resize(size);
522 uint8* target = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&data));
523 uint8* end = source.SerializeWithCachedSizesToArray(target);
524 EXPECT_EQ(size, end - target);
525 EXPECT_TRUE(destination.ParseFromString(data));
526 TestUtil::ExpectAllFieldsSet(destination);
527 }
528
TEST(ExtensionSetTest,SerializationToStream)529 TEST(ExtensionSetTest, SerializationToStream) {
530 // Serialize as TestAllExtensions and parse as TestAllTypes to insure wire
531 // compatibility of extensions.
532 //
533 // This checks serialization to an output stream by creating an array output
534 // stream that can only buffer 1 byte at a time - this prevents the message
535 // from ever jumping to the fast path, ensuring that serialization happens via
536 // the CodedOutputStream.
537 unittest::TestAllExtensions source;
538 unittest::TestAllTypes destination;
539 TestUtil::SetAllExtensions(&source);
540 size_t size = source.ByteSizeLong();
541 std::string data;
542 data.resize(size);
543 {
544 io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
545 io::CodedOutputStream output_stream(&array_stream);
546 source.SerializeWithCachedSizes(&output_stream);
547 ASSERT_FALSE(output_stream.HadError());
548 }
549 EXPECT_TRUE(destination.ParseFromString(data));
550 TestUtil::ExpectAllFieldsSet(destination);
551 }
552
TEST(ExtensionSetTest,PackedSerializationToArray)553 TEST(ExtensionSetTest, PackedSerializationToArray) {
554 // Serialize as TestPackedExtensions and parse as TestPackedTypes to insure
555 // wire compatibility of extensions.
556 //
557 // This checks serialization to a flat array by explicitly reserving space in
558 // the string and calling the generated message's
559 // SerializeWithCachedSizesToArray.
560 unittest::TestPackedExtensions source;
561 unittest::TestPackedTypes destination;
562 TestUtil::SetPackedExtensions(&source);
563 size_t size = source.ByteSizeLong();
564 std::string data;
565 data.resize(size);
566 uint8* target = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&data));
567 uint8* end = source.SerializeWithCachedSizesToArray(target);
568 EXPECT_EQ(size, end - target);
569 EXPECT_TRUE(destination.ParseFromString(data));
570 TestUtil::ExpectPackedFieldsSet(destination);
571 }
572
TEST(ExtensionSetTest,PackedSerializationToStream)573 TEST(ExtensionSetTest, PackedSerializationToStream) {
574 // Serialize as TestPackedExtensions and parse as TestPackedTypes to insure
575 // wire compatibility of extensions.
576 //
577 // This checks serialization to an output stream by creating an array output
578 // stream that can only buffer 1 byte at a time - this prevents the message
579 // from ever jumping to the fast path, ensuring that serialization happens via
580 // the CodedOutputStream.
581 unittest::TestPackedExtensions source;
582 unittest::TestPackedTypes destination;
583 TestUtil::SetPackedExtensions(&source);
584 size_t size = source.ByteSizeLong();
585 std::string data;
586 data.resize(size);
587 {
588 io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
589 io::CodedOutputStream output_stream(&array_stream);
590 source.SerializeWithCachedSizes(&output_stream);
591 ASSERT_FALSE(output_stream.HadError());
592 }
593 EXPECT_TRUE(destination.ParseFromString(data));
594 TestUtil::ExpectPackedFieldsSet(destination);
595 }
596
TEST(ExtensionSetTest,NestedExtensionGroup)597 TEST(ExtensionSetTest, NestedExtensionGroup) {
598 // Serialize as TestGroup and parse as TestGroupExtension.
599 unittest::TestGroup source;
600 unittest::TestGroupExtension destination;
601 std::string data;
602
603 source.mutable_optionalgroup()->set_a(117);
604 source.set_optional_foreign_enum(unittest::FOREIGN_BAZ);
605 source.SerializeToString(&data);
606 EXPECT_TRUE(destination.ParseFromString(data));
607 EXPECT_TRUE(
608 destination
609 .GetExtension(unittest::TestNestedExtension::optionalgroup_extension)
610 .has_a());
611 EXPECT_EQ(117, destination
612 .GetExtension(
613 unittest::TestNestedExtension::optionalgroup_extension)
614 .a());
615 EXPECT_TRUE(destination.HasExtension(
616 unittest::TestNestedExtension::optional_foreign_enum_extension));
617 EXPECT_EQ(
618 unittest::FOREIGN_BAZ,
619 destination.GetExtension(
620 unittest::TestNestedExtension::optional_foreign_enum_extension));
621 }
622
TEST(ExtensionSetTest,Parsing)623 TEST(ExtensionSetTest, Parsing) {
624 // Serialize as TestAllTypes and parse as TestAllExtensions.
625 unittest::TestAllTypes source;
626 unittest::TestAllExtensions destination;
627 std::string data;
628
629 TestUtil::SetAllFields(&source);
630 source.SerializeToString(&data);
631 EXPECT_TRUE(destination.ParseFromString(data));
632 TestUtil::SetOneofFields(&destination);
633 TestUtil::ExpectAllExtensionsSet(destination);
634 }
635
TEST(ExtensionSetTest,PackedParsing)636 TEST(ExtensionSetTest, PackedParsing) {
637 // Serialize as TestPackedTypes and parse as TestPackedExtensions.
638 unittest::TestPackedTypes source;
639 unittest::TestPackedExtensions destination;
640 std::string data;
641
642 TestUtil::SetPackedFields(&source);
643 source.SerializeToString(&data);
644 EXPECT_TRUE(destination.ParseFromString(data));
645 TestUtil::ExpectPackedExtensionsSet(destination);
646 }
647
TEST(ExtensionSetTest,PackedToUnpackedParsing)648 TEST(ExtensionSetTest, PackedToUnpackedParsing) {
649 unittest::TestPackedTypes source;
650 unittest::TestUnpackedExtensions destination;
651 std::string data;
652
653 TestUtil::SetPackedFields(&source);
654 source.SerializeToString(&data);
655 EXPECT_TRUE(destination.ParseFromString(data));
656 TestUtil::ExpectUnpackedExtensionsSet(destination);
657
658 // Reserialize
659 unittest::TestUnpackedTypes unpacked;
660 TestUtil::SetUnpackedFields(&unpacked);
661 // Serialized proto has to be the same size and parsed to the same message.
662 EXPECT_EQ(unpacked.SerializeAsString().size(),
663 destination.SerializeAsString().size());
664 EXPECT_TRUE(EqualsToSerialized(unpacked, destination.SerializeAsString()));
665
666 // Make sure we can add extensions.
667 destination.AddExtension(unittest::unpacked_int32_extension, 1);
668 destination.AddExtension(unittest::unpacked_enum_extension,
669 protobuf_unittest::FOREIGN_BAR);
670 }
671
TEST(ExtensionSetTest,UnpackedToPackedParsing)672 TEST(ExtensionSetTest, UnpackedToPackedParsing) {
673 unittest::TestUnpackedTypes source;
674 unittest::TestPackedExtensions destination;
675 std::string data;
676
677 TestUtil::SetUnpackedFields(&source);
678 source.SerializeToString(&data);
679 EXPECT_TRUE(destination.ParseFromString(data));
680 TestUtil::ExpectPackedExtensionsSet(destination);
681
682 // Reserialize
683 unittest::TestPackedTypes packed;
684 TestUtil::SetPackedFields(&packed);
685 // Serialized proto has to be the same size and parsed to the same message.
686 EXPECT_EQ(packed.SerializeAsString().size(),
687 destination.SerializeAsString().size());
688 EXPECT_TRUE(EqualsToSerialized(packed, destination.SerializeAsString()));
689
690 // Make sure we can add extensions.
691 destination.AddExtension(unittest::packed_int32_extension, 1);
692 destination.AddExtension(unittest::packed_enum_extension,
693 protobuf_unittest::FOREIGN_BAR);
694 }
695
TEST(ExtensionSetTest,IsInitialized)696 TEST(ExtensionSetTest, IsInitialized) {
697 // Test that IsInitialized() returns false if required fields in nested
698 // extensions are missing.
699 unittest::TestAllExtensions message;
700
701 EXPECT_TRUE(message.IsInitialized());
702
703 message.MutableExtension(unittest::TestRequired::single);
704 EXPECT_FALSE(message.IsInitialized());
705
706 message.MutableExtension(unittest::TestRequired::single)->set_a(1);
707 EXPECT_FALSE(message.IsInitialized());
708 message.MutableExtension(unittest::TestRequired::single)->set_b(2);
709 EXPECT_FALSE(message.IsInitialized());
710 message.MutableExtension(unittest::TestRequired::single)->set_c(3);
711 EXPECT_TRUE(message.IsInitialized());
712
713 message.AddExtension(unittest::TestRequired::multi);
714 EXPECT_FALSE(message.IsInitialized());
715
716 message.MutableExtension(unittest::TestRequired::multi, 0)->set_a(1);
717 EXPECT_FALSE(message.IsInitialized());
718 message.MutableExtension(unittest::TestRequired::multi, 0)->set_b(2);
719 EXPECT_FALSE(message.IsInitialized());
720 message.MutableExtension(unittest::TestRequired::multi, 0)->set_c(3);
721 EXPECT_TRUE(message.IsInitialized());
722 }
723
TEST(ExtensionSetTest,MutableString)724 TEST(ExtensionSetTest, MutableString) {
725 // Test the mutable string accessors.
726 unittest::TestAllExtensions message;
727
728 message.MutableExtension(unittest::optional_string_extension)->assign("foo");
729 EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension));
730 EXPECT_EQ("foo", message.GetExtension(unittest::optional_string_extension));
731
732 message.AddExtension(unittest::repeated_string_extension)->assign("bar");
733 ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_string_extension));
734 EXPECT_EQ("bar",
735 message.GetExtension(unittest::repeated_string_extension, 0));
736 }
737
TEST(ExtensionSetTest,SpaceUsedExcludingSelf)738 TEST(ExtensionSetTest, SpaceUsedExcludingSelf) {
739 // Scalar primitive extensions should increase the extension set size by a
740 // minimum of the size of the primitive type.
741 #define TEST_SCALAR_EXTENSIONS_SPACE_USED(type, value) \
742 do { \
743 unittest::TestAllExtensions message; \
744 const int base_size = message.SpaceUsedLong(); \
745 message.SetExtension(unittest::optional_##type##_extension, value); \
746 int min_expected_size = \
747 base_size + \
748 sizeof(message.GetExtension(unittest::optional_##type##_extension)); \
749 EXPECT_LE(min_expected_size, message.SpaceUsedLong()); \
750 } while (0)
751
752 TEST_SCALAR_EXTENSIONS_SPACE_USED(int32, 101);
753 TEST_SCALAR_EXTENSIONS_SPACE_USED(int64, 102);
754 TEST_SCALAR_EXTENSIONS_SPACE_USED(uint32, 103);
755 TEST_SCALAR_EXTENSIONS_SPACE_USED(uint64, 104);
756 TEST_SCALAR_EXTENSIONS_SPACE_USED(sint32, 105);
757 TEST_SCALAR_EXTENSIONS_SPACE_USED(sint64, 106);
758 TEST_SCALAR_EXTENSIONS_SPACE_USED(fixed32, 107);
759 TEST_SCALAR_EXTENSIONS_SPACE_USED(fixed64, 108);
760 TEST_SCALAR_EXTENSIONS_SPACE_USED(sfixed32, 109);
761 TEST_SCALAR_EXTENSIONS_SPACE_USED(sfixed64, 110);
762 TEST_SCALAR_EXTENSIONS_SPACE_USED(float, 111);
763 TEST_SCALAR_EXTENSIONS_SPACE_USED(double, 112);
764 TEST_SCALAR_EXTENSIONS_SPACE_USED(bool, true);
765 #undef TEST_SCALAR_EXTENSIONS_SPACE_USED
766 {
767 unittest::TestAllExtensions message;
768 const int base_size = message.SpaceUsedLong();
769 message.SetExtension(unittest::optional_nested_enum_extension,
770 unittest::TestAllTypes::FOO);
771 int min_expected_size =
772 base_size +
773 sizeof(message.GetExtension(unittest::optional_nested_enum_extension));
774 EXPECT_LE(min_expected_size, message.SpaceUsedLong());
775 }
776 {
777 // Strings may cause extra allocations depending on their length; ensure
778 // that gets included as well.
779 unittest::TestAllExtensions message;
780 const int base_size = message.SpaceUsedLong();
781 const std::string s(
782 "this is a fairly large string that will cause some "
783 "allocation in order to store it in the extension");
784 message.SetExtension(unittest::optional_string_extension, s);
785 int min_expected_size = base_size + s.length();
786 EXPECT_LE(min_expected_size, message.SpaceUsedLong());
787 }
788 {
789 // Messages also have additional allocation that need to be counted.
790 unittest::TestAllExtensions message;
791 const int base_size = message.SpaceUsedLong();
792 unittest::ForeignMessage foreign;
793 foreign.set_c(42);
794 message.MutableExtension(unittest::optional_foreign_message_extension)
795 ->CopyFrom(foreign);
796 int min_expected_size = base_size + foreign.SpaceUsedLong();
797 EXPECT_LE(min_expected_size, message.SpaceUsedLong());
798 }
799
800 // Repeated primitive extensions will increase space used by at least a
801 // RepeatedField<T>, and will cause additional allocations when the array
802 // gets too big for the initial space.
803 // This macro:
804 // - Adds a value to the repeated extension, then clears it, establishing
805 // the base size.
806 // - Adds a small number of values, testing that it doesn't increase the
807 // SpaceUsedLong()
808 // - Adds a large number of values (requiring allocation in the repeated
809 // field), and ensures that that allocation is included in SpaceUsedLong()
810 #define TEST_REPEATED_EXTENSIONS_SPACE_USED(type, cpptype, value) \
811 do { \
812 unittest::TestAllExtensions message; \
813 const size_t base_size = message.SpaceUsedLong(); \
814 size_t min_expected_size = sizeof(RepeatedField<cpptype>) + base_size; \
815 message.AddExtension(unittest::repeated_##type##_extension, value); \
816 message.ClearExtension(unittest::repeated_##type##_extension); \
817 const size_t empty_repeated_field_size = message.SpaceUsedLong(); \
818 EXPECT_LE(min_expected_size, empty_repeated_field_size) << #type; \
819 message.AddExtension(unittest::repeated_##type##_extension, value); \
820 message.AddExtension(unittest::repeated_##type##_extension, value); \
821 EXPECT_EQ(empty_repeated_field_size, message.SpaceUsedLong()) << #type; \
822 message.ClearExtension(unittest::repeated_##type##_extension); \
823 const size_t old_capacity = \
824 message.GetRepeatedExtension(unittest::repeated_##type##_extension) \
825 .Capacity(); \
826 EXPECT_GE(old_capacity, kRepeatedFieldLowerClampLimit); \
827 for (int i = 0; i < 16; ++i) { \
828 message.AddExtension(unittest::repeated_##type##_extension, value); \
829 } \
830 int expected_size = \
831 sizeof(cpptype) * \
832 (message \
833 .GetRepeatedExtension(unittest::repeated_##type##_extension) \
834 .Capacity() - \
835 old_capacity) + \
836 empty_repeated_field_size; \
837 EXPECT_LE(expected_size, message.SpaceUsedLong()) << #type; \
838 } while (0)
839
840 TEST_REPEATED_EXTENSIONS_SPACE_USED(int32, int32, 101);
841 TEST_REPEATED_EXTENSIONS_SPACE_USED(int64, int64, 102);
842 TEST_REPEATED_EXTENSIONS_SPACE_USED(uint32, uint32, 103);
843 TEST_REPEATED_EXTENSIONS_SPACE_USED(uint64, uint64, 104);
844 TEST_REPEATED_EXTENSIONS_SPACE_USED(sint32, int32, 105);
845 TEST_REPEATED_EXTENSIONS_SPACE_USED(sint64, int64, 106);
846 TEST_REPEATED_EXTENSIONS_SPACE_USED(fixed32, uint32, 107);
847 TEST_REPEATED_EXTENSIONS_SPACE_USED(fixed64, uint64, 108);
848 TEST_REPEATED_EXTENSIONS_SPACE_USED(sfixed32, int32, 109);
849 TEST_REPEATED_EXTENSIONS_SPACE_USED(sfixed64, int64, 110);
850 TEST_REPEATED_EXTENSIONS_SPACE_USED(float, float, 111);
851 TEST_REPEATED_EXTENSIONS_SPACE_USED(double, double, 112);
852 TEST_REPEATED_EXTENSIONS_SPACE_USED(bool, bool, true);
853 TEST_REPEATED_EXTENSIONS_SPACE_USED(nested_enum, int,
854 unittest::TestAllTypes::FOO);
855 #undef TEST_REPEATED_EXTENSIONS_SPACE_USED
856 // Repeated strings
857 {
858 unittest::TestAllExtensions message;
859 const size_t base_size = message.SpaceUsedLong();
860 size_t min_expected_size =
861 sizeof(RepeatedPtrField<std::string>) + base_size;
862 const std::string value(256, 'x');
863 // Once items are allocated, they may stick around even when cleared so
864 // without the hardcore memory management accessors there isn't a notion of
865 // the empty repeated field memory usage as there is with primitive types.
866 for (int i = 0; i < 16; ++i) {
867 message.AddExtension(unittest::repeated_string_extension, value);
868 }
869 min_expected_size +=
870 (sizeof(value) + value.size()) * (16 - kRepeatedFieldLowerClampLimit);
871 EXPECT_LE(min_expected_size, message.SpaceUsedLong());
872 }
873 // Repeated messages
874 {
875 unittest::TestAllExtensions message;
876 const size_t base_size = message.SpaceUsedLong();
877 size_t min_expected_size =
878 sizeof(RepeatedPtrField<unittest::ForeignMessage>) + base_size;
879 unittest::ForeignMessage prototype;
880 prototype.set_c(2);
881 for (int i = 0; i < 16; ++i) {
882 message.AddExtension(unittest::repeated_foreign_message_extension)
883 ->CopyFrom(prototype);
884 }
885 min_expected_size +=
886 (16 - kRepeatedFieldLowerClampLimit) * prototype.SpaceUsedLong();
887 EXPECT_LE(min_expected_size, message.SpaceUsedLong());
888 }
889 }
890
891 // N.B.: We do not test range-based for here because we remain C++03 compatible.
892 template <typename T, typename M, typename ID>
SumAllExtensions(const M & message,ID extension,T zero)893 inline T SumAllExtensions(const M& message, ID extension, T zero) {
894 T sum = zero;
895 typename RepeatedField<T>::const_iterator iter =
896 message.GetRepeatedExtension(extension).begin();
897 typename RepeatedField<T>::const_iterator end =
898 message.GetRepeatedExtension(extension).end();
899 for (; iter != end; ++iter) {
900 sum += *iter;
901 }
902 return sum;
903 }
904
905 template <typename T, typename M, typename ID>
IncAllExtensions(M * message,ID extension,T val)906 inline void IncAllExtensions(M* message, ID extension, T val) {
907 typename RepeatedField<T>::iterator iter =
908 message->MutableRepeatedExtension(extension)->begin();
909 typename RepeatedField<T>::iterator end =
910 message->MutableRepeatedExtension(extension)->end();
911 for (; iter != end; ++iter) {
912 *iter += val;
913 }
914 }
915
TEST(ExtensionSetTest,RepeatedFields)916 TEST(ExtensionSetTest, RepeatedFields) {
917 unittest::TestAllExtensions message;
918
919 // Test empty repeated-field case (b/12926163)
920 ASSERT_EQ(
921 0,
922 message.GetRepeatedExtension(unittest::repeated_int32_extension).size());
923 ASSERT_EQ(
924 0, message.GetRepeatedExtension(unittest::repeated_nested_enum_extension)
925 .size());
926 ASSERT_EQ(
927 0,
928 message.GetRepeatedExtension(unittest::repeated_string_extension).size());
929 ASSERT_EQ(
930 0,
931 message.GetRepeatedExtension(unittest::repeated_nested_message_extension)
932 .size());
933
934 unittest::TestAllTypes::NestedMessage nested_message;
935 nested_message.set_bb(42);
936 unittest::TestAllTypes::NestedEnum nested_enum =
937 unittest::TestAllTypes::NestedEnum_MIN;
938
939 for (int i = 0; i < 10; ++i) {
940 message.AddExtension(unittest::repeated_int32_extension, 1);
941 message.AddExtension(unittest::repeated_int64_extension, 2);
942 message.AddExtension(unittest::repeated_uint32_extension, 3);
943 message.AddExtension(unittest::repeated_uint64_extension, 4);
944 message.AddExtension(unittest::repeated_sint32_extension, 5);
945 message.AddExtension(unittest::repeated_sint64_extension, 6);
946 message.AddExtension(unittest::repeated_fixed32_extension, 7);
947 message.AddExtension(unittest::repeated_fixed64_extension, 8);
948 message.AddExtension(unittest::repeated_sfixed32_extension, 7);
949 message.AddExtension(unittest::repeated_sfixed64_extension, 8);
950 message.AddExtension(unittest::repeated_float_extension, 9.0);
951 message.AddExtension(unittest::repeated_double_extension, 10.0);
952 message.AddExtension(unittest::repeated_bool_extension, true);
953 message.AddExtension(unittest::repeated_nested_enum_extension, nested_enum);
954 message.AddExtension(unittest::repeated_string_extension,
955 std::string("test"));
956 message.AddExtension(unittest::repeated_bytes_extension,
957 std::string("test\xFF"));
958 message.AddExtension(unittest::repeated_nested_message_extension)
959 ->CopyFrom(nested_message);
960 message.AddExtension(unittest::repeated_nested_enum_extension, nested_enum);
961 }
962
963 ASSERT_EQ(10, SumAllExtensions<int32>(message,
964 unittest::repeated_int32_extension, 0));
965 IncAllExtensions<int32>(&message, unittest::repeated_int32_extension, 1);
966 ASSERT_EQ(20, SumAllExtensions<int32>(message,
967 unittest::repeated_int32_extension, 0));
968
969 ASSERT_EQ(20, SumAllExtensions<int64>(message,
970 unittest::repeated_int64_extension, 0));
971 IncAllExtensions<int64>(&message, unittest::repeated_int64_extension, 1);
972 ASSERT_EQ(30, SumAllExtensions<int64>(message,
973 unittest::repeated_int64_extension, 0));
974
975 ASSERT_EQ(30, SumAllExtensions<uint32>(
976 message, unittest::repeated_uint32_extension, 0));
977 IncAllExtensions<uint32>(&message, unittest::repeated_uint32_extension, 1);
978 ASSERT_EQ(40, SumAllExtensions<uint32>(
979 message, unittest::repeated_uint32_extension, 0));
980
981 ASSERT_EQ(40, SumAllExtensions<uint64>(
982 message, unittest::repeated_uint64_extension, 0));
983 IncAllExtensions<uint64>(&message, unittest::repeated_uint64_extension, 1);
984 ASSERT_EQ(50, SumAllExtensions<uint64>(
985 message, unittest::repeated_uint64_extension, 0));
986
987 ASSERT_EQ(50, SumAllExtensions<int32>(
988 message, unittest::repeated_sint32_extension, 0));
989 IncAllExtensions<int32>(&message, unittest::repeated_sint32_extension, 1);
990 ASSERT_EQ(60, SumAllExtensions<int32>(
991 message, unittest::repeated_sint32_extension, 0));
992
993 ASSERT_EQ(60, SumAllExtensions<int64>(
994 message, unittest::repeated_sint64_extension, 0));
995 IncAllExtensions<int64>(&message, unittest::repeated_sint64_extension, 1);
996 ASSERT_EQ(70, SumAllExtensions<int64>(
997 message, unittest::repeated_sint64_extension, 0));
998
999 ASSERT_EQ(70, SumAllExtensions<uint32>(
1000 message, unittest::repeated_fixed32_extension, 0));
1001 IncAllExtensions<uint32>(&message, unittest::repeated_fixed32_extension, 1);
1002 ASSERT_EQ(80, SumAllExtensions<uint32>(
1003 message, unittest::repeated_fixed32_extension, 0));
1004
1005 ASSERT_EQ(80, SumAllExtensions<uint64>(
1006 message, unittest::repeated_fixed64_extension, 0));
1007 IncAllExtensions<uint64>(&message, unittest::repeated_fixed64_extension, 1);
1008 ASSERT_EQ(90, SumAllExtensions<uint64>(
1009 message, unittest::repeated_fixed64_extension, 0));
1010
1011 // Usually, floating-point arithmetic cannot be trusted to be exact, so it is
1012 // a Bad Idea to assert equality in a test like this. However, we're dealing
1013 // with integers with a small number of significant mantissa bits, so we
1014 // should actually have exact precision here.
1015 ASSERT_EQ(90, SumAllExtensions<float>(message,
1016 unittest::repeated_float_extension, 0));
1017 IncAllExtensions<float>(&message, unittest::repeated_float_extension, 1);
1018 ASSERT_EQ(100, SumAllExtensions<float>(
1019 message, unittest::repeated_float_extension, 0));
1020
1021 ASSERT_EQ(100, SumAllExtensions<double>(
1022 message, unittest::repeated_double_extension, 0));
1023 IncAllExtensions<double>(&message, unittest::repeated_double_extension, 1);
1024 ASSERT_EQ(110, SumAllExtensions<double>(
1025 message, unittest::repeated_double_extension, 0));
1026
1027 RepeatedPtrField<std::string>::iterator string_iter;
1028 RepeatedPtrField<std::string>::iterator string_end;
1029 for (string_iter =
1030 message
1031 .MutableRepeatedExtension(unittest::repeated_string_extension)
1032 ->begin(),
1033 string_end =
1034 message
1035 .MutableRepeatedExtension(unittest::repeated_string_extension)
1036 ->end();
1037 string_iter != string_end; ++string_iter) {
1038 *string_iter += "test";
1039 }
1040 RepeatedPtrField<std::string>::const_iterator string_const_iter;
1041 RepeatedPtrField<std::string>::const_iterator string_const_end;
1042 for (string_const_iter =
1043 message.GetRepeatedExtension(unittest::repeated_string_extension)
1044 .begin(),
1045 string_const_end =
1046 message.GetRepeatedExtension(unittest::repeated_string_extension)
1047 .end();
1048 string_iter != string_end; ++string_iter) {
1049 ASSERT_TRUE(*string_iter == "testtest");
1050 }
1051
1052 RepeatedField<unittest::TestAllTypes_NestedEnum>::iterator enum_iter;
1053 RepeatedField<unittest::TestAllTypes_NestedEnum>::iterator enum_end;
1054 for (enum_iter = message
1055 .MutableRepeatedExtension(
1056 unittest::repeated_nested_enum_extension)
1057 ->begin(),
1058 enum_end = message
1059 .MutableRepeatedExtension(
1060 unittest::repeated_nested_enum_extension)
1061 ->end();
1062 enum_iter != enum_end; ++enum_iter) {
1063 *enum_iter = unittest::TestAllTypes::NestedEnum_MAX;
1064 }
1065 RepeatedField<unittest::TestAllTypes_NestedEnum>::const_iterator
1066 enum_const_iter;
1067 RepeatedField<unittest::TestAllTypes_NestedEnum>::const_iterator
1068 enum_const_end;
1069 for (enum_const_iter =
1070 message
1071 .GetRepeatedExtension(unittest::repeated_nested_enum_extension)
1072 .begin(),
1073 enum_const_end =
1074 message
1075 .GetRepeatedExtension(unittest::repeated_nested_enum_extension)
1076 .end();
1077 enum_const_iter != enum_const_end; ++enum_const_iter) {
1078 ASSERT_EQ(*enum_const_iter, unittest::TestAllTypes::NestedEnum_MAX);
1079 }
1080
1081 RepeatedPtrField<unittest::TestAllTypes_NestedMessage>::iterator msg_iter;
1082 RepeatedPtrField<unittest::TestAllTypes_NestedMessage>::iterator msg_end;
1083 for (msg_iter = message
1084 .MutableRepeatedExtension(
1085 unittest::repeated_nested_message_extension)
1086 ->begin(),
1087 msg_end = message
1088 .MutableRepeatedExtension(
1089 unittest::repeated_nested_message_extension)
1090 ->end();
1091 msg_iter != msg_end; ++msg_iter) {
1092 msg_iter->set_bb(1234);
1093 }
1094 RepeatedPtrField<unittest::TestAllTypes_NestedMessage>::const_iterator
1095 msg_const_iter;
1096 RepeatedPtrField<unittest::TestAllTypes_NestedMessage>::const_iterator
1097 msg_const_end;
1098 for (msg_const_iter = message
1099 .GetRepeatedExtension(
1100 unittest::repeated_nested_message_extension)
1101 .begin(),
1102 msg_const_end = message
1103 .GetRepeatedExtension(
1104 unittest::repeated_nested_message_extension)
1105 .end();
1106 msg_const_iter != msg_const_end; ++msg_const_iter) {
1107 ASSERT_EQ(msg_const_iter->bb(), 1234);
1108 }
1109
1110 // Test one primitive field.
1111 for (auto& x :
1112 *message.MutableRepeatedExtension(unittest::repeated_int32_extension)) {
1113 x = 4321;
1114 }
1115 for (const auto& x :
1116 message.GetRepeatedExtension(unittest::repeated_int32_extension)) {
1117 ASSERT_EQ(x, 4321);
1118 }
1119 // Test one string field.
1120 for (auto& x :
1121 *message.MutableRepeatedExtension(unittest::repeated_string_extension)) {
1122 x = "test_range_based_for";
1123 }
1124 for (const auto& x :
1125 message.GetRepeatedExtension(unittest::repeated_string_extension)) {
1126 ASSERT_TRUE(x == "test_range_based_for");
1127 }
1128 // Test one message field.
1129 for (auto& x : *message.MutableRepeatedExtension(
1130 unittest::repeated_nested_message_extension)) {
1131 x.set_bb(4321);
1132 }
1133 for (const auto& x : *message.MutableRepeatedExtension(
1134 unittest::repeated_nested_message_extension)) {
1135 ASSERT_EQ(x.bb(), 4321);
1136 }
1137 }
1138
1139 // From b/12926163
TEST(ExtensionSetTest,AbsentExtension)1140 TEST(ExtensionSetTest, AbsentExtension) {
1141 unittest::TestAllExtensions message;
1142 message.MutableRepeatedExtension(unittest::repeated_nested_message_extension)
1143 ->Add()
1144 ->set_bb(123);
1145 ASSERT_EQ(1,
1146 message.ExtensionSize(unittest::repeated_nested_message_extension));
1147 EXPECT_EQ(123,
1148 message.GetExtension(unittest::repeated_nested_message_extension, 0)
1149 .bb());
1150 }
1151
1152 #ifdef PROTOBUF_HAS_DEATH_TEST
1153
TEST(ExtensionSetTest,InvalidEnumDeath)1154 TEST(ExtensionSetTest, InvalidEnumDeath) {
1155 unittest::TestAllExtensions message;
1156 EXPECT_DEBUG_DEATH(
1157 message.SetExtension(unittest::optional_foreign_enum_extension,
1158 static_cast<unittest::ForeignEnum>(53)),
1159 "IsValid");
1160 }
1161
1162 #endif // PROTOBUF_HAS_DEATH_TEST
1163
TEST(ExtensionSetTest,DynamicExtensions)1164 TEST(ExtensionSetTest, DynamicExtensions) {
1165 // Test adding a dynamic extension to a compiled-in message object.
1166
1167 FileDescriptorProto dynamic_proto;
1168 dynamic_proto.set_name("dynamic_extensions_test.proto");
1169 dynamic_proto.add_dependency(
1170 unittest::TestAllExtensions::descriptor()->file()->name());
1171 dynamic_proto.set_package("dynamic_extensions");
1172
1173 // Copy the fields and nested types from TestDynamicExtensions into our new
1174 // proto, converting the fields into extensions.
1175 const Descriptor* template_descriptor =
1176 unittest::TestDynamicExtensions::descriptor();
1177 DescriptorProto template_descriptor_proto;
1178 template_descriptor->CopyTo(&template_descriptor_proto);
1179 dynamic_proto.mutable_message_type()->MergeFrom(
1180 template_descriptor_proto.nested_type());
1181 dynamic_proto.mutable_enum_type()->MergeFrom(
1182 template_descriptor_proto.enum_type());
1183 dynamic_proto.mutable_extension()->MergeFrom(
1184 template_descriptor_proto.field());
1185
1186 // For each extension that we added...
1187 for (int i = 0; i < dynamic_proto.extension_size(); i++) {
1188 // Set its extendee to TestAllExtensions.
1189 FieldDescriptorProto* extension = dynamic_proto.mutable_extension(i);
1190 extension->set_extendee(
1191 unittest::TestAllExtensions::descriptor()->full_name());
1192
1193 // If the field refers to one of the types nested in TestDynamicExtensions,
1194 // make it refer to the type in our dynamic proto instead.
1195 std::string prefix = "." + template_descriptor->full_name() + ".";
1196 if (extension->has_type_name()) {
1197 std::string* type_name = extension->mutable_type_name();
1198 if (HasPrefixString(*type_name, prefix)) {
1199 type_name->replace(0, prefix.size(), ".dynamic_extensions.");
1200 }
1201 }
1202 }
1203
1204 // Now build the file, using the generated pool as an underlay.
1205 DescriptorPool dynamic_pool(DescriptorPool::generated_pool());
1206 const FileDescriptor* file = dynamic_pool.BuildFile(dynamic_proto);
1207 ASSERT_TRUE(file != NULL);
1208 DynamicMessageFactory dynamic_factory(&dynamic_pool);
1209 dynamic_factory.SetDelegateToGeneratedFactory(true);
1210
1211 // Construct a message that we can parse with the extensions we defined.
1212 // Since the extensions were based off of the fields of TestDynamicExtensions,
1213 // we can use that message to create this test message.
1214 std::string data;
1215 unittest::TestDynamicExtensions dynamic_extension;
1216 {
1217 unittest::TestDynamicExtensions message;
1218 message.set_scalar_extension(123);
1219 message.set_enum_extension(unittest::FOREIGN_BAR);
1220 message.set_dynamic_enum_extension(
1221 unittest::TestDynamicExtensions::DYNAMIC_BAZ);
1222 message.mutable_message_extension()->set_c(456);
1223 message.mutable_dynamic_message_extension()->set_dynamic_field(789);
1224 message.add_repeated_extension("foo");
1225 message.add_repeated_extension("bar");
1226 message.add_packed_extension(12);
1227 message.add_packed_extension(-34);
1228 message.add_packed_extension(56);
1229 message.add_packed_extension(-78);
1230
1231 // Also add some unknown fields.
1232
1233 // An unknown enum value (for a known field).
1234 message.mutable_unknown_fields()->AddVarint(
1235 unittest::TestDynamicExtensions::kDynamicEnumExtensionFieldNumber,
1236 12345);
1237 // A regular unknown field.
1238 message.mutable_unknown_fields()->AddLengthDelimited(54321, "unknown");
1239
1240 message.SerializeToString(&data);
1241 dynamic_extension = message;
1242 }
1243
1244 // Now we can parse this using our dynamic extension definitions...
1245 unittest::TestAllExtensions message;
1246 {
1247 io::ArrayInputStream raw_input(data.data(), data.size());
1248 io::CodedInputStream input(&raw_input);
1249 input.SetExtensionRegistry(&dynamic_pool, &dynamic_factory);
1250 ASSERT_TRUE(message.ParseFromCodedStream(&input));
1251 ASSERT_TRUE(input.ConsumedEntireMessage());
1252 }
1253
1254 // Can we print it?
1255 EXPECT_EQ(
1256 "[dynamic_extensions.scalar_extension]: 123\n"
1257 "[dynamic_extensions.enum_extension]: FOREIGN_BAR\n"
1258 "[dynamic_extensions.dynamic_enum_extension]: DYNAMIC_BAZ\n"
1259 "[dynamic_extensions.message_extension] {\n"
1260 " c: 456\n"
1261 "}\n"
1262 "[dynamic_extensions.dynamic_message_extension] {\n"
1263 " dynamic_field: 789\n"
1264 "}\n"
1265 "[dynamic_extensions.repeated_extension]: \"foo\"\n"
1266 "[dynamic_extensions.repeated_extension]: \"bar\"\n"
1267 "[dynamic_extensions.packed_extension]: 12\n"
1268 "[dynamic_extensions.packed_extension]: -34\n"
1269 "[dynamic_extensions.packed_extension]: 56\n"
1270 "[dynamic_extensions.packed_extension]: -78\n"
1271 "2002: 12345\n"
1272 "54321: \"unknown\"\n",
1273 message.DebugString());
1274
1275 // Can we serialize it?
1276 EXPECT_TRUE(
1277 EqualsToSerialized(dynamic_extension, message.SerializeAsString()));
1278
1279 // What if we parse using the reflection-based parser?
1280 {
1281 unittest::TestAllExtensions message2;
1282 io::ArrayInputStream raw_input(data.data(), data.size());
1283 io::CodedInputStream input(&raw_input);
1284 input.SetExtensionRegistry(&dynamic_pool, &dynamic_factory);
1285 ASSERT_TRUE(WireFormat::ParseAndMergePartial(&input, &message2));
1286 ASSERT_TRUE(input.ConsumedEntireMessage());
1287 EXPECT_EQ(message.DebugString(), message2.DebugString());
1288 }
1289
1290 // Are the embedded generated types actually using the generated objects?
1291 {
1292 const FieldDescriptor* message_extension =
1293 file->FindExtensionByName("message_extension");
1294 ASSERT_TRUE(message_extension != NULL);
1295 const Message& sub_message =
1296 message.GetReflection()->GetMessage(message, message_extension);
1297 const unittest::ForeignMessage* typed_sub_message =
1298 #if PROTOBUF_RTTI
1299 dynamic_cast<const unittest::ForeignMessage*>(&sub_message);
1300 #else
1301 static_cast<const unittest::ForeignMessage*>(&sub_message);
1302 #endif
1303 ASSERT_TRUE(typed_sub_message != NULL);
1304 EXPECT_EQ(456, typed_sub_message->c());
1305 }
1306
1307 // What does GetMessage() return for the embedded dynamic type if it isn't
1308 // present?
1309 {
1310 const FieldDescriptor* dynamic_message_extension =
1311 file->FindExtensionByName("dynamic_message_extension");
1312 ASSERT_TRUE(dynamic_message_extension != NULL);
1313 const Message& parent = unittest::TestAllExtensions::default_instance();
1314 const Message& sub_message = parent.GetReflection()->GetMessage(
1315 parent, dynamic_message_extension, &dynamic_factory);
1316 const Message* prototype =
1317 dynamic_factory.GetPrototype(dynamic_message_extension->message_type());
1318 EXPECT_EQ(prototype, &sub_message);
1319 }
1320 }
1321
TEST(ExtensionSetTest,BoolExtension)1322 TEST(ExtensionSetTest, BoolExtension) {
1323 unittest::TestAllExtensions msg;
1324 uint8 wire_bytes[2] = {13 * 8, 42 /* out of bounds payload for bool */};
1325 EXPECT_TRUE(msg.ParseFromArray(wire_bytes, 2));
1326 EXPECT_TRUE(msg.GetExtension(protobuf_unittest::optional_bool_extension));
1327 }
1328
TEST(ExtensionSetTest,ConstInit)1329 TEST(ExtensionSetTest, ConstInit) {
1330 PROTOBUF_CONSTINIT static ExtensionSet set{};
1331 EXPECT_EQ(set.NumExtensions(), 0);
1332 }
1333
1334 } // namespace
1335 } // namespace internal
1336 } // namespace protobuf
1337 } // namespace google
1338