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
37 #include <google/protobuf/stubs/strutil.h>
38 #include <google/protobuf/test_util.h>
39 #include <google/protobuf/test_util2.h>
40 #include <google/protobuf/unittest.pb.h>
41 #include <google/protobuf/unittest_mset.pb.h>
42 #include <google/protobuf/io/coded_stream.h>
43 #include <google/protobuf/io/zero_copy_stream_impl.h>
44 #include <google/protobuf/descriptor.pb.h>
45 #include <google/protobuf/arena.h>
46 #include <google/protobuf/descriptor.h>
47 #include <google/protobuf/dynamic_message.h>
48 #include <google/protobuf/extension_set.h>
49 #include <google/protobuf/wire_format.h>
50
51 #include <google/protobuf/stubs/logging.h>
52 #include <google/protobuf/stubs/common.h>
53 #include <google/protobuf/testing/googletest.h>
54 #include <gtest/gtest.h>
55 #include <google/protobuf/stubs/stl_util.h>
56
57
58 namespace google {
59 namespace protobuf {
60 namespace internal {
61 namespace {
62
63 using TestUtil::EqualsToSerialized;
64
65 // This test closely mirrors net/proto2/compiler/cpp/internal/unittest.cc
66 // except that it uses extensions rather than regular fields.
67
TEST(ExtensionSetTest,Defaults)68 TEST(ExtensionSetTest, Defaults) {
69 // Check that all default values are set correctly in the initial message.
70 unittest::TestAllExtensions message;
71
72 TestUtil::ExpectExtensionsClear(message);
73
74 // Messages should return pointers to default instances until first use.
75 // (This is not checked by ExpectClear() since it is not actually true after
76 // the fields have been set and then cleared.)
77 EXPECT_EQ(&unittest::OptionalGroup_extension::default_instance(),
78 &message.GetExtension(unittest::optionalgroup_extension));
79 EXPECT_EQ(&unittest::TestAllTypes::NestedMessage::default_instance(),
80 &message.GetExtension(unittest::optional_nested_message_extension));
81 EXPECT_EQ(
82 &unittest::ForeignMessage::default_instance(),
83 &message.GetExtension(unittest::optional_foreign_message_extension));
84 EXPECT_EQ(&unittest_import::ImportMessage::default_instance(),
85 &message.GetExtension(unittest::optional_import_message_extension));
86 }
87
TEST(ExtensionSetTest,Accessors)88 TEST(ExtensionSetTest, Accessors) {
89 // Set every field to a unique value then go back and check all those
90 // values.
91 unittest::TestAllExtensions message;
92
93 TestUtil::SetAllExtensions(&message);
94 TestUtil::ExpectAllExtensionsSet(message);
95
96 TestUtil::ModifyRepeatedExtensions(&message);
97 TestUtil::ExpectRepeatedExtensionsModified(message);
98 }
99
TEST(ExtensionSetTest,Clear)100 TEST(ExtensionSetTest, Clear) {
101 // Set every field to a unique value, clear the message, then check that
102 // it is cleared.
103 unittest::TestAllExtensions message;
104
105 TestUtil::SetAllExtensions(&message);
106 message.Clear();
107 TestUtil::ExpectExtensionsClear(message);
108
109 // Unlike with the defaults test, we do NOT expect that requesting embedded
110 // messages will return a pointer to the default instance. Instead, they
111 // should return the objects that were created when mutable_blah() was
112 // called.
113 EXPECT_NE(&unittest::OptionalGroup_extension::default_instance(),
114 &message.GetExtension(unittest::optionalgroup_extension));
115 EXPECT_NE(&unittest::TestAllTypes::NestedMessage::default_instance(),
116 &message.GetExtension(unittest::optional_nested_message_extension));
117 EXPECT_NE(
118 &unittest::ForeignMessage::default_instance(),
119 &message.GetExtension(unittest::optional_foreign_message_extension));
120 EXPECT_NE(&unittest_import::ImportMessage::default_instance(),
121 &message.GetExtension(unittest::optional_import_message_extension));
122
123 // Make sure setting stuff again after clearing works. (This takes slightly
124 // different code paths since the objects are reused.)
125 TestUtil::SetAllExtensions(&message);
126 TestUtil::ExpectAllExtensionsSet(message);
127 }
128
TEST(ExtensionSetTest,ClearOneField)129 TEST(ExtensionSetTest, ClearOneField) {
130 // Set every field to a unique value, then clear one value and insure that
131 // only that one value is cleared.
132 unittest::TestAllExtensions message;
133
134 TestUtil::SetAllExtensions(&message);
135 int64 original_value =
136 message.GetExtension(unittest::optional_int64_extension);
137
138 // Clear the field and make sure it shows up as cleared.
139 message.ClearExtension(unittest::optional_int64_extension);
140 EXPECT_FALSE(message.HasExtension(unittest::optional_int64_extension));
141 EXPECT_EQ(0, message.GetExtension(unittest::optional_int64_extension));
142
143 // Other adjacent fields should not be cleared.
144 EXPECT_TRUE(message.HasExtension(unittest::optional_int32_extension));
145 EXPECT_TRUE(message.HasExtension(unittest::optional_uint32_extension));
146
147 // Make sure if we set it again, then all fields are set.
148 message.SetExtension(unittest::optional_int64_extension, original_value);
149 TestUtil::ExpectAllExtensionsSet(message);
150 }
151
TEST(ExtensionSetTest,SetAllocatedExtension)152 TEST(ExtensionSetTest, SetAllocatedExtension) {
153 unittest::TestAllExtensions message;
154 EXPECT_FALSE(
155 message.HasExtension(unittest::optional_foreign_message_extension));
156 // Add a extension using SetAllocatedExtension
157 unittest::ForeignMessage* foreign_message = new unittest::ForeignMessage();
158 message.SetAllocatedExtension(unittest::optional_foreign_message_extension,
159 foreign_message);
160 EXPECT_TRUE(
161 message.HasExtension(unittest::optional_foreign_message_extension));
162 EXPECT_EQ(foreign_message, message.MutableExtension(
163 unittest::optional_foreign_message_extension));
164 EXPECT_EQ(foreign_message, &message.GetExtension(
165 unittest::optional_foreign_message_extension));
166
167 // SetAllocatedExtension should delete the previously existing extension.
168 // (We reply on unittest to check memory leaks for this case)
169 message.SetAllocatedExtension(unittest::optional_foreign_message_extension,
170 new unittest::ForeignMessage());
171
172 // SetAllocatedExtension with a NULL parameter is equivalent to ClearExtenion.
173 message.SetAllocatedExtension(unittest::optional_foreign_message_extension,
174 NULL);
175 EXPECT_FALSE(
176 message.HasExtension(unittest::optional_foreign_message_extension));
177 }
178
TEST(ExtensionSetTest,ReleaseExtension)179 TEST(ExtensionSetTest, ReleaseExtension) {
180 proto2_wireformat_unittest::TestMessageSet message;
181 EXPECT_FALSE(message.HasExtension(
182 unittest::TestMessageSetExtension1::message_set_extension));
183 // Add a extension using SetAllocatedExtension
184 unittest::TestMessageSetExtension1* extension =
185 new unittest::TestMessageSetExtension1();
186 message.SetAllocatedExtension(
187 unittest::TestMessageSetExtension1::message_set_extension, extension);
188 EXPECT_TRUE(message.HasExtension(
189 unittest::TestMessageSetExtension1::message_set_extension));
190 // Release the extension using ReleaseExtension
191 unittest::TestMessageSetExtension1* released_extension =
192 message.ReleaseExtension(
193 unittest::TestMessageSetExtension1::message_set_extension);
194 EXPECT_EQ(extension, released_extension);
195 EXPECT_FALSE(message.HasExtension(
196 unittest::TestMessageSetExtension1::message_set_extension));
197 // ReleaseExtension will return the underlying object even after
198 // ClearExtension is called.
199 message.SetAllocatedExtension(
200 unittest::TestMessageSetExtension1::message_set_extension, extension);
201 message.ClearExtension(
202 unittest::TestMessageSetExtension1::message_set_extension);
203 released_extension = message.ReleaseExtension(
204 unittest::TestMessageSetExtension1::message_set_extension);
205 EXPECT_TRUE(released_extension != NULL);
206 delete released_extension;
207 }
208
TEST(ExtensionSetTest,ArenaUnsafeArenaSetAllocatedAndRelease)209 TEST(ExtensionSetTest, ArenaUnsafeArenaSetAllocatedAndRelease) {
210 Arena arena;
211 unittest::TestAllExtensions* message =
212 Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
213 unittest::ForeignMessage extension;
214 message->UnsafeArenaSetAllocatedExtension(
215 unittest::optional_foreign_message_extension, &extension);
216 // No copy when set.
217 unittest::ForeignMessage* mutable_extension =
218 message->MutableExtension(unittest::optional_foreign_message_extension);
219 EXPECT_EQ(&extension, mutable_extension);
220 // No copy when unsafe released.
221 unittest::ForeignMessage* released_extension =
222 message->UnsafeArenaReleaseExtension(
223 unittest::optional_foreign_message_extension);
224 EXPECT_EQ(&extension, released_extension);
225 EXPECT_FALSE(
226 message->HasExtension(unittest::optional_foreign_message_extension));
227 // Set the ownership back and let the destructors run. It should not take
228 // ownership, so this should not crash.
229 message->UnsafeArenaSetAllocatedExtension(
230 unittest::optional_foreign_message_extension, &extension);
231 }
232
TEST(ExtensionSetTest,UnsafeArenaSetAllocatedAndRelease)233 TEST(ExtensionSetTest, UnsafeArenaSetAllocatedAndRelease) {
234 unittest::TestAllExtensions message;
235 unittest::ForeignMessage* extension = new unittest::ForeignMessage();
236 message.UnsafeArenaSetAllocatedExtension(
237 unittest::optional_foreign_message_extension, extension);
238 // No copy when set.
239 unittest::ForeignMessage* mutable_extension =
240 message.MutableExtension(unittest::optional_foreign_message_extension);
241 EXPECT_EQ(extension, mutable_extension);
242 // No copy when unsafe released.
243 unittest::ForeignMessage* released_extension =
244 message.UnsafeArenaReleaseExtension(
245 unittest::optional_foreign_message_extension);
246 EXPECT_EQ(extension, released_extension);
247 EXPECT_FALSE(
248 message.HasExtension(unittest::optional_foreign_message_extension));
249 // Set the ownership back and let the destructors run. It should take
250 // ownership, so this should not leak.
251 message.UnsafeArenaSetAllocatedExtension(
252 unittest::optional_foreign_message_extension, extension);
253 }
254
TEST(ExtensionSetTest,ArenaUnsafeArenaReleaseOfHeapAlloc)255 TEST(ExtensionSetTest, ArenaUnsafeArenaReleaseOfHeapAlloc) {
256 Arena arena;
257 unittest::TestAllExtensions* message =
258 Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
259 unittest::ForeignMessage* extension = new unittest::ForeignMessage;
260 message->SetAllocatedExtension(unittest::optional_foreign_message_extension,
261 extension);
262 // The arena should maintain ownership of the heap allocated proto because we
263 // used UnsafeArenaReleaseExtension. The leak checker will ensure this.
264 unittest::ForeignMessage* released_extension =
265 message->UnsafeArenaReleaseExtension(
266 unittest::optional_foreign_message_extension);
267 EXPECT_EQ(extension, released_extension);
268 EXPECT_FALSE(
269 message->HasExtension(unittest::optional_foreign_message_extension));
270 }
271
272
TEST(ExtensionSetTest,CopyFrom)273 TEST(ExtensionSetTest, CopyFrom) {
274 unittest::TestAllExtensions message1, message2;
275
276 TestUtil::SetAllExtensions(&message1);
277 message2.CopyFrom(message1);
278 TestUtil::ExpectAllExtensionsSet(message2);
279 message2.CopyFrom(message1); // exercise copy when fields already exist
280 TestUtil::ExpectAllExtensionsSet(message2);
281 }
282
TEST(ExtensionSetTest,CopyFromPacked)283 TEST(ExtensionSetTest, CopyFromPacked) {
284 unittest::TestPackedExtensions message1, message2;
285
286 TestUtil::SetPackedExtensions(&message1);
287 message2.CopyFrom(message1);
288 TestUtil::ExpectPackedExtensionsSet(message2);
289 message2.CopyFrom(message1); // exercise copy when fields already exist
290 TestUtil::ExpectPackedExtensionsSet(message2);
291 }
292
TEST(ExtensionSetTest,CopyFromUpcasted)293 TEST(ExtensionSetTest, CopyFromUpcasted) {
294 unittest::TestAllExtensions message1, message2;
295 const Message& upcasted_message = message1;
296
297 TestUtil::SetAllExtensions(&message1);
298 message2.CopyFrom(upcasted_message);
299 TestUtil::ExpectAllExtensionsSet(message2);
300 // exercise copy when fields already exist
301 message2.CopyFrom(upcasted_message);
302 TestUtil::ExpectAllExtensionsSet(message2);
303 }
304
TEST(ExtensionSetTest,SwapWithEmpty)305 TEST(ExtensionSetTest, SwapWithEmpty) {
306 unittest::TestAllExtensions message1, message2;
307 TestUtil::SetAllExtensions(&message1);
308
309 TestUtil::ExpectAllExtensionsSet(message1);
310 TestUtil::ExpectExtensionsClear(message2);
311 message1.Swap(&message2);
312 TestUtil::ExpectAllExtensionsSet(message2);
313 TestUtil::ExpectExtensionsClear(message1);
314 }
315
TEST(ExtensionSetTest,SwapWithSelf)316 TEST(ExtensionSetTest, SwapWithSelf) {
317 unittest::TestAllExtensions message;
318 TestUtil::SetAllExtensions(&message);
319
320 TestUtil::ExpectAllExtensionsSet(message);
321 message.Swap(&message);
322 TestUtil::ExpectAllExtensionsSet(message);
323 }
324
TEST(ExtensionSetTest,SwapExtension)325 TEST(ExtensionSetTest, SwapExtension) {
326 unittest::TestAllExtensions message1;
327 unittest::TestAllExtensions message2;
328
329 TestUtil::SetAllExtensions(&message1);
330 std::vector<const FieldDescriptor*> fields;
331
332 // Swap empty fields.
333 const Reflection* reflection = message1.GetReflection();
334 reflection->SwapFields(&message1, &message2, fields);
335 TestUtil::ExpectAllExtensionsSet(message1);
336 TestUtil::ExpectExtensionsClear(message2);
337
338 // Swap two extensions.
339 fields.push_back(reflection->FindKnownExtensionByNumber(12));
340 fields.push_back(reflection->FindKnownExtensionByNumber(25));
341 reflection->SwapFields(&message1, &message2, fields);
342
343 EXPECT_TRUE(message1.HasExtension(unittest::optional_int32_extension));
344 EXPECT_FALSE(message1.HasExtension(unittest::optional_double_extension));
345 EXPECT_FALSE(message1.HasExtension(unittest::optional_cord_extension));
346
347 EXPECT_FALSE(message2.HasExtension(unittest::optional_int32_extension));
348 EXPECT_TRUE(message2.HasExtension(unittest::optional_double_extension));
349 EXPECT_TRUE(message2.HasExtension(unittest::optional_cord_extension));
350 }
351
TEST(ExtensionSetTest,SwapExtensionWithEmpty)352 TEST(ExtensionSetTest, SwapExtensionWithEmpty) {
353 unittest::TestAllExtensions message1;
354 unittest::TestAllExtensions message2;
355 unittest::TestAllExtensions message3;
356
357 TestUtil::SetAllExtensions(&message3);
358
359 const Reflection* reflection = message3.GetReflection();
360 std::vector<const FieldDescriptor*> fields;
361 reflection->ListFields(message3, &fields);
362
363 reflection->SwapFields(&message1, &message2, fields);
364
365 TestUtil::ExpectExtensionsClear(message1);
366 TestUtil::ExpectExtensionsClear(message2);
367 }
368
TEST(ExtensionSetTest,SwapExtensionBothFull)369 TEST(ExtensionSetTest, SwapExtensionBothFull) {
370 unittest::TestAllExtensions message1;
371 unittest::TestAllExtensions message2;
372
373 TestUtil::SetAllExtensions(&message1);
374 TestUtil::SetAllExtensions(&message2);
375
376 const Reflection* reflection = message1.GetReflection();
377 std::vector<const FieldDescriptor*> fields;
378 reflection->ListFields(message1, &fields);
379
380 reflection->SwapFields(&message1, &message2, fields);
381
382 TestUtil::ExpectAllExtensionsSet(message1);
383 TestUtil::ExpectAllExtensionsSet(message2);
384 }
385
TEST(ExtensionSetTest,ArenaSetAllExtension)386 TEST(ExtensionSetTest, ArenaSetAllExtension) {
387 Arena arena1;
388 unittest::TestAllExtensions* message1 =
389 Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
390 TestUtil::SetAllExtensions(message1);
391 TestUtil::ExpectAllExtensionsSet(*message1);
392 }
393
TEST(ExtensionSetTest,ArenaCopyConstructor)394 TEST(ExtensionSetTest, ArenaCopyConstructor) {
395 Arena arena1;
396 unittest::TestAllExtensions* message1 =
397 Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
398 TestUtil::SetAllExtensions(message1);
399 unittest::TestAllExtensions message2(*message1);
400 arena1.Reset();
401 TestUtil::ExpectAllExtensionsSet(message2);
402 }
403
TEST(ExtensionSetTest,ArenaMergeFrom)404 TEST(ExtensionSetTest, ArenaMergeFrom) {
405 Arena arena1;
406 unittest::TestAllExtensions* message1 =
407 Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
408 TestUtil::SetAllExtensions(message1);
409 unittest::TestAllExtensions message2;
410 message2.MergeFrom(*message1);
411 arena1.Reset();
412 TestUtil::ExpectAllExtensionsSet(message2);
413 }
414
TEST(ExtensionSetTest,ArenaSetAllocatedMessageAndRelease)415 TEST(ExtensionSetTest, ArenaSetAllocatedMessageAndRelease) {
416 Arena arena;
417 unittest::TestAllExtensions* message =
418 Arena::CreateMessage<unittest::TestAllExtensions>(&arena);
419 EXPECT_FALSE(
420 message->HasExtension(unittest::optional_foreign_message_extension));
421 // Add a extension using SetAllocatedExtension
422 unittest::ForeignMessage* foreign_message = new unittest::ForeignMessage();
423 message->SetAllocatedExtension(unittest::optional_foreign_message_extension,
424 foreign_message);
425 // foreign_message is now owned by the arena.
426 EXPECT_EQ(foreign_message, message->MutableExtension(
427 unittest::optional_foreign_message_extension));
428
429 // Underlying message is copied, and returned.
430 unittest::ForeignMessage* released_message =
431 message->ReleaseExtension(unittest::optional_foreign_message_extension);
432 delete released_message;
433 EXPECT_FALSE(
434 message->HasExtension(unittest::optional_foreign_message_extension));
435 }
436
TEST(ExtensionSetTest,SwapExtensionBothFullWithArena)437 TEST(ExtensionSetTest, SwapExtensionBothFullWithArena) {
438 Arena arena1;
439 std::unique_ptr<Arena> arena2(new Arena());
440
441 unittest::TestAllExtensions* message1 =
442 Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
443 unittest::TestAllExtensions* message2 =
444 Arena::CreateMessage<unittest::TestAllExtensions>(arena2.get());
445
446 TestUtil::SetAllExtensions(message1);
447 TestUtil::SetAllExtensions(message2);
448 message1->SetExtension(unittest::optional_int32_extension, 1);
449 message2->SetExtension(unittest::optional_int32_extension, 2);
450 message1->Swap(message2);
451 EXPECT_EQ(2, message1->GetExtension(unittest::optional_int32_extension));
452 EXPECT_EQ(1, message2->GetExtension(unittest::optional_int32_extension));
453 // Re-set the original values so ExpectAllExtensionsSet is happy.
454 message1->SetExtension(unittest::optional_int32_extension, 101);
455 message2->SetExtension(unittest::optional_int32_extension, 101);
456 TestUtil::ExpectAllExtensionsSet(*message1);
457 TestUtil::ExpectAllExtensionsSet(*message2);
458 arena2.reset(NULL);
459 TestUtil::ExpectAllExtensionsSet(*message1);
460 // Test corner cases, when one is empty and other is not.
461 Arena arena3, arena4;
462
463 unittest::TestAllExtensions* message3 =
464 Arena::CreateMessage<unittest::TestAllExtensions>(&arena3);
465 unittest::TestAllExtensions* message4 =
466 Arena::CreateMessage<unittest::TestAllExtensions>(&arena4);
467 TestUtil::SetAllExtensions(message3);
468 message3->Swap(message4);
469 arena3.Reset();
470 TestUtil::ExpectAllExtensionsSet(*message4);
471 }
472
TEST(ExtensionSetTest,SwapFieldsOfExtensionBothFullWithArena)473 TEST(ExtensionSetTest, SwapFieldsOfExtensionBothFullWithArena) {
474 Arena arena1;
475 Arena* arena2 = new Arena();
476
477 unittest::TestAllExtensions* message1 =
478 Arena::CreateMessage<unittest::TestAllExtensions>(&arena1);
479 unittest::TestAllExtensions* message2 =
480 Arena::CreateMessage<unittest::TestAllExtensions>(arena2);
481
482 TestUtil::SetAllExtensions(message1);
483 TestUtil::SetAllExtensions(message2);
484
485 const Reflection* reflection = message1->GetReflection();
486 std::vector<const FieldDescriptor*> fields;
487 reflection->ListFields(*message1, &fields);
488 reflection->SwapFields(message1, message2, fields);
489 TestUtil::ExpectAllExtensionsSet(*message1);
490 TestUtil::ExpectAllExtensionsSet(*message2);
491 delete arena2;
492 TestUtil::ExpectAllExtensionsSet(*message1);
493 }
494
TEST(ExtensionSetTest,SwapExtensionWithSelf)495 TEST(ExtensionSetTest, SwapExtensionWithSelf) {
496 unittest::TestAllExtensions message1;
497
498 TestUtil::SetAllExtensions(&message1);
499
500 std::vector<const FieldDescriptor*> fields;
501 const Reflection* reflection = message1.GetReflection();
502 reflection->ListFields(message1, &fields);
503 reflection->SwapFields(&message1, &message1, fields);
504
505 TestUtil::ExpectAllExtensionsSet(message1);
506 }
507
TEST(ExtensionSetTest,SerializationToArray)508 TEST(ExtensionSetTest, SerializationToArray) {
509 // Serialize as TestAllExtensions and parse as TestAllTypes to insure wire
510 // compatibility of extensions.
511 //
512 // This checks serialization to a flat array by explicitly reserving space in
513 // the string and calling the generated message's
514 // SerializeWithCachedSizesToArray.
515 unittest::TestAllExtensions source;
516 unittest::TestAllTypes destination;
517 TestUtil::SetAllExtensions(&source);
518 int size = source.ByteSize();
519 std::string data;
520 data.resize(size);
521 uint8* target = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&data));
522 uint8* end = source.SerializeWithCachedSizesToArray(target);
523 EXPECT_EQ(size, end - target);
524 EXPECT_TRUE(destination.ParseFromString(data));
525 TestUtil::ExpectAllFieldsSet(destination);
526 }
527
TEST(ExtensionSetTest,SerializationToStream)528 TEST(ExtensionSetTest, SerializationToStream) {
529 // Serialize as TestAllExtensions and parse as TestAllTypes to insure wire
530 // compatibility of extensions.
531 //
532 // This checks serialization to an output stream by creating an array output
533 // stream that can only buffer 1 byte at a time - this prevents the message
534 // from ever jumping to the fast path, ensuring that serialization happens via
535 // the CodedOutputStream.
536 unittest::TestAllExtensions source;
537 unittest::TestAllTypes destination;
538 TestUtil::SetAllExtensions(&source);
539 int size = source.ByteSize();
540 std::string data;
541 data.resize(size);
542 {
543 io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
544 io::CodedOutputStream output_stream(&array_stream);
545 source.SerializeWithCachedSizes(&output_stream);
546 ASSERT_FALSE(output_stream.HadError());
547 }
548 EXPECT_TRUE(destination.ParseFromString(data));
549 TestUtil::ExpectAllFieldsSet(destination);
550 }
551
TEST(ExtensionSetTest,PackedSerializationToArray)552 TEST(ExtensionSetTest, PackedSerializationToArray) {
553 // Serialize as TestPackedExtensions and parse as TestPackedTypes to insure
554 // wire compatibility of extensions.
555 //
556 // This checks serialization to a flat array by explicitly reserving space in
557 // the string and calling the generated message's
558 // SerializeWithCachedSizesToArray.
559 unittest::TestPackedExtensions source;
560 unittest::TestPackedTypes destination;
561 TestUtil::SetPackedExtensions(&source);
562 int size = source.ByteSize();
563 std::string data;
564 data.resize(size);
565 uint8* target = reinterpret_cast<uint8*>(::google::protobuf::string_as_array(&data));
566 uint8* end = source.SerializeWithCachedSizesToArray(target);
567 EXPECT_EQ(size, end - target);
568 EXPECT_TRUE(destination.ParseFromString(data));
569 TestUtil::ExpectPackedFieldsSet(destination);
570 }
571
TEST(ExtensionSetTest,PackedSerializationToStream)572 TEST(ExtensionSetTest, PackedSerializationToStream) {
573 // Serialize as TestPackedExtensions and parse as TestPackedTypes to insure
574 // wire compatibility of extensions.
575 //
576 // This checks serialization to an output stream by creating an array output
577 // stream that can only buffer 1 byte at a time - this prevents the message
578 // from ever jumping to the fast path, ensuring that serialization happens via
579 // the CodedOutputStream.
580 unittest::TestPackedExtensions source;
581 unittest::TestPackedTypes destination;
582 TestUtil::SetPackedExtensions(&source);
583 int size = source.ByteSize();
584 std::string data;
585 data.resize(size);
586 {
587 io::ArrayOutputStream array_stream(::google::protobuf::string_as_array(&data), size, 1);
588 io::CodedOutputStream output_stream(&array_stream);
589 source.SerializeWithCachedSizes(&output_stream);
590 ASSERT_FALSE(output_stream.HadError());
591 }
592 EXPECT_TRUE(destination.ParseFromString(data));
593 TestUtil::ExpectPackedFieldsSet(destination);
594 }
595
TEST(ExtensionSetTest,NestedExtensionGroup)596 TEST(ExtensionSetTest, NestedExtensionGroup) {
597 // Serialize as TestGroup and parse as TestGroupExtension.
598 unittest::TestGroup source;
599 unittest::TestGroupExtension destination;
600 std::string data;
601
602 source.mutable_optionalgroup()->set_a(117);
603 source.set_optional_foreign_enum(unittest::FOREIGN_BAZ);
604 source.SerializeToString(&data);
605 EXPECT_TRUE(destination.ParseFromString(data));
606 EXPECT_TRUE(
607 destination
608 .GetExtension(unittest::TestNestedExtension::optionalgroup_extension)
609 .has_a());
610 EXPECT_EQ(117, destination
611 .GetExtension(
612 unittest::TestNestedExtension::optionalgroup_extension)
613 .a());
614 EXPECT_TRUE(destination.HasExtension(
615 unittest::TestNestedExtension::optional_foreign_enum_extension));
616 EXPECT_EQ(
617 unittest::FOREIGN_BAZ,
618 destination.GetExtension(
619 unittest::TestNestedExtension::optional_foreign_enum_extension));
620 }
621
TEST(ExtensionSetTest,Parsing)622 TEST(ExtensionSetTest, Parsing) {
623 // Serialize as TestAllTypes and parse as TestAllExtensions.
624 unittest::TestAllTypes source;
625 unittest::TestAllExtensions destination;
626 std::string data;
627
628 TestUtil::SetAllFields(&source);
629 source.SerializeToString(&data);
630 EXPECT_TRUE(destination.ParseFromString(data));
631 TestUtil::SetOneofFields(&destination);
632 TestUtil::ExpectAllExtensionsSet(destination);
633 }
634
TEST(ExtensionSetTest,PackedParsing)635 TEST(ExtensionSetTest, PackedParsing) {
636 // Serialize as TestPackedTypes and parse as TestPackedExtensions.
637 unittest::TestPackedTypes source;
638 unittest::TestPackedExtensions destination;
639 std::string data;
640
641 TestUtil::SetPackedFields(&source);
642 source.SerializeToString(&data);
643 EXPECT_TRUE(destination.ParseFromString(data));
644 TestUtil::ExpectPackedExtensionsSet(destination);
645 }
646
TEST(ExtensionSetTest,PackedToUnpackedParsing)647 TEST(ExtensionSetTest, PackedToUnpackedParsing) {
648 unittest::TestPackedTypes source;
649 unittest::TestUnpackedExtensions destination;
650 std::string data;
651
652 TestUtil::SetPackedFields(&source);
653 source.SerializeToString(&data);
654 EXPECT_TRUE(destination.ParseFromString(data));
655 TestUtil::ExpectUnpackedExtensionsSet(destination);
656
657 // Reserialize
658 unittest::TestUnpackedTypes unpacked;
659 TestUtil::SetUnpackedFields(&unpacked);
660 // Serialized proto has to be the same size and parsed to the same message.
661 EXPECT_EQ(unpacked.SerializeAsString().size(),
662 destination.SerializeAsString().size());
663 EXPECT_TRUE(EqualsToSerialized(unpacked, destination.SerializeAsString()));
664
665 // Make sure we can add extensions.
666 destination.AddExtension(unittest::unpacked_int32_extension, 1);
667 destination.AddExtension(unittest::unpacked_enum_extension,
668 protobuf_unittest::FOREIGN_BAR);
669 }
670
TEST(ExtensionSetTest,UnpackedToPackedParsing)671 TEST(ExtensionSetTest, UnpackedToPackedParsing) {
672 unittest::TestUnpackedTypes source;
673 unittest::TestPackedExtensions destination;
674 std::string data;
675
676 TestUtil::SetUnpackedFields(&source);
677 source.SerializeToString(&data);
678 EXPECT_TRUE(destination.ParseFromString(data));
679 TestUtil::ExpectPackedExtensionsSet(destination);
680
681 // Reserialize
682 unittest::TestPackedTypes packed;
683 TestUtil::SetPackedFields(&packed);
684 // Serialized proto has to be the same size and parsed to the same message.
685 EXPECT_EQ(packed.SerializeAsString().size(),
686 destination.SerializeAsString().size());
687 EXPECT_TRUE(EqualsToSerialized(packed, destination.SerializeAsString()));
688
689 // Make sure we can add extensions.
690 destination.AddExtension(unittest::packed_int32_extension, 1);
691 destination.AddExtension(unittest::packed_enum_extension,
692 protobuf_unittest::FOREIGN_BAR);
693 }
694
TEST(ExtensionSetTest,IsInitialized)695 TEST(ExtensionSetTest, IsInitialized) {
696 // Test that IsInitialized() returns false if required fields in nested
697 // extensions are missing.
698 unittest::TestAllExtensions message;
699
700 EXPECT_TRUE(message.IsInitialized());
701
702 message.MutableExtension(unittest::TestRequired::single);
703 EXPECT_FALSE(message.IsInitialized());
704
705 message.MutableExtension(unittest::TestRequired::single)->set_a(1);
706 EXPECT_FALSE(message.IsInitialized());
707 message.MutableExtension(unittest::TestRequired::single)->set_b(2);
708 EXPECT_FALSE(message.IsInitialized());
709 message.MutableExtension(unittest::TestRequired::single)->set_c(3);
710 EXPECT_TRUE(message.IsInitialized());
711
712 message.AddExtension(unittest::TestRequired::multi);
713 EXPECT_FALSE(message.IsInitialized());
714
715 message.MutableExtension(unittest::TestRequired::multi, 0)->set_a(1);
716 EXPECT_FALSE(message.IsInitialized());
717 message.MutableExtension(unittest::TestRequired::multi, 0)->set_b(2);
718 EXPECT_FALSE(message.IsInitialized());
719 message.MutableExtension(unittest::TestRequired::multi, 0)->set_c(3);
720 EXPECT_TRUE(message.IsInitialized());
721 }
722
TEST(ExtensionSetTest,MutableString)723 TEST(ExtensionSetTest, MutableString) {
724 // Test the mutable string accessors.
725 unittest::TestAllExtensions message;
726
727 message.MutableExtension(unittest::optional_string_extension)->assign("foo");
728 EXPECT_TRUE(message.HasExtension(unittest::optional_string_extension));
729 EXPECT_EQ("foo", message.GetExtension(unittest::optional_string_extension));
730
731 message.AddExtension(unittest::repeated_string_extension)->assign("bar");
732 ASSERT_EQ(1, message.ExtensionSize(unittest::repeated_string_extension));
733 EXPECT_EQ("bar",
734 message.GetExtension(unittest::repeated_string_extension, 0));
735 }
736
TEST(ExtensionSetTest,SpaceUsedExcludingSelf)737 TEST(ExtensionSetTest, SpaceUsedExcludingSelf) {
738 // Scalar primitive extensions should increase the extension set size by a
739 // minimum of the size of the primitive type.
740 #define TEST_SCALAR_EXTENSIONS_SPACE_USED(type, value) \
741 do { \
742 unittest::TestAllExtensions message; \
743 const int base_size = message.SpaceUsed(); \
744 message.SetExtension(unittest::optional_##type##_extension, value); \
745 int min_expected_size = \
746 base_size + \
747 sizeof(message.GetExtension(unittest::optional_##type##_extension)); \
748 EXPECT_LE(min_expected_size, message.SpaceUsed()); \
749 } while (0)
750
751 TEST_SCALAR_EXTENSIONS_SPACE_USED(int32, 101);
752 TEST_SCALAR_EXTENSIONS_SPACE_USED(int64, 102);
753 TEST_SCALAR_EXTENSIONS_SPACE_USED(uint32, 103);
754 TEST_SCALAR_EXTENSIONS_SPACE_USED(uint64, 104);
755 TEST_SCALAR_EXTENSIONS_SPACE_USED(sint32, 105);
756 TEST_SCALAR_EXTENSIONS_SPACE_USED(sint64, 106);
757 TEST_SCALAR_EXTENSIONS_SPACE_USED(fixed32, 107);
758 TEST_SCALAR_EXTENSIONS_SPACE_USED(fixed64, 108);
759 TEST_SCALAR_EXTENSIONS_SPACE_USED(sfixed32, 109);
760 TEST_SCALAR_EXTENSIONS_SPACE_USED(sfixed64, 110);
761 TEST_SCALAR_EXTENSIONS_SPACE_USED(float, 111);
762 TEST_SCALAR_EXTENSIONS_SPACE_USED(double, 112);
763 TEST_SCALAR_EXTENSIONS_SPACE_USED(bool, true);
764 #undef TEST_SCALAR_EXTENSIONS_SPACE_USED
765 {
766 unittest::TestAllExtensions message;
767 const int base_size = message.SpaceUsed();
768 message.SetExtension(unittest::optional_nested_enum_extension,
769 unittest::TestAllTypes::FOO);
770 int min_expected_size =
771 base_size +
772 sizeof(message.GetExtension(unittest::optional_nested_enum_extension));
773 EXPECT_LE(min_expected_size, message.SpaceUsed());
774 }
775 {
776 // Strings may cause extra allocations depending on their length; ensure
777 // that gets included as well.
778 unittest::TestAllExtensions message;
779 const int base_size = message.SpaceUsed();
780 const std::string s(
781 "this is a fairly large string that will cause some "
782 "allocation in order to store it in the extension");
783 message.SetExtension(unittest::optional_string_extension, s);
784 int min_expected_size = base_size + s.length();
785 EXPECT_LE(min_expected_size, message.SpaceUsed());
786 }
787 {
788 // Messages also have additional allocation that need to be counted.
789 unittest::TestAllExtensions message;
790 const int base_size = message.SpaceUsed();
791 unittest::ForeignMessage foreign;
792 foreign.set_c(42);
793 message.MutableExtension(unittest::optional_foreign_message_extension)
794 ->CopyFrom(foreign);
795 int min_expected_size = base_size + foreign.SpaceUsed();
796 EXPECT_LE(min_expected_size, message.SpaceUsed());
797 }
798
799 // Repeated primitive extensions will increase space used by at least a
800 // RepeatedField<T>, and will cause additional allocations when the array
801 // gets too big for the initial space.
802 // This macro:
803 // - Adds a value to the repeated extension, then clears it, establishing
804 // the base size.
805 // - Adds a small number of values, testing that it doesn't increase the
806 // SpaceUsed()
807 // - Adds a large number of values (requiring allocation in the repeated
808 // field), and ensures that that allocation is included in SpaceUsed()
809 #define TEST_REPEATED_EXTENSIONS_SPACE_USED(type, cpptype, value) \
810 do { \
811 unittest::TestAllExtensions message; \
812 const int base_size = message.SpaceUsed(); \
813 int min_expected_size = sizeof(RepeatedField<cpptype>) + base_size; \
814 message.AddExtension(unittest::repeated_##type##_extension, value); \
815 message.ClearExtension(unittest::repeated_##type##_extension); \
816 const int empty_repeated_field_size = message.SpaceUsed(); \
817 EXPECT_LE(min_expected_size, empty_repeated_field_size) << #type; \
818 message.AddExtension(unittest::repeated_##type##_extension, value); \
819 message.AddExtension(unittest::repeated_##type##_extension, value); \
820 EXPECT_EQ(empty_repeated_field_size, message.SpaceUsed()) << #type; \
821 message.ClearExtension(unittest::repeated_##type##_extension); \
822 const int old_capacity = \
823 message.GetRepeatedExtension(unittest::repeated_##type##_extension) \
824 .Capacity(); \
825 EXPECT_GE(old_capacity, kMinRepeatedFieldAllocationSize); \
826 for (int i = 0; i < 16; ++i) { \
827 message.AddExtension(unittest::repeated_##type##_extension, value); \
828 } \
829 int expected_size = \
830 sizeof(cpptype) * \
831 (message \
832 .GetRepeatedExtension(unittest::repeated_##type##_extension) \
833 .Capacity() - \
834 old_capacity) + \
835 empty_repeated_field_size; \
836 EXPECT_LE(expected_size, message.SpaceUsed()) << #type; \
837 } while (0)
838
839 TEST_REPEATED_EXTENSIONS_SPACE_USED(int32, int32, 101);
840 TEST_REPEATED_EXTENSIONS_SPACE_USED(int64, int64, 102);
841 TEST_REPEATED_EXTENSIONS_SPACE_USED(uint32, uint32, 103);
842 TEST_REPEATED_EXTENSIONS_SPACE_USED(uint64, uint64, 104);
843 TEST_REPEATED_EXTENSIONS_SPACE_USED(sint32, int32, 105);
844 TEST_REPEATED_EXTENSIONS_SPACE_USED(sint64, int64, 106);
845 TEST_REPEATED_EXTENSIONS_SPACE_USED(fixed32, uint32, 107);
846 TEST_REPEATED_EXTENSIONS_SPACE_USED(fixed64, uint64, 108);
847 TEST_REPEATED_EXTENSIONS_SPACE_USED(sfixed32, int32, 109);
848 TEST_REPEATED_EXTENSIONS_SPACE_USED(sfixed64, int64, 110);
849 TEST_REPEATED_EXTENSIONS_SPACE_USED(float, float, 111);
850 TEST_REPEATED_EXTENSIONS_SPACE_USED(double, double, 112);
851 TEST_REPEATED_EXTENSIONS_SPACE_USED(bool, bool, true);
852 TEST_REPEATED_EXTENSIONS_SPACE_USED(nested_enum, int,
853 unittest::TestAllTypes::FOO);
854 #undef TEST_REPEATED_EXTENSIONS_SPACE_USED
855 // Repeated strings
856 {
857 unittest::TestAllExtensions message;
858 const int base_size = message.SpaceUsed();
859 int min_expected_size = 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 - kMinRepeatedFieldAllocationSize);
869 EXPECT_LE(min_expected_size, message.SpaceUsed());
870 }
871 // Repeated messages
872 {
873 unittest::TestAllExtensions message;
874 const int base_size = message.SpaceUsed();
875 int 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 - kMinRepeatedFieldAllocationSize) * prototype.SpaceUsed();
885 EXPECT_LE(min_expected_size, message.SpaceUsed());
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
1323 } // namespace
1324 } // namespace internal
1325 } // namespace protobuf
1326 } // namespace google
1327