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