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