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