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