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