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