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