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