arena_unittest.cc
Go to the documentation of this file.
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 #include <google/protobuf/arena.h>
32 
33 #include <algorithm>
34 #include <cstring>
35 #include <memory>
36 #include <string>
37 #include <type_traits>
38 #include <typeinfo>
39 #include <vector>
40 
45 #include <google/protobuf/unittest.pb.h>
46 #include <google/protobuf/unittest_arena.pb.h>
47 #include <google/protobuf/unittest_no_arena.pb.h>
57 #include <gtest/gtest.h>
59 
60 
61 using proto2_arena_unittest::ArenaMessage;
62 using protobuf_unittest::TestAllExtensions;
63 using protobuf_unittest::TestAllTypes;
64 using protobuf_unittest::TestEmptyMessage;
65 using protobuf_unittest::TestOneof2;
66 using protobuf_unittest_no_arena::TestNoArenaMessage;
67 
68 namespace google {
69 namespace protobuf {
70 
71 class Notifier {
72  public:
73  Notifier() : count_(0) {}
74  void Notify() { count_++; }
75  int GetCount() { return count_; }
76 
77  private:
78  int count_;
79 };
80 
82  public:
84  void SetNotifier(Notifier* notifier) { notifier_ = notifier; }
85  virtual ~SimpleDataType() {
86  if (notifier_ != NULL) {
87  notifier_->Notify();
88  }
89  };
90 
91  private:
93 };
94 
95 // A simple class that does not allow copying and so cannot be used as a
96 // parameter type without "const &".
98  public:
99  explicit PleaseDontCopyMe(int value) : value_(value) {}
100 
101  int value() const { return value_; }
102 
103  private:
104  int value_;
106 };
107 
108 // A class that takes four different types as constructor arguments.
110  public:
111  MustBeConstructedWithOneThroughFour(int one, const char* two,
112  const std::string& three,
113  const PleaseDontCopyMe* four)
114  : one_(one), two_(two), three_(three), four_(four) {}
115 
116  int one_;
117  const char* const two_;
120 
121  private:
123 };
124 
125 // A class that takes eight different types as constructor arguments.
127  public:
128  MustBeConstructedWithOneThroughEight(int one, const char* two,
129  const std::string& three,
130  const PleaseDontCopyMe* four, int five,
131  const char* six,
132  const std::string& seven,
133  const std::string& eight)
134  : one_(one),
135  two_(two),
136  three_(three),
137  four_(four),
138  five_(five),
139  six_(six),
140  seven_(seven),
141  eight_(eight) {}
142 
143  int one_;
144  const char* const two_;
147  int five_;
148  const char* const six_;
151 
152  private:
154 };
155 
156 TEST(ArenaTest, ArenaConstructable) {
161 }
162 
163 TEST(ArenaTest, DestructorSkippable) {
168 }
169 
170 TEST(ArenaTest, BasicCreate) {
171  Arena arena;
172  EXPECT_TRUE(Arena::Create<int32>(&arena) != NULL);
173  EXPECT_TRUE(Arena::Create<int64>(&arena) != NULL);
174  EXPECT_TRUE(Arena::Create<float>(&arena) != NULL);
175  EXPECT_TRUE(Arena::Create<double>(&arena) != NULL);
176  EXPECT_TRUE(Arena::Create<std::string>(&arena) != NULL);
177  arena.Own(new int32);
178  arena.Own(new int64);
179  arena.Own(new float);
180  arena.Own(new double);
181  arena.Own(new std::string);
182  arena.Own<int>(NULL);
183  Notifier notifier;
184  SimpleDataType* data = Arena::Create<SimpleDataType>(&arena);
185  data->SetNotifier(&notifier);
186  data = new SimpleDataType;
187  data->SetNotifier(&notifier);
188  arena.Own(data);
189  arena.Reset();
190  EXPECT_EQ(2, notifier.GetCount());
191 }
192 
193 TEST(ArenaTest, CreateAndConstCopy) {
194  Arena arena;
195  const std::string s("foo");
196  const std::string* s_copy = Arena::Create<std::string>(&arena, s);
197  EXPECT_TRUE(s_copy != NULL);
198  EXPECT_EQ("foo", s);
199  EXPECT_EQ("foo", *s_copy);
200 }
201 
202 TEST(ArenaTest, CreateAndNonConstCopy) {
203  Arena arena;
204  std::string s("foo");
205  const std::string* s_copy = Arena::Create<std::string>(&arena, s);
206  EXPECT_TRUE(s_copy != NULL);
207  EXPECT_EQ("foo", s);
208  EXPECT_EQ("foo", *s_copy);
209 }
210 
211 TEST(ArenaTest, CreateAndMove) {
212  Arena arena;
213  std::string s("foo");
214  const std::string* s_move = Arena::Create<std::string>(&arena, std::move(s));
215  EXPECT_TRUE(s_move != NULL);
216  EXPECT_TRUE(s.empty()); // NOLINT
217  EXPECT_EQ("foo", *s_move);
218 }
219 
220 TEST(ArenaTest, CreateWithFourConstructorArguments) {
221  Arena arena;
222  const std::string three("3");
223  const PleaseDontCopyMe four(4);
224  const MustBeConstructedWithOneThroughFour* new_object =
225  Arena::Create<MustBeConstructedWithOneThroughFour>(&arena, 1, "2", three,
226  &four);
227  EXPECT_TRUE(new_object != NULL);
228  ASSERT_EQ(1, new_object->one_);
229  ASSERT_STREQ("2", new_object->two_);
230  ASSERT_EQ("3", new_object->three_);
231  ASSERT_EQ(4, new_object->four_->value());
232 }
233 
234 TEST(ArenaTest, CreateWithEightConstructorArguments) {
235  Arena arena;
236  const std::string three("3");
237  const PleaseDontCopyMe four(4);
238  const std::string seven("7");
239  const std::string eight("8");
240  const MustBeConstructedWithOneThroughEight* new_object =
241  Arena::Create<MustBeConstructedWithOneThroughEight>(
242  &arena, 1, "2", three, &four, 5, "6", seven, eight);
243  EXPECT_TRUE(new_object != NULL);
244  ASSERT_EQ(1, new_object->one_);
245  ASSERT_STREQ("2", new_object->two_);
246  ASSERT_EQ("3", new_object->three_);
247  ASSERT_EQ(4, new_object->four_->value());
248  ASSERT_EQ(5, new_object->five_);
249  ASSERT_STREQ("6", new_object->six_);
250  ASSERT_EQ("7", new_object->seven_);
251  ASSERT_EQ("8", new_object->eight_);
252 }
253 
255  public:
256  explicit PleaseMoveMe(const std::string& value) : value_(value) {}
257  PleaseMoveMe(PleaseMoveMe&&) = default;
258  PleaseMoveMe(const PleaseMoveMe&) = delete;
259 
260  const std::string& value() const { return value_; }
261 
262  private:
264 };
265 
266 TEST(ArenaTest, CreateWithMoveArguments) {
267  Arena arena;
268  PleaseMoveMe one("1");
269  const PleaseMoveMe* new_object =
270  Arena::Create<PleaseMoveMe>(&arena, std::move(one));
271  EXPECT_TRUE(new_object);
272  ASSERT_EQ("1", new_object->value());
273 }
274 
275 TEST(ArenaTest, InitialBlockTooSmall) {
276  // Construct a small (64 byte) initial block of memory to be used by the
277  // arena allocator; then, allocate an object which will not fit in the
278  // initial block.
279  std::vector<char> arena_block(96);
281  options.initial_block = &arena_block[0];
282  options.initial_block_size = arena_block.size();
283  Arena arena(options);
284 
285  char* p = Arena::CreateArray<char>(&arena, 96);
286  uintptr_t allocation = reinterpret_cast<uintptr_t>(p);
287 
288  // Ensure that the arena allocator did not return memory pointing into the
289  // initial block of memory.
290  uintptr_t arena_start = reinterpret_cast<uintptr_t>(&arena_block[0]);
291  uintptr_t arena_end = arena_start + arena_block.size();
292  EXPECT_FALSE(allocation >= arena_start && allocation < arena_end);
293 
294  // Write to the memory we allocated; this should (but is not guaranteed to)
295  // trigger a check for heap corruption if the object was allocated from the
296  // initially-provided block.
297  memset(p, '\0', 96);
298 }
299 
300 TEST(ArenaTest, Parsing) {
301  TestAllTypes original;
302  TestUtil::SetAllFields(&original);
303 
304  // Test memory leak.
305  Arena arena;
306  TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
307  arena_message->ParseFromString(original.SerializeAsString());
308  TestUtil::ExpectAllFieldsSet(*arena_message);
309 
310  // Test that string fields have nul terminator bytes (earlier bug).
311  EXPECT_EQ(strlen(original.optional_string().c_str()),
312  strlen(arena_message->optional_string().c_str()));
313 }
314 
315 TEST(ArenaTest, UnknownFields) {
316  TestAllTypes original;
317  TestUtil::SetAllFields(&original);
318 
319  // Test basic parsing into (populating) and reading out of unknown fields on
320  // an arena.
321  Arena arena;
322  TestEmptyMessage* arena_message =
323  Arena::CreateMessage<TestEmptyMessage>(&arena);
324  arena_message->ParseFromString(original.SerializeAsString());
325 
326  TestAllTypes copied;
327  copied.ParseFromString(arena_message->SerializeAsString());
329 
330  // Exercise UFS manual manipulation (setters).
331  arena_message = Arena::CreateMessage<TestEmptyMessage>(&arena);
332  arena_message->mutable_unknown_fields()->AddVarint(
333  TestAllTypes::kOptionalInt32FieldNumber, 42);
334  copied.Clear();
335  copied.ParseFromString(arena_message->SerializeAsString());
336  EXPECT_TRUE(copied.has_optional_int32());
337  EXPECT_EQ(42, copied.optional_int32());
338 
339  // Exercise UFS swap path.
340  TestEmptyMessage* arena_message_2 =
341  Arena::CreateMessage<TestEmptyMessage>(&arena);
342  arena_message_2->Swap(arena_message);
343  copied.Clear();
344  copied.ParseFromString(arena_message_2->SerializeAsString());
345  EXPECT_TRUE(copied.has_optional_int32());
346  EXPECT_EQ(42, copied.optional_int32());
347 
348  // Test field manipulation.
349  TestEmptyMessage* arena_message_3 =
350  Arena::CreateMessage<TestEmptyMessage>(&arena);
351  arena_message_3->mutable_unknown_fields()->AddVarint(1000, 42);
352  arena_message_3->mutable_unknown_fields()->AddFixed32(1001, 42);
353  arena_message_3->mutable_unknown_fields()->AddFixed64(1002, 42);
354  arena_message_3->mutable_unknown_fields()->AddLengthDelimited(1003);
355  arena_message_3->mutable_unknown_fields()->DeleteSubrange(0, 2);
356  arena_message_3->mutable_unknown_fields()->DeleteByNumber(1002);
357  arena_message_3->mutable_unknown_fields()->DeleteByNumber(1003);
358  EXPECT_TRUE(arena_message_3->unknown_fields().empty());
359 }
360 
361 TEST(ArenaTest, Swap) {
362  Arena arena1;
363  Arena arena2;
364  TestAllTypes* arena1_message;
365  TestAllTypes* arena2_message;
366 
367  // Case 1: Swap(), no UFS on either message, both messages on different
368  // arenas. Arena pointers should remain the same after swap.
369  arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
370  arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
371  arena1_message->Swap(arena2_message);
372  EXPECT_EQ(&arena1, arena1_message->GetArena());
373  EXPECT_EQ(&arena2, arena2_message->GetArena());
374 
375  // Case 2: Swap(), UFS on one message, both messages on different arenas.
376  arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
377  arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
378  arena1_message->mutable_unknown_fields()->AddVarint(1, 42);
379  arena1_message->Swap(arena2_message);
380  EXPECT_EQ(&arena1, arena1_message->GetArena());
381  EXPECT_EQ(&arena2, arena2_message->GetArena());
382  EXPECT_EQ(0, arena1_message->unknown_fields().field_count());
383  EXPECT_EQ(1, arena2_message->unknown_fields().field_count());
384  EXPECT_EQ(42, arena2_message->unknown_fields().field(0).varint());
385 
386  // Case 3: Swap(), UFS on both messages, both messages on different arenas.
387  arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
388  arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
389  arena1_message->mutable_unknown_fields()->AddVarint(1, 42);
390  arena2_message->mutable_unknown_fields()->AddVarint(2, 84);
391  arena1_message->Swap(arena2_message);
392  EXPECT_EQ(&arena1, arena1_message->GetArena());
393  EXPECT_EQ(&arena2, arena2_message->GetArena());
394  EXPECT_EQ(1, arena1_message->unknown_fields().field_count());
395  EXPECT_EQ(1, arena2_message->unknown_fields().field_count());
396  EXPECT_EQ(84, arena1_message->unknown_fields().field(0).varint());
397  EXPECT_EQ(42, arena2_message->unknown_fields().field(0).varint());
398 }
399 
400 TEST(ArenaTest, ReflectionSwapFields) {
401  Arena arena1;
402  Arena arena2;
403  TestAllTypes* arena1_message;
404  TestAllTypes* arena2_message;
405 
406  // Case 1: messages on different arenas, only one message is set.
407  arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
408  arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
409  TestUtil::SetAllFields(arena1_message);
410  const Reflection* reflection = arena1_message->GetReflection();
411  std::vector<const FieldDescriptor*> fields;
412  reflection->ListFields(*arena1_message, &fields);
413  reflection->SwapFields(arena1_message, arena2_message, fields);
414  EXPECT_EQ(&arena1, arena1_message->GetArena());
415  EXPECT_EQ(&arena2, arena2_message->GetArena());
417  arena1_message->SerializeToString(&output);
418  EXPECT_EQ(0, output.size());
419  TestUtil::ExpectAllFieldsSet(*arena2_message);
420  reflection->SwapFields(arena1_message, arena2_message, fields);
421  arena2_message->SerializeToString(&output);
422  EXPECT_EQ(0, output.size());
423  TestUtil::ExpectAllFieldsSet(*arena1_message);
424 
425  // Case 2: messages on different arenas, both messages are set.
426  arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
427  arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
428  TestUtil::SetAllFields(arena1_message);
429  TestUtil::SetAllFields(arena2_message);
430  reflection->SwapFields(arena1_message, arena2_message, fields);
431  EXPECT_EQ(&arena1, arena1_message->GetArena());
432  EXPECT_EQ(&arena2, arena2_message->GetArena());
433  TestUtil::ExpectAllFieldsSet(*arena1_message);
434  TestUtil::ExpectAllFieldsSet(*arena2_message);
435 
436  // Case 3: messages on different arenas with different lifetimes.
437  arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
438  {
439  Arena arena3;
440  TestAllTypes* arena3_message = Arena::CreateMessage<TestAllTypes>(&arena3);
441  TestUtil::SetAllFields(arena3_message);
442  reflection->SwapFields(arena1_message, arena3_message, fields);
443  }
444  TestUtil::ExpectAllFieldsSet(*arena1_message);
445 
446  // Case 4: one message on arena, the other on heap.
447  arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
448  TestAllTypes message;
449  TestUtil::SetAllFields(arena1_message);
450  reflection->SwapFields(arena1_message, &message, fields);
451  EXPECT_EQ(&arena1, arena1_message->GetArena());
452  EXPECT_EQ(nullptr, message.GetArena());
453  arena1_message->SerializeToString(&output);
454  EXPECT_EQ(0, output.size());
456 }
457 
458 TEST(ArenaTest, SetAllocatedMessage) {
459  Arena arena;
460  TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
461  TestAllTypes::NestedMessage* nested = new TestAllTypes::NestedMessage;
462  nested->set_bb(118);
463  arena_message->set_allocated_optional_nested_message(nested);
464  EXPECT_EQ(118, arena_message->optional_nested_message().bb());
465 
466  TestNoArenaMessage no_arena_message;
467  EXPECT_FALSE(no_arena_message.has_arena_message());
468  no_arena_message.set_allocated_arena_message(NULL);
469  EXPECT_FALSE(no_arena_message.has_arena_message());
470  no_arena_message.set_allocated_arena_message(new ArenaMessage);
471  EXPECT_TRUE(no_arena_message.has_arena_message());
472 }
473 
474 TEST(ArenaTest, ReleaseMessage) {
475  Arena arena;
476  TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
477  arena_message->mutable_optional_nested_message()->set_bb(118);
478  std::unique_ptr<TestAllTypes::NestedMessage> nested(
479  arena_message->release_optional_nested_message());
480  EXPECT_EQ(118, nested->bb());
481 
482  TestAllTypes::NestedMessage* released_null =
483  arena_message->release_optional_nested_message();
484  EXPECT_EQ(NULL, released_null);
485 }
486 
487 TEST(ArenaTest, SetAllocatedString) {
488  Arena arena;
489  TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
490  std::string* allocated_str = new std::string("hello");
491  arena_message->set_allocated_optional_string(allocated_str);
492  EXPECT_EQ("hello", arena_message->optional_string());
493 }
494 
495 TEST(ArenaTest, ReleaseString) {
496  Arena arena;
497  TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
498  arena_message->set_optional_string("hello");
499  std::unique_ptr<std::string> released_str(
500  arena_message->release_optional_string());
501  EXPECT_EQ("hello", *released_str);
502 
503  // Test default value.
504 }
505 
506 
507 TEST(ArenaTest, SwapBetweenArenasWithAllFieldsSet) {
508  Arena arena1;
509  TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
510  {
511  Arena arena2;
512  TestAllTypes* arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
513  TestUtil::SetAllFields(arena2_message);
514  arena2_message->Swap(arena1_message);
516  arena2_message->SerializeToString(&output);
517  EXPECT_EQ(0, output.size());
518  }
519  TestUtil::ExpectAllFieldsSet(*arena1_message);
520 }
521 
522 TEST(ArenaTest, SwapBetweenArenaAndNonArenaWithAllFieldsSet) {
523  TestAllTypes non_arena_message;
524  TestUtil::SetAllFields(&non_arena_message);
525  {
526  Arena arena2;
527  TestAllTypes* arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
528  TestUtil::SetAllFields(arena2_message);
529  arena2_message->Swap(&non_arena_message);
530  TestUtil::ExpectAllFieldsSet(*arena2_message);
531  TestUtil::ExpectAllFieldsSet(non_arena_message);
532  }
533 }
534 
535 TEST(ArenaTest, UnsafeArenaSwap) {
536  Arena shared_arena;
537  TestAllTypes* message1 = Arena::CreateMessage<TestAllTypes>(&shared_arena);
538  TestAllTypes* message2 = Arena::CreateMessage<TestAllTypes>(&shared_arena);
539  TestUtil::SetAllFields(message1);
540  message1->UnsafeArenaSwap(message2);
541  TestUtil::ExpectAllFieldsSet(*message2);
542 }
543 
544 TEST(ArenaTest, SwapBetweenArenasUsingReflection) {
545  Arena arena1;
546  TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
547  {
548  Arena arena2;
549  TestAllTypes* arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
550  TestUtil::SetAllFields(arena2_message);
551  const Reflection* r = arena2_message->GetReflection();
552  r->Swap(arena1_message, arena2_message);
554  arena2_message->SerializeToString(&output);
555  EXPECT_EQ(0, output.size());
556  }
557  TestUtil::ExpectAllFieldsSet(*arena1_message);
558 }
559 
560 TEST(ArenaTest, SwapBetweenArenaAndNonArenaUsingReflection) {
561  TestAllTypes non_arena_message;
562  TestUtil::SetAllFields(&non_arena_message);
563  {
564  Arena arena2;
565  TestAllTypes* arena2_message = Arena::CreateMessage<TestAllTypes>(&arena2);
566  TestUtil::SetAllFields(arena2_message);
567  const Reflection* r = arena2_message->GetReflection();
568  r->Swap(&non_arena_message, arena2_message);
569  TestUtil::ExpectAllFieldsSet(*arena2_message);
570  TestUtil::ExpectAllFieldsSet(non_arena_message);
571  }
572 }
573 
574 TEST(ArenaTest, ReleaseFromArenaMessageMakesCopy) {
575  TestAllTypes::NestedMessage* nested_msg = NULL;
576  std::string* nested_string = NULL;
577  {
578  Arena arena;
579  TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
580  arena_message->mutable_optional_nested_message()->set_bb(42);
581  *arena_message->mutable_optional_string() = "Hello";
582  nested_msg = arena_message->release_optional_nested_message();
583  nested_string = arena_message->release_optional_string();
584  }
585  EXPECT_EQ(42, nested_msg->bb());
586  EXPECT_EQ("Hello", *nested_string);
587  delete nested_msg;
588  delete nested_string;
589 }
590 
591 #if PROTOBUF_RTTI
592 TEST(ArenaTest, ReleaseFromArenaMessageUsingReflectionMakesCopy) {
593  TestAllTypes::NestedMessage* nested_msg = NULL;
594  // Note: no string: reflection API only supports releasing submessages.
595  {
596  Arena arena;
597  TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
598  arena_message->mutable_optional_nested_message()->set_bb(42);
599  const Reflection* r = arena_message->GetReflection();
600  const FieldDescriptor* f = arena_message->GetDescriptor()->FindFieldByName(
601  "optional_nested_message");
602  nested_msg = static_cast<TestAllTypes::NestedMessage*>(
603  r->ReleaseMessage(arena_message, f));
604  }
605  EXPECT_EQ(42, nested_msg->bb());
606  delete nested_msg;
607 }
608 #endif // PROTOBUF_RTTI
609 
610 TEST(ArenaTest, SetAllocatedAcrossArenas) {
611  Arena arena1;
612  TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
613  TestAllTypes::NestedMessage* heap_submessage =
614  new TestAllTypes::NestedMessage();
615  heap_submessage->set_bb(42);
616  arena1_message->set_allocated_optional_nested_message(heap_submessage);
617  // Should keep same object and add to arena's Own()-list.
618  EXPECT_EQ(heap_submessage, arena1_message->mutable_optional_nested_message());
619  {
620  Arena arena2;
621  TestAllTypes::NestedMessage* arena2_submessage =
622  Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
623  arena2_submessage->set_bb(42);
624  arena1_message->set_allocated_optional_nested_message(arena2_submessage);
625  EXPECT_NE(arena2_submessage,
626  arena1_message->mutable_optional_nested_message());
627  }
628 
629  TestAllTypes::NestedMessage* arena1_submessage =
630  Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena1);
631  arena1_submessage->set_bb(42);
632  TestAllTypes* heap_message = new TestAllTypes;
633  heap_message->set_allocated_optional_nested_message(arena1_submessage);
634  EXPECT_NE(arena1_submessage, heap_message->mutable_optional_nested_message());
635  delete heap_message;
636 }
637 
638 TEST(ArenaTest, SetAllocatedAcrossArenasWithReflection) {
639  // Same as above, with reflection.
640  Arena arena1;
641  TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
642  const Reflection* r = arena1_message->GetReflection();
643  const Descriptor* d = arena1_message->GetDescriptor();
644  const FieldDescriptor* msg_field =
645  d->FindFieldByName("optional_nested_message");
646  TestAllTypes::NestedMessage* heap_submessage =
647  new TestAllTypes::NestedMessage();
648  heap_submessage->set_bb(42);
649  r->SetAllocatedMessage(arena1_message, heap_submessage, msg_field);
650  // Should keep same object and add to arena's Own()-list.
651  EXPECT_EQ(heap_submessage, arena1_message->mutable_optional_nested_message());
652  {
653  Arena arena2;
654  TestAllTypes::NestedMessage* arena2_submessage =
655  Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
656  arena2_submessage->set_bb(42);
657  r->SetAllocatedMessage(arena1_message, arena2_submessage, msg_field);
658  EXPECT_NE(arena2_submessage,
659  arena1_message->mutable_optional_nested_message());
660  }
661 
662  TestAllTypes::NestedMessage* arena1_submessage =
663  Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena1);
664  arena1_submessage->set_bb(42);
665  TestAllTypes* heap_message = new TestAllTypes;
666  r->SetAllocatedMessage(heap_message, arena1_submessage, msg_field);
667  EXPECT_NE(arena1_submessage, heap_message->mutable_optional_nested_message());
668  delete heap_message;
669 }
670 
671 TEST(ArenaTest, AddAllocatedWithReflection) {
672  Arena arena1;
673  ArenaMessage* arena1_message = Arena::CreateMessage<ArenaMessage>(&arena1);
674  const Reflection* r = arena1_message->GetReflection();
675  const Descriptor* d = arena1_message->GetDescriptor();
676  const FieldDescriptor* fd =
677  d->FindFieldByName("repeated_import_no_arena_message");
678  // Message with cc_enable_arenas = false;
679  r->AddMessage(arena1_message, fd);
680  r->AddMessage(arena1_message, fd);
681  r->AddMessage(arena1_message, fd);
682  EXPECT_EQ(3, r->FieldSize(*arena1_message, fd));
683  // Message with cc_enable_arenas = true;
684  fd = d->FindFieldByName("repeated_nested_message");
685  r->AddMessage(arena1_message, fd);
686  r->AddMessage(arena1_message, fd);
687  r->AddMessage(arena1_message, fd);
688  EXPECT_EQ(3, r->FieldSize(*arena1_message, fd));
689 }
690 
691 TEST(ArenaTest, RepeatedPtrFieldAddClearedTest) {
692  {
694  EXPECT_TRUE(repeated_field.empty());
695  EXPECT_EQ(0, repeated_field.size());
696  // Ownership is passed to repeated_field.
697  TestAllTypes* cleared = new TestAllTypes();
698  repeated_field.AddCleared(cleared);
699  EXPECT_TRUE(repeated_field.empty());
700  EXPECT_EQ(0, repeated_field.size());
701  }
702  {
704  EXPECT_TRUE(repeated_field.empty());
705  EXPECT_EQ(0, repeated_field.size());
706  // Ownership is passed to repeated_field.
707  TestAllTypes* cleared = new TestAllTypes();
708  repeated_field.AddAllocated(cleared);
709  EXPECT_FALSE(repeated_field.empty());
710  EXPECT_EQ(1, repeated_field.size());
711  }
712 }
713 
714 TEST(ArenaTest, AddAllocatedToRepeatedField) {
715  // Heap->arena case.
716  Arena arena1;
717  TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
718  for (int i = 0; i < 10; i++) {
719  TestAllTypes::NestedMessage* heap_submessage =
720  new TestAllTypes::NestedMessage();
721  heap_submessage->set_bb(42);
722  arena1_message->mutable_repeated_nested_message()->AddAllocated(
723  heap_submessage);
724  // Should not copy object -- will use arena_->Own().
725  EXPECT_EQ(heap_submessage, &arena1_message->repeated_nested_message(i));
726  EXPECT_EQ(42, arena1_message->repeated_nested_message(i).bb());
727  }
728 
729  // Arena1->Arena2 case.
730  arena1_message->Clear();
731  for (int i = 0; i < 10; i++) {
732  Arena arena2;
733  TestAllTypes::NestedMessage* arena2_submessage =
734  Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
735  arena2_submessage->set_bb(42);
736  arena1_message->mutable_repeated_nested_message()->AddAllocated(
737  arena2_submessage);
738  // Should copy object.
739  EXPECT_NE(arena2_submessage, &arena1_message->repeated_nested_message(i));
740  EXPECT_EQ(42, arena1_message->repeated_nested_message(i).bb());
741  }
742 
743  // Arena->heap case.
744  TestAllTypes* heap_message = new TestAllTypes();
745  for (int i = 0; i < 10; i++) {
746  Arena arena2;
747  TestAllTypes::NestedMessage* arena2_submessage =
748  Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
749  arena2_submessage->set_bb(42);
750  heap_message->mutable_repeated_nested_message()->AddAllocated(
751  arena2_submessage);
752  // Should copy object.
753  EXPECT_NE(arena2_submessage, &heap_message->repeated_nested_message(i));
754  EXPECT_EQ(42, heap_message->repeated_nested_message(i).bb());
755  }
756  delete heap_message;
757 
758  // Heap-arena case for strings (which are not arena-allocated).
759  arena1_message->Clear();
760  for (int i = 0; i < 10; i++) {
761  std::string* s = new std::string("Test");
762  arena1_message->mutable_repeated_string()->AddAllocated(s);
763  // Should not copy.
764  EXPECT_EQ(s, &arena1_message->repeated_string(i));
765  EXPECT_EQ("Test", arena1_message->repeated_string(i));
766  }
767 }
768 
769 TEST(ArenaTest, AddAllocatedToRepeatedFieldViaReflection) {
770  // Heap->arena case.
771  Arena arena1;
772  TestAllTypes* arena1_message = Arena::CreateMessage<TestAllTypes>(&arena1);
773  const Reflection* r = arena1_message->GetReflection();
774  const Descriptor* d = arena1_message->GetDescriptor();
775  const FieldDescriptor* fd = d->FindFieldByName("repeated_nested_message");
776  for (int i = 0; i < 10; i++) {
777  TestAllTypes::NestedMessage* heap_submessage =
778  new TestAllTypes::NestedMessage;
779  heap_submessage->set_bb(42);
780  r->AddAllocatedMessage(arena1_message, fd, heap_submessage);
781  // Should not copy object -- will use arena_->Own().
782  EXPECT_EQ(heap_submessage, &arena1_message->repeated_nested_message(i));
783  EXPECT_EQ(42, arena1_message->repeated_nested_message(i).bb());
784  }
785 
786  // Arena1->Arena2 case.
787  arena1_message->Clear();
788  for (int i = 0; i < 10; i++) {
789  Arena arena2;
790  TestAllTypes::NestedMessage* arena2_submessage =
791  Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
792  arena2_submessage->set_bb(42);
793  r->AddAllocatedMessage(arena1_message, fd, arena2_submessage);
794  // Should copy object.
795  EXPECT_NE(arena2_submessage, &arena1_message->repeated_nested_message(i));
796  EXPECT_EQ(42, arena1_message->repeated_nested_message(i).bb());
797  }
798 
799  // Arena->heap case.
800  TestAllTypes* heap_message = new TestAllTypes;
801  for (int i = 0; i < 10; i++) {
802  Arena arena2;
803  TestAllTypes::NestedMessage* arena2_submessage =
804  Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena2);
805  arena2_submessage->set_bb(42);
806  r->AddAllocatedMessage(heap_message, fd, arena2_submessage);
807  // Should copy object.
808  EXPECT_NE(arena2_submessage, &heap_message->repeated_nested_message(i));
809  EXPECT_EQ(42, heap_message->repeated_nested_message(i).bb());
810  }
811  delete heap_message;
812 }
813 
814 TEST(ArenaTest, ReleaseLastRepeatedField) {
815  // Release from arena-allocated repeated field and ensure that returned object
816  // is heap-allocated.
817  Arena arena;
818  TestAllTypes* arena_message = Arena::CreateMessage<TestAllTypes>(&arena);
819  for (int i = 0; i < 10; i++) {
820  TestAllTypes::NestedMessage* nested =
821  Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena);
822  nested->set_bb(42);
823  arena_message->mutable_repeated_nested_message()->AddAllocated(nested);
824  }
825 
826  for (int i = 0; i < 10; i++) {
827  const TestAllTypes::NestedMessage* orig_submessage =
828  &arena_message->repeated_nested_message(10 - 1 - i); // last element
829  TestAllTypes::NestedMessage* released =
830  arena_message->mutable_repeated_nested_message()->ReleaseLast();
831  EXPECT_NE(released, orig_submessage);
832  EXPECT_EQ(42, released->bb());
833  delete released;
834  }
835 
836  // Test UnsafeArenaReleaseLast().
837  for (int i = 0; i < 10; i++) {
838  TestAllTypes::NestedMessage* nested =
839  Arena::CreateMessage<TestAllTypes::NestedMessage>(&arena);
840  nested->set_bb(42);
841  arena_message->mutable_repeated_nested_message()->AddAllocated(nested);
842  }
843 
844  for (int i = 0; i < 10; i++) {
845  const TestAllTypes::NestedMessage* orig_submessage =
846  &arena_message->repeated_nested_message(10 - 1 - i); // last element
847  TestAllTypes::NestedMessage* released =
848  arena_message->mutable_repeated_nested_message()
849  ->UnsafeArenaReleaseLast();
850  EXPECT_EQ(released, orig_submessage);
851  EXPECT_EQ(42, released->bb());
852  // no delete -- |released| is on the arena.
853  }
854 
855  // Test string case as well. ReleaseLast() in this case must copy the
856  // string, even though it was originally heap-allocated and its pointer
857  // was simply appended to the repeated field's internal vector, because the
858  // string was placed on the arena's destructor list and cannot be removed
859  // from that list (so the arena permanently owns the original instance).
860  arena_message->Clear();
861  for (int i = 0; i < 10; i++) {
862  std::string* s = new std::string("Test");
863  arena_message->mutable_repeated_string()->AddAllocated(s);
864  }
865  for (int i = 0; i < 10; i++) {
866  const std::string* orig_element =
867  &arena_message->repeated_string(10 - 1 - i);
868  std::string* released =
869  arena_message->mutable_repeated_string()->ReleaseLast();
870  EXPECT_NE(released, orig_element);
871  EXPECT_EQ("Test", *released);
872  delete released;
873  }
874 }
875 
876 TEST(ArenaTest, UnsafeArenaReleaseAdd) {
877  // Use unsafe_arena_release() and unsafe_arena_set_allocated() to transfer an
878  // arena-allocated string from one message to another.
879  const char kContent[] = "Test content";
880 
881  Arena arena;
882  TestAllTypes* message1 = Arena::CreateMessage<TestAllTypes>(&arena);
883  TestAllTypes* message2 = Arena::CreateMessage<TestAllTypes>(&arena);
884  std::string* arena_string = Arena::Create<std::string>(&arena);
885  *arena_string = kContent;
886 
887  message1->unsafe_arena_set_allocated_optional_string(arena_string);
888  message2->unsafe_arena_set_allocated_optional_string(
889  message1->unsafe_arena_release_optional_string());
890  EXPECT_EQ(kContent, message2->optional_string());
891 }
892 
893 TEST(ArenaTest, UnsafeArenaAddAllocated) {
894  Arena arena;
895  TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
896  for (int i = 0; i < 10; i++) {
897  std::string* arena_string = Arena::Create<std::string>(&arena);
898  message->mutable_repeated_string()->UnsafeArenaAddAllocated(arena_string);
899  EXPECT_EQ(arena_string, message->mutable_repeated_string(i));
900  }
901 }
902 
903 TEST(ArenaTest, UnsafeArenaRelease) {
904  Arena arena;
905  TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
906 
907  std::string* s = new std::string("test string");
908  message->unsafe_arena_set_allocated_optional_string(s);
909  EXPECT_TRUE(message->has_optional_string());
910  EXPECT_EQ("test string", message->optional_string());
911  s = message->unsafe_arena_release_optional_string();
912  EXPECT_FALSE(message->has_optional_string());
913  delete s;
914 
915  s = new std::string("test string");
916  message->unsafe_arena_set_allocated_oneof_string(s);
917  EXPECT_TRUE(message->has_oneof_string());
918  EXPECT_EQ("test string", message->oneof_string());
919  s = message->unsafe_arena_release_oneof_string();
920  EXPECT_FALSE(message->has_oneof_string());
921  delete s;
922 }
923 
924 TEST(ArenaTest, OneofMerge) {
925  Arena arena;
926  TestAllTypes* message0 = Arena::CreateMessage<TestAllTypes>(&arena);
927  TestAllTypes* message1 = Arena::CreateMessage<TestAllTypes>(&arena);
928 
929  message0->unsafe_arena_set_allocated_oneof_string(new std::string("x"));
930  ASSERT_TRUE(message0->has_oneof_string());
931  message1->unsafe_arena_set_allocated_oneof_string(new std::string("y"));
932  ASSERT_TRUE(message1->has_oneof_string());
933  EXPECT_EQ("x", message0->oneof_string());
934  EXPECT_EQ("y", message1->oneof_string());
935  message0->MergeFrom(*message1);
936  EXPECT_EQ("y", message0->oneof_string());
937  EXPECT_EQ("y", message1->oneof_string());
938  delete message0->unsafe_arena_release_oneof_string();
939  delete message1->unsafe_arena_release_oneof_string();
940 }
941 
942 TEST(ArenaTest, ArenaOneofReflection) {
943  Arena arena;
944  TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
945  const Descriptor* desc = message->GetDescriptor();
946  const Reflection* refl = message->GetReflection();
947 
948  const FieldDescriptor* string_field = desc->FindFieldByName("oneof_string");
949  const FieldDescriptor* msg_field =
950  desc->FindFieldByName("oneof_nested_message");
951  const OneofDescriptor* oneof = desc->FindOneofByName("oneof_field");
952 
953  refl->SetString(message, string_field, "Test value");
954  EXPECT_TRUE(refl->HasOneof(*message, oneof));
955  refl->ClearOneof(message, oneof);
956  EXPECT_FALSE(refl->HasOneof(*message, oneof));
957 
958  Message* submsg = refl->MutableMessage(message, msg_field);
959  EXPECT_TRUE(refl->HasOneof(*message, oneof));
960  refl->ClearOneof(message, oneof);
961  EXPECT_FALSE(refl->HasOneof(*message, oneof));
962  refl->MutableMessage(message, msg_field);
963  EXPECT_TRUE(refl->HasOneof(*message, oneof));
964  submsg = refl->ReleaseMessage(message, msg_field);
965  EXPECT_FALSE(refl->HasOneof(*message, oneof));
966  EXPECT_TRUE(submsg->GetArena() == NULL);
967  delete submsg;
968 }
969 
970 void TestSwapRepeatedField(Arena* arena1, Arena* arena2) {
971  // Test "safe" (copying) semantics for direct Swap() on RepeatedPtrField
972  // between arenas.
973  RepeatedPtrField<TestAllTypes> field1(arena1);
974  RepeatedPtrField<TestAllTypes> field2(arena2);
975  for (int i = 0; i < 10; i++) {
976  TestAllTypes* t = Arena::CreateMessage<TestAllTypes>(arena1);
977  t->set_optional_string("field1");
978  t->set_optional_int32(i);
979  if (arena1 != NULL) {
980  field1.UnsafeArenaAddAllocated(t);
981  } else {
982  field1.AddAllocated(t);
983  }
984  }
985  for (int i = 0; i < 5; i++) {
986  TestAllTypes* t = Arena::CreateMessage<TestAllTypes>(arena2);
987  t->set_optional_string("field2");
988  t->set_optional_int32(i);
989  if (arena2 != NULL) {
990  field2.UnsafeArenaAddAllocated(t);
991  } else {
992  field2.AddAllocated(t);
993  }
994  }
995  field1.Swap(&field2);
996  EXPECT_EQ(5, field1.size());
997  EXPECT_EQ(10, field2.size());
998  EXPECT_TRUE(std::string("field1") == field2.Get(0).optional_string());
999  EXPECT_TRUE(std::string("field2") == field1.Get(0).optional_string());
1000  // Ensure that fields retained their original order:
1001  for (int i = 0; i < field1.size(); i++) {
1002  EXPECT_EQ(i, field1.Get(i).optional_int32());
1003  }
1004  for (int i = 0; i < field2.size(); i++) {
1005  EXPECT_EQ(i, field2.Get(i).optional_int32());
1006  }
1007 }
1008 
1009 TEST(ArenaTest, SwapRepeatedField) {
1010  Arena arena;
1011  TestSwapRepeatedField(&arena, &arena);
1012 }
1013 
1014 TEST(ArenaTest, SwapRepeatedFieldWithDifferentArenas) {
1015  Arena arena1;
1016  Arena arena2;
1017  TestSwapRepeatedField(&arena1, &arena2);
1018 }
1019 
1020 TEST(ArenaTest, SwapRepeatedFieldWithNoArenaOnRightHandSide) {
1021  Arena arena;
1022  TestSwapRepeatedField(&arena, NULL);
1023 }
1024 
1025 TEST(ArenaTest, SwapRepeatedFieldWithNoArenaOnLeftHandSide) {
1026  Arena arena;
1027  TestSwapRepeatedField(NULL, &arena);
1028 }
1029 
1030 TEST(ArenaTest, ExtensionsOnArena) {
1031  Arena arena;
1032  // Ensure no leaks.
1033  TestAllExtensions* message_ext =
1034  Arena::CreateMessage<TestAllExtensions>(&arena);
1035  message_ext->SetExtension(protobuf_unittest::optional_int32_extension, 42);
1036  message_ext->SetExtension(protobuf_unittest::optional_string_extension,
1037  std::string("test"));
1038  message_ext
1039  ->MutableExtension(protobuf_unittest::optional_nested_message_extension)
1040  ->set_bb(42);
1041 }
1042 
1043 TEST(ArenaTest, RepeatedFieldOnArena) {
1044  // Preallocate an initial arena block to avoid mallocs during hooked region.
1045  std::vector<char> arena_block(1024 * 1024);
1047  options.initial_block = &arena_block[0];
1048  options.initial_block_size = arena_block.size();
1049  Arena arena(options);
1050 
1051  {
1052  internal::NoHeapChecker no_heap;
1053 
1054  // Fill some repeated fields on the arena to test for leaks. Also verify no
1055  // memory allocations.
1056  RepeatedField<int32> repeated_int32(&arena);
1057  RepeatedPtrField<TestAllTypes> repeated_message(&arena);
1058  for (int i = 0; i < 100; i++) {
1059  repeated_int32.Add(42);
1060  repeated_message.Add()->set_optional_int32(42);
1061  EXPECT_EQ(&arena, repeated_message.Get(0).GetArena());
1062  const TestAllTypes* msg_in_repeated_field = &repeated_message.Get(0);
1063  TestAllTypes* msg = repeated_message.UnsafeArenaReleaseLast();
1064  EXPECT_EQ(msg_in_repeated_field, msg);
1065  }
1066 
1067  // UnsafeArenaExtractSubrange (i) should not leak and (ii) should return
1068  // on-arena pointers.
1069  for (int i = 0; i < 10; i++) {
1070  repeated_message.Add()->set_optional_int32(42);
1071  }
1072  TestAllTypes* extracted_messages[5];
1073  repeated_message.UnsafeArenaExtractSubrange(0, 5, extracted_messages);
1074  EXPECT_EQ(&arena, repeated_message.Get(0).GetArena());
1075  EXPECT_EQ(5, repeated_message.size());
1076  }
1077 
1078  // Now, outside the scope of the NoHeapChecker, test ExtractSubrange's copying
1079  // semantics.
1080  {
1081  RepeatedPtrField<TestAllTypes> repeated_message(&arena);
1082  for (int i = 0; i < 100; i++) {
1083  repeated_message.Add()->set_optional_int32(42);
1084  }
1085 
1086  TestAllTypes* extracted_messages[5];
1087  // ExtractSubrange should copy to the heap.
1088  repeated_message.ExtractSubrange(0, 5, extracted_messages);
1089  EXPECT_EQ(NULL, extracted_messages[0]->GetArena());
1090  // We need to free the heap-allocated messages to prevent a leak.
1091  for (int i = 0; i < 5; i++) {
1092  delete extracted_messages[i];
1093  extracted_messages[i] = NULL;
1094  }
1095  }
1096 
1097  // Now check that we can create RepeatedFields/RepeatedPtrFields themselves on
1098  // the arena. They have the necessary type traits so that they can behave like
1099  // messages in this way. This is useful for higher-level generic templated
1100  // code that may allocate messages or repeated fields of messages on an arena.
1101  {
1102  RepeatedPtrField<TestAllTypes>* repeated_ptr_on_arena =
1103  Arena::CreateMessage<RepeatedPtrField<TestAllTypes> >(&arena);
1104  for (int i = 0; i < 10; i++) {
1105  // Add some elements and let the leak-checker ensure that everything is
1106  // freed.
1107  repeated_ptr_on_arena->Add();
1108  }
1109 
1110  RepeatedField<int>* repeated_int_on_arena =
1111  Arena::CreateMessage<RepeatedField<int> >(&arena);
1112  for (int i = 0; i < 100; i++) {
1113  repeated_int_on_arena->Add(i);
1114  }
1115 
1116  }
1117 
1118  arena.Reset();
1119 }
1120 
1121 
1122 #if PROTOBUF_RTTI
1123 TEST(ArenaTest, MutableMessageReflection) {
1124  Arena arena;
1125  TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
1126  const Reflection* r = message->GetReflection();
1127  const Descriptor* d = message->GetDescriptor();
1128  const FieldDescriptor* field = d->FindFieldByName("optional_nested_message");
1129  TestAllTypes::NestedMessage* submessage =
1130  static_cast<TestAllTypes::NestedMessage*>(
1131  r->MutableMessage(message, field));
1132  TestAllTypes::NestedMessage* submessage_expected =
1133  message->mutable_optional_nested_message();
1134 
1135  EXPECT_EQ(submessage_expected, submessage);
1136  EXPECT_EQ(&arena, submessage->GetArena());
1137 
1138  const FieldDescriptor* oneof_field =
1139  d->FindFieldByName("oneof_nested_message");
1140  submessage = static_cast<TestAllTypes::NestedMessage*>(
1141  r->MutableMessage(message, oneof_field));
1142  submessage_expected = message->mutable_oneof_nested_message();
1143 
1144  EXPECT_EQ(submessage_expected, submessage);
1145  EXPECT_EQ(&arena, submessage->GetArena());
1146 }
1147 #endif // PROTOBUF_RTTI
1148 
1149 
1150 void FillArenaAwareFields(TestAllTypes* message) {
1151  std::string test_string = "hello world";
1152  message->set_optional_int32(42);
1153  message->set_optional_string(test_string);
1154  message->set_optional_bytes(test_string);
1155  message->mutable_optional_nested_message()->set_bb(42);
1156 
1157  message->set_oneof_uint32(42);
1158  message->mutable_oneof_nested_message()->set_bb(42);
1159  message->set_oneof_string(test_string);
1160  message->set_oneof_bytes(test_string);
1161 
1162  message->add_repeated_int32(42);
1163  // No repeated string: not yet arena-aware.
1164  message->add_repeated_nested_message()->set_bb(42);
1165  message->mutable_optional_lazy_message()->set_bb(42);
1166 }
1167 
1168 // Test: no allocations occur on heap while touching all supported field types.
1169 TEST(ArenaTest, NoHeapAllocationsTest) {
1170  // Allocate a large initial block to avoid mallocs during hooked test.
1171  std::vector<char> arena_block(128 * 1024);
1173  options.initial_block = &arena_block[0];
1174  options.initial_block_size = arena_block.size();
1175  Arena arena(options);
1176 
1177  {
1178 
1179  TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
1181  }
1182 
1183  arena.Reset();
1184 }
1185 
1186 TEST(ArenaTest, ParseCorruptedString) {
1187  TestAllTypes message;
1189  TestParseCorruptedString<TestAllTypes, true>(message);
1190  TestParseCorruptedString<TestAllTypes, false>(message);
1191 }
1192 
1193 #if PROTOBUF_RTTI
1194 // Test construction on an arena via generic MessageLite interface. We should be
1195 // able to successfully deserialize on the arena without incurring heap
1196 // allocations, i.e., everything should still be arena-allocation-aware.
1197 TEST(ArenaTest, MessageLiteOnArena) {
1198  std::vector<char> arena_block(128 * 1024);
1199  ArenaOptions options;
1200  options.initial_block = &arena_block[0];
1201  options.initial_block_size = arena_block.size();
1202  Arena arena(options);
1203  const MessageLite* prototype = &TestAllTypes::default_instance();
1204 
1205  TestAllTypes initial_message;
1206  FillArenaAwareFields(&initial_message);
1207  std::string serialized;
1208  initial_message.SerializeToString(&serialized);
1209 
1210  {
1211 
1212  MessageLite* generic_message = prototype->New(&arena);
1213  EXPECT_TRUE(generic_message != NULL);
1214  EXPECT_EQ(&arena, generic_message->GetArena());
1215  EXPECT_TRUE(generic_message->ParseFromString(serialized));
1216  TestAllTypes* deserialized = static_cast<TestAllTypes*>(generic_message);
1217  EXPECT_EQ(42, deserialized->optional_int32());
1218  }
1219 
1220  arena.Reset();
1221 }
1222 #endif // PROTOBUF_RTTI
1223 
1224 
1225 // RepeatedField should support non-POD types, and invoke constructors and
1226 // destructors appropriately, because it's used this way by lots of other code
1227 // (even if this was not its original intent).
1228 TEST(ArenaTest, RepeatedFieldWithNonPODType) {
1229  {
1230  RepeatedField<std::string> field_on_heap;
1231  for (int i = 0; i < 100; i++) {
1232  *field_on_heap.Add() = "test string long enough to exceed inline buffer";
1233  }
1234  }
1235  {
1236  Arena arena;
1237  RepeatedField<std::string> field_on_arena(&arena);
1238  for (int i = 0; i < 100; i++) {
1239  *field_on_arena.Add() = "test string long enough to exceed inline buffer";
1240  }
1241  }
1242 }
1243 
1244 // Align n to next multiple of 8
1245 uint64 Align8(uint64 n) { return (n + 7) & -8; }
1246 
1247 TEST(ArenaTest, SpaceAllocated_and_Used) {
1249  options.start_block_size = 256;
1250  options.max_block_size = 8192;
1251  Arena arena_1(options);
1252  EXPECT_EQ(0, arena_1.SpaceAllocated());
1253  EXPECT_EQ(0, arena_1.SpaceUsed());
1254  EXPECT_EQ(0, arena_1.Reset());
1255  Arena::CreateArray<char>(&arena_1, 320);
1256  // Arena will allocate slightly more than 320 for the block headers.
1257  EXPECT_LE(320, arena_1.SpaceAllocated());
1258  EXPECT_EQ(Align8(320), arena_1.SpaceUsed());
1259  EXPECT_LE(320, arena_1.Reset());
1260 
1261  // Test with initial block.
1262  std::vector<char> arena_block(1024);
1263  options.initial_block = &arena_block[0];
1264  options.initial_block_size = arena_block.size();
1265  Arena arena_2(options);
1266  EXPECT_EQ(1024, arena_2.SpaceAllocated());
1267  EXPECT_EQ(0, arena_2.SpaceUsed());
1268  EXPECT_EQ(1024, arena_2.Reset());
1269  Arena::CreateArray<char>(&arena_2, 55);
1270  EXPECT_EQ(1024, arena_2.SpaceAllocated());
1271  EXPECT_EQ(Align8(55), arena_2.SpaceUsed());
1272  EXPECT_EQ(1024, arena_2.Reset());
1273 
1274  // Reset options to test doubling policy explicitly.
1275  options.initial_block = NULL;
1276  options.initial_block_size = 0;
1277  Arena arena_3(options);
1278  EXPECT_EQ(0, arena_3.SpaceUsed());
1279  Arena::CreateArray<char>(&arena_3, 160);
1280  EXPECT_EQ(256, arena_3.SpaceAllocated());
1281  EXPECT_EQ(Align8(160), arena_3.SpaceUsed());
1282  Arena::CreateArray<char>(&arena_3, 70);
1283  EXPECT_EQ(256 + 512, arena_3.SpaceAllocated());
1284  EXPECT_EQ(Align8(160) + Align8(70), arena_3.SpaceUsed());
1285  EXPECT_EQ(256 + 512, arena_3.Reset());
1286 }
1287 
1288 TEST(ArenaTest, Alignment) {
1289  Arena arena;
1290  for (int i = 0; i < 200; i++) {
1291  void* p = Arena::CreateArray<char>(&arena, i);
1292  GOOGLE_CHECK_EQ(reinterpret_cast<uintptr_t>(p) % 8, 0) << i << ": " << p;
1293  }
1294 }
1295 
1296 TEST(ArenaTest, BlockSizeSmallerThanAllocation) {
1297  for (size_t i = 0; i <= 8; ++i) {
1298  ArenaOptions opt;
1299  opt.start_block_size = opt.max_block_size = i;
1300  Arena arena(opt);
1301 
1302  *Arena::Create<int64>(&arena) = 42;
1303  EXPECT_GE(arena.SpaceAllocated(), 8);
1304  EXPECT_EQ(8, arena.SpaceUsed());
1305 
1306  *Arena::Create<int64>(&arena) = 42;
1307  EXPECT_GE(arena.SpaceAllocated(), 16);
1308  EXPECT_EQ(16, arena.SpaceUsed());
1309  }
1310 }
1311 
1312 TEST(ArenaTest, GetArenaShouldReturnTheArenaForArenaAllocatedMessages) {
1313  Arena arena;
1314  ArenaMessage* message = Arena::CreateMessage<ArenaMessage>(&arena);
1315  const ArenaMessage* const_pointer_to_message = message;
1316  EXPECT_EQ(&arena, Arena::GetArena(message));
1317  EXPECT_EQ(&arena, Arena::GetArena(const_pointer_to_message));
1318 
1319  // Test that the Message* / MessageLite* specialization SFINAE works.
1320  const Message* const_pointer_to_message_type = message;
1321  EXPECT_EQ(&arena, Arena::GetArena(const_pointer_to_message_type));
1322  const MessageLite* const_pointer_to_message_lite_type = message;
1323  EXPECT_EQ(&arena, Arena::GetArena(const_pointer_to_message_lite_type));
1324 }
1325 
1326 TEST(ArenaTest, GetArenaShouldReturnNullForNonArenaAllocatedMessages) {
1327  ArenaMessage message;
1328  const ArenaMessage* const_pointer_to_message = &message;
1330  EXPECT_EQ(NULL, Arena::GetArena(const_pointer_to_message));
1331 }
1332 
1333 TEST(ArenaTest, GetArenaShouldReturnNullForNonArenaCompatibleTypes) {
1334  TestNoArenaMessage message;
1335  const TestNoArenaMessage* const_pointer_to_message = &message;
1336  EXPECT_EQ(nullptr, Arena::GetArena(&message));
1337  EXPECT_EQ(nullptr, Arena::GetArena(const_pointer_to_message));
1338 
1339  // Test that GetArena returns nullptr for types that have a GetArena method
1340  // that doesn't return Arena*.
1341  struct {
1342  int GetArena() const { return 0; }
1343  } has_get_arena_method_wrong_return_type;
1344  EXPECT_EQ(nullptr, Arena::GetArena(&has_get_arena_method_wrong_return_type));
1345 
1346  // Test that GetArena returns nullptr for types that have a GetArena alias.
1347  struct {
1348  using GetArena = Arena*;
1349  GetArena unused;
1350  } has_get_arena_alias;
1351  EXPECT_EQ(nullptr, Arena::GetArena(&has_get_arena_alias));
1352 
1353  // Test that GetArena returns nullptr for types that have a GetArena data
1354  // member.
1355  struct {
1356  Arena GetArena;
1357  } has_get_arena_data_member;
1358  EXPECT_EQ(nullptr, Arena::GetArena(&has_get_arena_data_member));
1359 }
1360 
1361 TEST(ArenaTest, AddCleanup) {
1362  Arena arena;
1363  for (int i = 0; i < 100; i++) {
1364  arena.Own(new int);
1365  }
1366 }
1367 
1368 TEST(ArenaTest, UnsafeSetAllocatedOnArena) {
1369  Arena arena;
1370  TestAllTypes* message = Arena::CreateMessage<TestAllTypes>(&arena);
1371  EXPECT_FALSE(message->has_optional_string());
1372 
1373  std::string owned_string = "test with long enough content to heap-allocate";
1374  message->unsafe_arena_set_allocated_optional_string(&owned_string);
1375  EXPECT_TRUE(message->has_optional_string());
1376 
1377  message->unsafe_arena_set_allocated_optional_string(NULL);
1378  EXPECT_FALSE(message->has_optional_string());
1379 }
1380 
1381 // A helper utility class to only contain static hook functions, some
1382 // counters to be used to verify the counters have been called and a cookie
1383 // value to be verified.
1385  public:
1386  static void* on_init(Arena* arena) {
1387  ++num_init;
1388  int* cookie = new int(kCookieValue);
1389  return static_cast<void*>(cookie);
1390  }
1391 
1392  static void on_allocation(const std::type_info* /*unused*/, uint64 alloc_size,
1393  void* cookie) {
1394  ++num_allocations;
1395  int cookie_value = *static_cast<int*>(cookie);
1396  EXPECT_EQ(kCookieValue, cookie_value);
1397  }
1398 
1399  static void on_reset(Arena* arena, void* cookie, uint64 space_used) {
1400  ++num_reset;
1401  int cookie_value = *static_cast<int*>(cookie);
1402  EXPECT_EQ(kCookieValue, cookie_value);
1403  }
1404 
1405  static void on_destruction(Arena* arena, void* cookie, uint64 space_used) {
1406  ++num_destruct;
1407  int cookie_value = *static_cast<int*>(cookie);
1408  EXPECT_EQ(kCookieValue, cookie_value);
1409  delete static_cast<int*>(cookie);
1410  }
1411 
1412  static const int kCookieValue = 999;
1417 };
1423 
1425  public:
1426  static void Set(ArenaOptions* options) {
1427  options->on_arena_init = ArenaHooksTestUtil::on_init;
1428  options->on_arena_allocation = ArenaHooksTestUtil::on_allocation;
1429  options->on_arena_reset = ArenaHooksTestUtil::on_reset;
1430  options->on_arena_destruction = ArenaHooksTestUtil::on_destruction;
1431  }
1432 };
1433 
1434 // Test the hooks are correctly called and that the cookie is passed.
1435 TEST(ArenaTest, ArenaHooksSanity) {
1438 
1439  // Scope for defining the arena
1440  {
1441  Arena arena(options);
1444  Arena::Create<uint64>(&arena);
1447  } else {
1449  }
1450  arena.Reset();
1451  arena.Reset();
1453  }
1456 }
1457 
1458 
1459 } // namespace protobuf
1460 } // namespace google
google::protobuf::SimpleDataType::~SimpleDataType
virtual ~SimpleDataType()
Definition: arena_unittest.cc:85
GOOGLE_CHECK_EQ
#define GOOGLE_CHECK_EQ(A, B)
Definition: logging.h:156
EXPECT_GE
#define EXPECT_GE(val1, val2)
Definition: gtest.h:2058
google::protobuf::SimpleDataType::notifier_
Notifier * notifier_
Definition: arena_unittest.cc:89
google::protobuf::RepeatedPtrField
Definition: command_line_interface.h:62
google::protobuf::RepeatedPtrField::Add
Element * Add()
Definition: repeated_field.h:2035
google::protobuf.internal::GetArena
Arena * GetArena(MessageLite *msg, int64 arena_offset)
Definition: generated_message_table_driven_lite.h:86
google::protobuf::Reflection::ClearOneof
void ClearOneof(Message *message, const OneofDescriptor *oneof_descriptor) const
Definition: generated_message_reflection.cc:2043
google::protobuf::FieldDescriptor
Definition: src/google/protobuf/descriptor.h:515
google::protobuf::TestSwapRepeatedField
void TestSwapRepeatedField(Arena *arena1, Arena *arena2)
Definition: arena_unittest.cc:970
wire_format_lite.h
EXPECT_LE
#define EXPECT_LE(val1, val2)
Definition: gtest.h:2054
arena_test_util.h
google::protobuf::MustBeConstructedWithOneThroughFour::two_
const char *const two_
Definition: arena_unittest.cc:117
NULL
NULL
Definition: test_security_zap.cpp:405
google::protobuf::int64
int64_t int64
Definition: protobuf/src/google/protobuf/stubs/port.h:151
google::protobuf::MessageLite::GetArena
virtual Arena * GetArena() const
Definition: message_lite.h:206
options
Message * options
Definition: src/google/protobuf/descriptor.cc:3119
extension_set.h
gtest.h
google::protobuf::SimpleDataType::SetNotifier
void SetNotifier(Notifier *notifier)
Definition: arena_unittest.cc:84
s
XmlRpcServer s
google::protobuf::PleaseMoveMe::value_
std::string value_
Definition: arena_unittest.cc:263
EXPECT_EQ
#define EXPECT_EQ(val1, val2)
Definition: glog/src/googletest.h:155
google::protobuf::uint32
uint32_t uint32
Definition: protobuf/src/google/protobuf/stubs/port.h:155
google::protobuf::RepeatedPtrField::Get
const Element & Get(int index) const
Definition: repeated_field.h:2014
desc
#define desc
Definition: extension_set.h:342
google::protobuf::OneofDescriptor
Definition: src/google/protobuf/descriptor.h:843
string
GLsizei const GLchar *const * string
Definition: glcorearb.h:3083
google::protobuf::RepeatedField< int32 >
google::protobuf::Reflection::SetString
void SetString(Message *message, const FieldDescriptor *field, const std::string &value) const
Definition: generated_message_reflection.cc:1193
google::protobuf.internal.python_message.UnknownFields
UnknownFields
Definition: python_message.py:1432
google::protobuf::ArenaHooksTestUtil::on_destruction
static void on_destruction(Arena *arena, void *cookie, uint64 space_used)
Definition: arena_unittest.cc:1405
google::protobuf::MustBeConstructedWithOneThroughEight::two_
const char *const two_
Definition: arena_unittest.cc:144
google::protobuf::MessageLite
Definition: message_lite.h:183
google::protobuf::FillArenaAwareFields
void FillArenaAwareFields(TestAllTypes *message)
Definition: arena_unittest.cc:1150
google::protobuf::Reflection::Swap
void Swap(Message *message1, Message *message2) const
Definition: generated_message_reflection.cc:600
google::protobuf::Reflection
Definition: src/google/protobuf/message.h:400
google::protobuf::Align8
uint64 Align8(uint64 n)
Definition: arena_unittest.cc:1245
google::protobuf::SimpleDataType
Definition: arena_unittest.cc:81
google::protobuf::RepeatedField::Add
void Add(const Element &value)
Definition: repeated_field.h:1220
google::protobuf::RepeatedPtrField::UnsafeArenaReleaseLast
Element * UnsafeArenaReleaseLast()
Definition: repeated_field.h:2219
google::protobuf::ArenaOptions::start_block_size
size_t start_block_size
Definition: arena.h:118
Descriptor
Definition: ruby/ext/google/protobuf_c/protobuf.h:113
tests.google.protobuf.internal.test_util.SetAllFields
def SetAllFields(message)
Definition: compatibility_tests/v2.5.0/tests/google/protobuf/internal/test_util.py:182
ASSERT_EQ
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:2082
google::protobuf::Notifier::Notify
void Notify()
Definition: arena_unittest.cc:74
google::protobuf::RepeatedPtrField::ExtractSubrange
void ExtractSubrange(int start, int num, Element **elements)
Definition: repeated_field.h:2061
FieldDescriptor
Definition: ruby/ext/google/protobuf_c/protobuf.h:129
google::protobuf::PleaseMoveMe::value
const std::string & value() const
Definition: arena_unittest.cc:260
google::protobuf::int32
int32_t int32
Definition: protobuf/src/google/protobuf/stubs/port.h:150
google::protobuf::Reflection::SwapFields
void SwapFields(Message *message1, Message *message2, const std::vector< const FieldDescriptor * > &fields) const
Definition: generated_message_reflection.cc:673
google::protobuf::MustBeConstructedWithOneThroughEight::one_
int one_
Definition: arena_unittest.cc:143
google::protobuf::MustBeConstructedWithOneThroughFour::GOOGLE_DISALLOW_EVIL_CONSTRUCTORS
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MustBeConstructedWithOneThroughFour)
google::protobuf::MustBeConstructedWithOneThroughEight::four_
const PleaseDontCopyMe * four_
Definition: arena_unittest.cc:146
strutil.h
repeated_field
PHP_PROTO_OBJECT_FREE_END PHP_PROTO_OBJECT_DTOR_END intern repeated_field
Definition: array.c:486
unknown_field_set.h
google::protobuf::MustBeConstructedWithOneThroughFour::three_
std::string three_
Definition: arena_unittest.cc:118
google::protobuf::MustBeConstructedWithOneThroughEight::six_
const char *const six_
Definition: arena_unittest.cc:148
coded_stream.h
EXPECT_NE
#define EXPECT_NE(val1, val2)
Definition: glog/src/googletest.h:156
google::protobuf::ArenaOptionsTestFriend
Definition: arena_unittest.cc:1424
google::protobuf::Reflection::HasOneof
bool HasOneof(const Message &message, const OneofDescriptor *oneof_descriptor) const
Definition: generated_message_reflection.cc:2021
message.h
p
const char * p
Definition: gmock-matchers_test.cc:3863
google::protobuf::ArenaHooksTestUtil
Definition: arena_unittest.cc:1384
google::protobuf::ArenaHooksTestUtil::on_init
static void * on_init(Arena *arena)
Definition: arena_unittest.cc:1386
google::protobuf::uint64
uint64_t uint64
Definition: protobuf/src/google/protobuf/stubs/port.h:156
google::protobuf::MustBeConstructedWithOneThroughEight::eight_
std::string eight_
Definition: arena_unittest.cc:150
tests.google.protobuf.internal.test_util.ExpectAllFieldsSet
def ExpectAllFieldsSet(test_case, message)
Definition: compatibility_tests/v2.5.0/tests/google/protobuf/internal/test_util.py:367
repeated_field.h
google::protobuf::TEST
TEST(ArenaTest, ArenaConstructable)
Definition: arena_unittest.cc:156
google::protobuf::RepeatedPtrField::Swap
void Swap(RepeatedPtrField *other)
Definition: repeated_field.h:2176
google::protobuf::ArenaOptionsTestFriend::Set
static void Set(ArenaOptions *options)
Definition: arena_unittest.cc:1426
EXPECT_TRUE
#define EXPECT_TRUE(cond)
Definition: glog/src/googletest.h:137
google::protobuf::Notifier::GetCount
int GetCount()
Definition: arena_unittest.cc:75
ASSERT_TRUE
#define ASSERT_TRUE(condition)
Definition: gtest.h:1995
d
d
google::protobuf::Notifier::count_
int count_
Definition: arena_unittest.cc:78
google::protobuf::ArenaHooksTestUtil::on_reset
static void on_reset(Arena *arena, void *cookie, uint64 space_used)
Definition: arena_unittest.cc:1399
field
const FieldDescriptor * field
Definition: parser_unittest.cc:2694
google::protobuf::MustBeConstructedWithOneThroughEight::seven_
std::string seven_
Definition: arena_unittest.cc:149
google::protobuf::Reflection::MutableMessage
Message * MutableMessage(Message *message, const FieldDescriptor *field, MessageFactory *factory=nullptr) const
Definition: generated_message_reflection.cc:1462
google::protobuf::MustBeConstructedWithOneThroughFour::MustBeConstructedWithOneThroughFour
MustBeConstructedWithOneThroughFour(int one, const char *two, const std::string &three, const PleaseDontCopyMe *four)
Definition: arena_unittest.cc:111
google::protobuf::SimpleDataType::SimpleDataType
SimpleDataType()
Definition: arena_unittest.cc:83
n
GLdouble n
Definition: glcorearb.h:4153
google::protobuf::RepeatedPtrField::UnsafeArenaAddAllocated
void UnsafeArenaAddAllocated(Element *value)
Definition: repeated_field.h:2209
google::protobuf::Notifier
Definition: arena_unittest.cc:71
i
int i
Definition: gmock-matchers_test.cc:764
google::protobuf::RepeatedPtrField::size
int size() const
Definition: repeated_field.h:2009
zero_copy_stream_impl_lite.h
google::protobuf::MustBeConstructedWithOneThroughFour::one_
int one_
Definition: arena_unittest.cc:116
google::protobuf::MustBeConstructedWithOneThroughEight::GOOGLE_DISALLOW_EVIL_CONSTRUCTORS
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(MustBeConstructedWithOneThroughEight)
fields
static const upb_fielddef fields[107]
Definition: ruby/ext/google/protobuf_c/upb.c:7671
google::protobuf::ArenaOptions
Definition: arena.h:115
google::protobuf::PleaseMoveMe
Definition: arena_unittest.cc:254
google::protobuf::Message
Definition: src/google/protobuf/message.h:205
google::protobuf::Notifier::Notifier
Notifier()
Definition: arena_unittest.cc:73
google::protobuf::ArenaHooksTestUtil::num_allocations
static uint32 num_allocations
Definition: arena_unittest.cc:1414
common.h
google::protobuf::MustBeConstructedWithOneThroughEight::MustBeConstructedWithOneThroughEight
MustBeConstructedWithOneThroughEight(int one, const char *two, const std::string &three, const PleaseDontCopyMe *four, int five, const char *six, const std::string &seven, const std::string &eight)
Definition: arena_unittest.cc:128
google::protobuf::PleaseDontCopyMe::value
int value() const
Definition: arena_unittest.cc:101
google::protobuf::PleaseDontCopyMe::PleaseDontCopyMe
PleaseDontCopyMe(int value)
Definition: arena_unittest.cc:99
EXPECT_FALSE
#define EXPECT_FALSE(cond)
Definition: glog/src/googletest.h:145
google::protobuf::ArenaHooksTestUtil::num_destruct
static uint32 num_destruct
Definition: arena_unittest.cc:1416
arena.h
google::protobuf::MustBeConstructedWithOneThroughEight
Definition: arena_unittest.cc:126
message_lite.h
logging.h
google::protobuf::ArenaOptions::max_block_size
size_t max_block_size
Definition: arena.h:124
r
GLboolean r
Definition: glcorearb.h:3228
google::protobuf::Descriptor
Definition: src/google/protobuf/descriptor.h:231
google::protobuf::ArenaHooksTestUtil::num_reset
static uint32 num_reset
Definition: arena_unittest.cc:1415
descriptor.h
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: glcorearb.h:2879
ASSERT_STREQ
#define ASSERT_STREQ(s1, s2)
Definition: gtest.h:2130
f
GLfloat f
Definition: glcorearb.h:3964
google::protobuf::ArenaHooksTestUtil::kCookieValue
static const int kCookieValue
Definition: arena_unittest.cc:1412
value
GLsizei const GLfloat * value
Definition: glcorearb.h:3093
google::protobuf.internal::NoHeapChecker
Definition: arena_test_util.h:79
google::protobuf::ArenaHooksTestUtil::num_init
static uint32 num_init
Definition: arena_unittest.cc:1413
google::protobuf::RepeatedPtrField::UnsafeArenaExtractSubrange
void UnsafeArenaExtractSubrange(int start, int num, Element **elements)
Definition: repeated_field.h:2117
google::protobuf::Reflection::ReleaseMessage
Message * ReleaseMessage(Message *message, const FieldDescriptor *field, MessageFactory *factory=nullptr) const
Definition: generated_message_reflection.cc:1585
google::protobuf::ArenaHooksTestUtil::on_allocation
static void on_allocation(const std::type_info *, uint64 alloc_size, void *cookie)
Definition: arena_unittest.cc:1392
output
const upb_json_parsermethod const upb_symtab upb_sink * output
Definition: ruby/ext/google/protobuf_c/upb.h:10503
google::protobuf::PleaseDontCopyMe
Definition: arena_unittest.cc:97
google::protobuf::MustBeConstructedWithOneThroughFour::four_
const PleaseDontCopyMe * four_
Definition: arena_unittest.cc:119
google::protobuf::MustBeConstructedWithOneThroughEight::three_
std::string three_
Definition: arena_unittest.cc:145
google::protobuf::PleaseMoveMe::PleaseMoveMe
PleaseMoveMe(const std::string &value)
Definition: arena_unittest.cc:256
test_util.h
google::protobuf::MustBeConstructedWithOneThroughEight::five_
int five_
Definition: arena_unittest.cc:147
google::protobuf::Reflection::ListFields
void ListFields(const Message &message, std::vector< const FieldDescriptor * > *output) const
Definition: generated_message_reflection.cc:1029
google::protobuf::MustBeConstructedWithOneThroughFour
Definition: arena_unittest.cc:109
google::protobuf::RepeatedPtrField::AddAllocated
void AddAllocated(Element *value)
Definition: repeated_field.h:2204
google
Definition: data_proto2_to_proto3_util.h:11
message
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: glcorearb.h:2695
google::protobuf::PleaseDontCopyMe::value_
int value_
Definition: arena_unittest.cc:104
google::protobuf::PleaseDontCopyMe::GOOGLE_DISALLOW_EVIL_CONSTRUCTORS
GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(PleaseDontCopyMe)


libaditof
Author(s):
autogenerated on Wed May 21 2025 02:06:48