• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2023 Google LLC.  All rights reserved.
3 //
4 // Use of this source code is governed by a BSD-style
5 // license that can be found in the LICENSE file or at
6 // https://developers.google.com/open-source/licenses/bsd
7 
8 #include <cstdint>
9 #include <iterator>
10 #include <limits>
11 #include <memory>
12 #include <string>
13 #include <type_traits>
14 #include <utility>
15 #include <vector>
16 
17 #include <gmock/gmock.h>
18 #include <gtest/gtest.h>
19 #include "absl/status/statusor.h"
20 #include "absl/strings/string_view.h"
21 #include "google/protobuf/compiler/hpb/tests/child_model.upb.proto.h"
22 #include "google/protobuf/compiler/hpb/tests/no_package.upb.proto.h"
23 #include "google/protobuf/compiler/hpb/tests/test_extension.upb.proto.h"
24 #include "google/protobuf/compiler/hpb/tests/test_model.upb.proto.h"
25 #include "google/protobuf/hpb/backend/upb/interop.h"
26 #include "google/protobuf/hpb/hpb.h"
27 #include "google/protobuf/hpb/ptr.h"
28 #include "google/protobuf/hpb/repeated_field.h"
29 #include "google/protobuf/hpb/requires.h"
30 #include "upb/mem/arena.h"
31 #include "upb/mem/arena.hpp"
32 
33 namespace {
34 
35 using ::hpb::internal::Requires;
36 using ::hpb_unittest::protos::ChildModel1;
37 using ::hpb_unittest::protos::container_ext;
38 using ::hpb_unittest::protos::ContainerExtension;
39 using ::hpb_unittest::protos::other_ext;
40 using ::hpb_unittest::protos::RED;
41 using ::hpb_unittest::protos::TestEnum;
42 using ::hpb_unittest::protos::TestModel;
43 using ::hpb_unittest::protos::TestModel_Category;
44 using ::hpb_unittest::protos::TestModel_Category_IMAGES;
45 using ::hpb_unittest::protos::TestModel_Category_NEWS;
46 using ::hpb_unittest::protos::TestModel_Category_VIDEO;
47 using ::hpb_unittest::protos::theme;
48 using ::hpb_unittest::protos::ThemeExtension;
49 using ::testing::ElementsAre;
50 
TEST(CppGeneratedCode,Constructor)51 TEST(CppGeneratedCode, Constructor) { TestModel test_model; }
52 
TEST(CppGeneratedCode,MessageEnum)53 TEST(CppGeneratedCode, MessageEnum) { EXPECT_EQ(5, TestModel_Category_IMAGES); }
54 
TEST(CppGeneratedCode,ImportedEnum)55 TEST(CppGeneratedCode, ImportedEnum) { EXPECT_EQ(3, TestEnum::DEVICE_MONITOR); }
56 
TEST(CppGeneratedCode,Enum)57 TEST(CppGeneratedCode, Enum) { EXPECT_EQ(1, RED); }
58 
TEST(CppGeneratedCode,EnumNoPackage)59 TEST(CppGeneratedCode, EnumNoPackage) { EXPECT_EQ(1, ::hpb_CELSIUS); }
60 
TEST(CppGeneratedCode,MessageEnumType)61 TEST(CppGeneratedCode, MessageEnumType) {
62   TestModel_Category category1 = TestModel_Category_IMAGES;
63   TestModel::Category category2 = TestModel::IMAGES;
64   EXPECT_EQ(category1, category2);
65 }
66 
TEST(CppGeneratedCode,MessageEnumValue)67 TEST(CppGeneratedCode, MessageEnumValue) {
68   EXPECT_EQ(TestModel_Category_IMAGES, TestModel::IMAGES);
69 }
70 
TEST(CppGeneratedCode,ArenaConstructor)71 TEST(CppGeneratedCode, ArenaConstructor) {
72   ::hpb::Arena arena;
73   auto testModel = ::hpb::CreateMessage<TestModel>(arena);
74   EXPECT_EQ(false, testModel.has_b1());
75 }
76 
TEST(CppGeneratedCode,Booleans)77 TEST(CppGeneratedCode, Booleans) {
78   ::hpb::Arena arena;
79   auto testModel = ::hpb::CreateMessage<TestModel>(arena);
80   EXPECT_FALSE(testModel.b1());
81   testModel.set_b1(true);
82   EXPECT_TRUE(testModel.b1());
83   testModel.set_b1(false);
84   EXPECT_FALSE(testModel.b1());
85   testModel.set_b1(true);
86   EXPECT_TRUE(testModel.b1());
87   testModel.clear_b1();
88   EXPECT_FALSE(testModel.has_b1());
89 }
90 
TEST(CppGeneratedCode,ScalarInt32)91 TEST(CppGeneratedCode, ScalarInt32) {
92   ::hpb::Arena arena;
93   auto testModel = ::hpb::CreateMessage<TestModel>(arena);
94   // Test int32 defaults.
95   EXPECT_EQ(testModel.value(), 0);
96   EXPECT_FALSE(testModel.has_value());
97   // Floating point defaults.
98   EXPECT_EQ(std::numeric_limits<float>::infinity(),
99             testModel.float_value_with_default());
100   EXPECT_EQ(-std::numeric_limits<double>::infinity(),
101             testModel.double_value_with_default());
102 
103   // Set value.
104   testModel.set_value(5);
105   EXPECT_TRUE(testModel.has_value());
106   EXPECT_EQ(testModel.value(), 5);
107   // Change value.
108   testModel.set_value(10);
109   EXPECT_TRUE(testModel.has_value());
110   EXPECT_EQ(testModel.value(), 10);
111   // Clear value.
112   testModel.clear_value();
113   EXPECT_FALSE(testModel.has_value());
114   EXPECT_EQ(testModel.value(), 0);
115 }
116 
117 const char kTestStr1[] = "abcdefg";
118 const char kTestStr2[] = "just another test string";
119 
TEST(CppGeneratedCode,Strings)120 TEST(CppGeneratedCode, Strings) {
121   TestModel testModel;
122   testModel.set_str1(kTestStr1);
123   testModel.set_str2(kTestStr2);
124   EXPECT_EQ(testModel.str1(), kTestStr1);
125   EXPECT_EQ(testModel.str2(), kTestStr2);
126   EXPECT_TRUE(testModel.has_str1());
127   EXPECT_TRUE(testModel.has_str2());
128 
129   testModel.clear_str1();
130   EXPECT_FALSE(testModel.has_str1());
131   EXPECT_TRUE(testModel.has_str2());
132 }
133 
TEST(CppGeneratedCode,ScalarUInt32)134 TEST(CppGeneratedCode, ScalarUInt32) {
135   ::hpb::Arena arena;
136   auto testModel = ::hpb::CreateMessage<TestModel>(arena);
137   // Test defaults.
138   EXPECT_EQ(testModel.optional_uint32(), 0);
139   EXPECT_FALSE(testModel.has_optional_uint32());
140   // Set value.
141   testModel.set_optional_uint32(0xA0001000);
142   EXPECT_TRUE(testModel.has_optional_uint32());
143   EXPECT_EQ(testModel.optional_uint32(), 0xA0001000);
144   // Change value.
145   testModel.set_optional_uint32(0x70002000);
146   EXPECT_TRUE(testModel.has_optional_uint32());
147   EXPECT_EQ(testModel.optional_uint32(), 0x70002000);
148   // Clear value.
149   testModel.clear_optional_uint32();
150   EXPECT_FALSE(testModel.has_optional_uint32());
151   EXPECT_EQ(testModel.optional_uint32(), 0);
152 }
153 
TEST(CppGeneratedCode,ScalarInt64)154 TEST(CppGeneratedCode, ScalarInt64) {
155   ::hpb::Arena arena;
156   auto testModel = ::hpb::CreateMessage<TestModel>(arena);
157   // Test defaults.
158   EXPECT_EQ(testModel.optional_int64(), 0);
159   EXPECT_FALSE(testModel.has_optional_int64());
160   // Set value.
161   testModel.set_optional_int64(static_cast<int64_t>(0xFF00CCDDA0001000));
162   EXPECT_TRUE(testModel.has_optional_int64());
163   EXPECT_EQ(testModel.optional_int64(), 0xFF00CCDDA0001000);
164   // Change value.
165   testModel.set_optional_int64(static_cast<int64_t>(0xFF00CCDD70002000));
166   EXPECT_TRUE(testModel.has_optional_int64());
167   EXPECT_EQ(testModel.optional_int64(), 0xFF00CCDD70002000);
168   // Clear value.
169   testModel.clear_optional_int64();
170   EXPECT_FALSE(testModel.has_optional_int64());
171   EXPECT_EQ(testModel.optional_int64(), 0);
172   // Set after clear.
173   testModel.set_optional_int64(static_cast<int64_t>(0xFF00CCDDA0001000));
174   EXPECT_TRUE(testModel.has_optional_int64());
175   EXPECT_EQ(testModel.optional_int64(), 0xFF00CCDDA0001000);
176 }
177 
TEST(CppGeneratedCode,ScalarFloat)178 TEST(CppGeneratedCode, ScalarFloat) {
179   ::hpb::Arena arena;
180   auto testModel = ::hpb::CreateMessage<TestModel>(arena);
181   // Test defaults.
182   EXPECT_EQ(testModel.optional_float(), 0.0f);
183   EXPECT_FALSE(testModel.has_optional_float());
184   EXPECT_EQ(std::numeric_limits<float>::infinity(),
185             testModel.float_value_with_default());
186   EXPECT_EQ(-std::numeric_limits<double>::infinity(),
187             testModel.double_value_with_default());
188   // Set value.
189   testModel.set_optional_float(3.14159265f);
190   EXPECT_TRUE(testModel.has_optional_float());
191   EXPECT_NEAR(testModel.optional_float(), 3.14159265f, 1e-9f);
192   // Change value.
193   testModel.set_optional_float(-2.0f);
194   EXPECT_TRUE(testModel.has_optional_float());
195   EXPECT_NEAR(testModel.optional_float(), -2, 1e-9f);
196   // Clear value.
197   testModel.clear_optional_float();
198   EXPECT_FALSE(testModel.has_optional_float());
199   EXPECT_EQ(testModel.optional_float(), 0.0f);
200   // Set after clear.
201   testModel.set_optional_float(3.14159265f);
202   EXPECT_TRUE(testModel.has_optional_float());
203   EXPECT_NEAR(testModel.optional_float(), 3.14159265f, 1e-9f);
204 }
205 
TEST(CppGeneratedCode,ScalarDouble)206 TEST(CppGeneratedCode, ScalarDouble) {
207   ::hpb::Arena arena;
208   auto testModel = ::hpb::CreateMessage<TestModel>(arena);
209   // Test defaults.
210   EXPECT_EQ(testModel.optional_double(), 0.0);
211   EXPECT_FALSE(testModel.has_optional_double());
212   // Set value.
213   testModel.set_optional_double(3.141592653589793);
214   EXPECT_TRUE(testModel.has_optional_double());
215   EXPECT_NEAR(testModel.optional_double(), 3.141592653589793, 1e-16f);
216   // Change value.
217   testModel.set_optional_double(-1.0);
218   EXPECT_TRUE(testModel.has_optional_double());
219   EXPECT_NEAR(testModel.optional_double(), -1.0, 1e-16f);
220   // Clear value.
221   testModel.clear_optional_double();
222   EXPECT_FALSE(testModel.has_optional_double());
223   EXPECT_EQ(testModel.optional_double(), 0.0f);
224   // Set after clear.
225   testModel.set_optional_double(3.141592653589793);
226   EXPECT_TRUE(testModel.has_optional_double());
227   EXPECT_NEAR(testModel.optional_double(), 3.141592653589793, 1e-16f);
228 }
229 
TEST(CppGeneratedCode,Enums)230 TEST(CppGeneratedCode, Enums) {
231   ::hpb::Arena arena;
232   auto testModel = ::hpb::CreateMessage<TestModel>(arena);
233 
234   // Check enum default value.
235   EXPECT_EQ(TestModel_Category_IMAGES, 5);
236 
237   // Test defaults.
238   EXPECT_FALSE(testModel.has_category());
239   EXPECT_EQ(testModel.category(), TestModel_Category_IMAGES);
240   // Set value.
241   testModel.set_category(TestModel_Category_NEWS);
242   EXPECT_TRUE(testModel.has_category());
243   EXPECT_EQ(testModel.category(), TestModel_Category_NEWS);
244   // Change value.
245   testModel.set_category(TestModel_Category_VIDEO);
246   EXPECT_TRUE(testModel.has_category());
247   EXPECT_EQ(testModel.category(), TestModel_Category_VIDEO);
248   // Clear value.
249   testModel.clear_category();
250   EXPECT_FALSE(testModel.has_category());
251   EXPECT_EQ(testModel.category(), TestModel_Category_IMAGES);
252   // Set after clear.
253   testModel.set_category(TestModel_Category_VIDEO);
254   EXPECT_TRUE(testModel.has_category());
255   EXPECT_EQ(testModel.category(), TestModel_Category_VIDEO);
256 }
257 
TEST(CppGeneratedCode,FieldWithDefaultValue)258 TEST(CppGeneratedCode, FieldWithDefaultValue) {
259   ::hpb::Arena arena;
260   auto testModel = ::hpb::CreateMessage<TestModel>(arena);
261 
262   EXPECT_FALSE(testModel.has_int_value_with_default());
263   EXPECT_EQ(testModel.int_value_with_default(), 65);
264   testModel.set_int_value_with_default(10);
265   EXPECT_EQ(testModel.int_value_with_default(), 10);
266 
267   EXPECT_FALSE(testModel.has_string_value_with_default());
268   EXPECT_EQ(testModel.string_value_with_default(), "hello");
269   testModel.set_string_value_with_default("new string");
270   EXPECT_EQ(testModel.string_value_with_default(), "new string");
271 }
272 
TEST(CppGeneratedCode,OneOfFields)273 TEST(CppGeneratedCode, OneOfFields) {
274   ::hpb::Arena arena;
275   auto test_model = ::hpb::CreateMessage<TestModel>(arena);
276 
277   EXPECT_FALSE(test_model.has_oneof_member1());
278   EXPECT_FALSE(test_model.has_oneof_member2());
279   EXPECT_EQ(TestModel::CHILD_ONEOF1_NOT_SET, test_model.child_oneof1_case());
280 
281   test_model.set_oneof_member1("one of string");
282   EXPECT_TRUE(test_model.has_oneof_member1());
283   EXPECT_FALSE(test_model.has_oneof_member2());
284   EXPECT_EQ(test_model.oneof_member1(), "one of string");
285   EXPECT_EQ(TestModel::kOneofMember1, test_model.child_oneof1_case());
286 
287   test_model.set_oneof_member2(true);
288   EXPECT_FALSE(test_model.has_oneof_member1());
289   EXPECT_TRUE(test_model.has_oneof_member2());
290   EXPECT_EQ(test_model.oneof_member2(), true);
291   EXPECT_EQ(TestModel::kOneofMember2, test_model.child_oneof1_case());
292 
293   test_model.clear_oneof_member2();
294   EXPECT_FALSE(test_model.has_oneof_member1());
295   EXPECT_FALSE(test_model.has_oneof_member2());
296   EXPECT_EQ(test_model.oneof_member1(), "");
297   EXPECT_EQ(test_model.oneof_member2(), false);
298   EXPECT_EQ(TestModel::CHILD_ONEOF1_NOT_SET, test_model.child_oneof1_case());
299 }
300 
TEST(CppGeneratedCode,Messages)301 TEST(CppGeneratedCode, Messages) {
302   ::hpb::Arena arena;
303   auto test_model = ::hpb::CreateMessage<TestModel>(arena);
304   EXPECT_EQ(false, test_model.has_child_model_1());
305   auto child_model = test_model.child_model_1();
306   EXPECT_EQ(false, child_model->has_child_b1());
307   EXPECT_EQ(false, child_model->child_b1());
308   auto mutable_child = test_model.mutable_child_model_1();
309   mutable_child->set_child_b1(true);
310   EXPECT_EQ(true, mutable_child->has_child_b1());
311   EXPECT_EQ(true, mutable_child->child_b1());
312   // The View should not change due to mutation since it
313   // is default_instance.
314   EXPECT_EQ(false, child_model->has_child_b1());
315   // Readonly View should now show change.
316   child_model = test_model.child_model_1();
317   EXPECT_EQ(true, child_model->has_child_b1());
318   EXPECT_EQ(true, child_model->child_b1());
319   // Clear message field.
320   EXPECT_EQ(true, test_model.has_child_model_1());
321   test_model.clear_child_model_1();
322   EXPECT_EQ(false, test_model.has_child_model_1());
323 }
324 
TEST(CppGeneratedCode,NestedMessages)325 TEST(CppGeneratedCode, NestedMessages) {
326   ::hpb::Arena arena;
327   auto test_model = ::hpb::CreateMessage<TestModel>(arena);
328   auto nested_child = test_model.nested_child_1();
329   EXPECT_EQ(0, nested_child->nested_child_name().size());
330   auto mutable_nested_child = test_model.mutable_nested_child_1();
331   EXPECT_EQ(false, mutable_nested_child->has_nested_child_name());
332   mutable_nested_child->set_nested_child_name(kTestStr1);
333   EXPECT_EQ(true, mutable_nested_child->has_nested_child_name());
334 }
335 
TEST(CppGeneratedCode,RepeatedMessages)336 TEST(CppGeneratedCode, RepeatedMessages) {
337   ::hpb::Arena arena;
338   auto test_model = ::hpb::CreateMessage<TestModel>(arena);
339   EXPECT_EQ(0, test_model.child_models_size());
340   // Should be able to clear repeated field when empty.
341   test_model.mutable_child_models()->clear();
342   EXPECT_EQ(0, test_model.child_models_size());
343   // Add 2 children.
344   auto new_child = test_model.add_child_models();
345   EXPECT_EQ(true, new_child.ok());
346   new_child.value()->set_child_str1(kTestStr1);
347   new_child = test_model.add_child_models();
348   EXPECT_EQ(true, new_child.ok());
349   new_child.value()->set_child_str1(kTestStr2);
350   EXPECT_EQ(2, test_model.child_models_size());
351   // Mutable access.
352   auto mutable_first = test_model.mutable_child_models(0);
353   EXPECT_EQ(mutable_first->child_str1(), kTestStr1);
354   mutable_first->set_child_str1("change1");
355   auto mutable_second = test_model.mutable_child_models(1);
356   EXPECT_EQ(mutable_second->child_str1(), kTestStr2);
357   mutable_second->set_child_str1("change2");
358   // Check mutations using views.
359   auto view_first = test_model.child_models(0);
360   EXPECT_EQ(view_first->child_str1(), "change1");
361   auto view_second = test_model.child_models(1);
362   EXPECT_EQ(view_second->child_str1(), "change2");
363 }
364 
TEST(CppGeneratedCode,RepeatedScalar)365 TEST(CppGeneratedCode, RepeatedScalar) {
366   ::hpb::Arena arena;
367   auto test_model = ::hpb::CreateMessage<TestModel>(arena);
368   EXPECT_EQ(0, test_model.value_array_size());
369   // Should be able to clear repeated field when empty.
370   test_model.mutable_value_array()->clear();
371   EXPECT_EQ(0, test_model.value_array_size());
372   // Add 2 children.
373   EXPECT_EQ(true, test_model.add_value_array(5));
374   EXPECT_EQ(true, test_model.add_value_array(6));
375   EXPECT_EQ(2, test_model.value_array_size());
376   EXPECT_EQ(5, test_model.value_array(0));
377   EXPECT_EQ(6, test_model.value_array(1));
378   EXPECT_EQ(true, test_model.resize_value_array(3));
379   EXPECT_EQ(3, test_model.value_array_size());
380   test_model.set_value_array(2, 7);
381   EXPECT_EQ(5, test_model.value_array(0));
382   EXPECT_EQ(6, test_model.value_array(1));
383   EXPECT_EQ(7, test_model.value_array(2));
384 }
385 
TEST(CppGeneratedCode,RepeatedFieldClear)386 TEST(CppGeneratedCode, RepeatedFieldClear) {
387   ::hpb::Arena arena;
388   auto test_model = ::hpb::CreateMessage<TestModel>(arena);
389   test_model.mutable_value_array()->push_back(5);
390   test_model.mutable_value_array()->push_back(16);
391   test_model.mutable_value_array()->push_back(27);
392   ASSERT_EQ(test_model.mutable_value_array()->size(), 3);
393   test_model.mutable_value_array()->clear();
394   EXPECT_EQ(test_model.mutable_value_array()->size(), 0);
395 }
396 
TEST(CppGeneratedCode,RepeatedFieldProxyForScalars)397 TEST(CppGeneratedCode, RepeatedFieldProxyForScalars) {
398   ::hpb::Arena arena;
399   auto test_model = ::hpb::CreateMessage<TestModel>(arena);
400   EXPECT_EQ(0, test_model.value_array().size());
401   EXPECT_EQ(0, test_model.mutable_value_array()->size());
402 
403   test_model.mutable_value_array()->push_back(5);
404   test_model.mutable_value_array()->push_back(16);
405   test_model.mutable_value_array()->push_back(27);
406 
407   ASSERT_EQ(test_model.mutable_value_array()->size(), 3);
408   EXPECT_EQ((*test_model.mutable_value_array())[0], 5);
409   EXPECT_EQ((*test_model.mutable_value_array())[1], 16);
410   EXPECT_EQ((*test_model.mutable_value_array())[2], 27);
411 
412   const auto value_array = test_model.value_array();
413   ASSERT_EQ(value_array.size(), 3);
414   EXPECT_EQ(value_array[0], 5);
415   EXPECT_EQ(value_array[1], 16);
416   EXPECT_EQ(value_array[2], 27);
417 
418   EXPECT_THAT(value_array, ElementsAre(5, 16, 27));
419 
420   EXPECT_THAT(std::vector(value_array.begin(), value_array.end()),
421               ElementsAre(5, 16, 27));
422   EXPECT_THAT(std::vector(value_array.cbegin(), value_array.cend()),
423               ElementsAre(5, 16, 27));
424   EXPECT_THAT(std::vector(value_array.rbegin(), value_array.rend()),
425               ElementsAre(27, 16, 5));
426   EXPECT_THAT(std::vector(value_array.crbegin(), value_array.crend()),
427               ElementsAre(27, 16, 5));
428 }
429 
TEST(CppGeneratedCode,RepeatedScalarIterator)430 TEST(CppGeneratedCode, RepeatedScalarIterator) {
431   ::hpb::Arena arena;
432   auto test_model = ::hpb::CreateMessage<TestModel>(arena);
433   test_model.mutable_value_array()->push_back(5);
434   test_model.mutable_value_array()->push_back(16);
435   test_model.mutable_value_array()->push_back(27);
436   int sum = 0;
437   // Access by value.
438   const ::hpb::RepeatedField<int32_t>::CProxy rep1 = test_model.value_array();
439   for (auto i : rep1) {
440     sum += i;
441   }
442   EXPECT_EQ(sum, 5 + 16 + 27);
443   // Access by const reference.
444   sum = 0;
445   for (const auto& i : *test_model.mutable_value_array()) {
446     sum += i;
447   }
448   EXPECT_EQ(sum, 5 + 16 + 27);
449   // Access by forwarding reference.
450   sum = 0;
451   for (auto&& i : *test_model.mutable_value_array()) {
452     sum += i;
453   }
454   EXPECT_EQ(sum, 5 + 16 + 27);
455   // Test iterator operators.
456   auto begin = test_model.value_array().begin();
457   auto end = test_model.value_array().end();
458   sum = 0;
459   for (auto it = begin; it != end; ++it) {
460     sum += *it;
461   }
462   EXPECT_EQ(sum, 5 + 16 + 27);
463   auto it = begin;
464   ++it;
465   EXPECT_TRUE(begin < it);
466   EXPECT_TRUE(begin <= it);
467   it = end;
468   EXPECT_TRUE(it == end);
469   EXPECT_TRUE(it > begin);
470   EXPECT_TRUE(it >= begin);
471   EXPECT_TRUE(it != begin);
472   // difference type
473   it = end;
474   --it;
475   --it;
476   EXPECT_EQ(end - it, 2);
477   it = begin;
478   EXPECT_EQ(it[0], 5);
479   EXPECT_EQ(it[1], 16);
480   EXPECT_EQ(it[2], 27);
481   // ValueProxy.
482   sum = 0;
483   for (::hpb::RepeatedField<int32_t>::ValueCProxy c :
484        test_model.value_array()) {
485     sum += c;
486   }
487   EXPECT_EQ(sum, 5 + 16 + 27);
488   sum = 0;
489   for (::hpb::RepeatedField<int32_t>::ValueProxy c :
490        *test_model.mutable_value_array()) {
491     sum += c;
492   }
493   EXPECT_EQ(sum, 5 + 16 + 27);
494 }
495 
TEST(CppGeneratedCode,RepeatedFieldProxyForStrings)496 TEST(CppGeneratedCode, RepeatedFieldProxyForStrings) {
497   ::hpb::Arena arena;
498   auto test_model = ::hpb::CreateMessage<TestModel>(arena);
499   EXPECT_EQ(0, test_model.repeated_string().size());
500   EXPECT_EQ(0, test_model.mutable_repeated_string()->size());
501 
502   test_model.mutable_repeated_string()->push_back("a");
503   test_model.mutable_repeated_string()->push_back("b");
504   test_model.mutable_repeated_string()->push_back("c");
505 
506   ASSERT_EQ(test_model.repeated_string().size(), 3);
507   EXPECT_EQ(test_model.repeated_string()[0], "a");
508   EXPECT_EQ(test_model.repeated_string()[1], "b");
509   EXPECT_EQ(test_model.repeated_string()[2], "c");
510 
511   EXPECT_THAT(test_model.repeated_string(), ElementsAre("a", "b", "c"));
512   EXPECT_THAT(*test_model.mutable_repeated_string(),
513               ElementsAre("a", "b", "c"));
514 
515   ASSERT_EQ(test_model.mutable_repeated_string()->size(), 3);
516   EXPECT_EQ((*test_model.mutable_repeated_string())[0], "a");
517   EXPECT_EQ((*test_model.mutable_repeated_string())[1], "b");
518   EXPECT_EQ((*test_model.mutable_repeated_string())[2], "c");
519 
520   // The const accessor can't be used to modify the element
521   EXPECT_FALSE((std::is_assignable<decltype(test_model.repeated_string()[1]),
522                                    absl::string_view>::value));
523   // But the mutable one is fine.
524   (*test_model.mutable_repeated_string())[1] = "other";
525   EXPECT_THAT(test_model.repeated_string(), ElementsAre("a", "other", "c"));
526 
527   test_model.mutable_repeated_string()->clear();
528   EXPECT_EQ(test_model.mutable_repeated_string()->size(), 0);
529 }
530 
TEST(CppGeneratedCode,RepeatedFieldProxyForMessages)531 TEST(CppGeneratedCode, RepeatedFieldProxyForMessages) {
532   ::hpb::Arena arena;
533   auto test_model = ::hpb::CreateMessage<TestModel>(arena);
534   EXPECT_EQ(0, test_model.child_models().size());
535   ChildModel1 child1;
536   child1.set_child_str1(kTestStr1);
537   test_model.mutable_child_models()->push_back(child1);
538   ChildModel1 child2;
539   child2.set_child_str1(kTestStr2);
540   test_model.mutable_child_models()->push_back(std::move(child2));
541 
542   int i = 0;
543   for (auto child : test_model.child_models()) {
544     EXPECT_FALSE(Requires<decltype(child)>(
545         [](auto&& x) -> decltype(x.set_child_str1("")) {}));
546     if (i++ == 0) {
547       EXPECT_EQ(child.child_str1(), kTestStr1);
548     } else {
549       EXPECT_EQ(child.child_str1(), kTestStr2);
550     }
551   }
552 
553   i = 0;
554   for (const auto& child : *test_model.mutable_child_models()) {
555     if (i++ == 0) {
556       EXPECT_EQ(child.child_str1(), kTestStr1);
557     } else {
558       EXPECT_EQ(child.child_str1(), kTestStr2);
559     }
560   }
561 
562   using testing::_;
563   EXPECT_THAT(test_model.child_models(), ElementsAre(_, _));
564 
565   EXPECT_EQ(test_model.child_models().size(), 2);
566   EXPECT_EQ(test_model.child_models()[0].child_str1(), kTestStr1);
567   EXPECT_EQ(test_model.child_models()[1].child_str1(), kTestStr2);
568   EXPECT_EQ((*test_model.mutable_child_models())[0].child_str1(), kTestStr1);
569   EXPECT_EQ((*test_model.mutable_child_models())[1].child_str1(), kTestStr2);
570   (*test_model.mutable_child_models())[0].set_child_str1("change1");
571   EXPECT_EQ((*test_model.mutable_child_models())[0].child_str1(), "change1");
572   test_model.mutable_child_models()->clear();
573   EXPECT_EQ(test_model.mutable_child_models()->size(), 0);
574 }
575 
TEST(CppGeneratedCode,EmptyRepeatedFieldProxyForMessages)576 TEST(CppGeneratedCode, EmptyRepeatedFieldProxyForMessages) {
577   ::hpb::Arena arena;
578   auto test_model = ::hpb::CreateMessage<TestModel>(arena);
579   EXPECT_EQ(0, test_model.child_models().size());
580   ChildModel1 child1;
581   child1.set_child_str1(kTestStr1);
582 
583   EXPECT_EQ(test_model.child_models().size(), 0);
584   EXPECT_EQ(std::distance(test_model.child_models().begin(),
585                           test_model.child_models().end()),
586             0);
587 }
588 
TEST(CppGeneratedCode,RepeatedFieldProxyForMessagesIndexOperator)589 TEST(CppGeneratedCode, RepeatedFieldProxyForMessagesIndexOperator) {
590   ::hpb::Arena arena;
591   auto test_model = ::hpb::CreateMessage<TestModel>(arena);
592   EXPECT_EQ(0, test_model.child_models().size());
593   ChildModel1 child1;
594   child1.set_child_str1(kTestStr1);
595   test_model.mutable_child_models()->push_back(child1);
596   ChildModel1 child2;
597 
598   child2.set_child_str1(kTestStr2);
599   test_model.mutable_child_models()->push_back(std::move(child2));
600   ASSERT_EQ(test_model.child_models().size(), 2);
601 
602   // test_model.child_models()[0].set_child_str1("change1");
603   (*test_model.mutable_child_models())[0].set_child_str1("change1");
604   EXPECT_EQ((*test_model.mutable_child_models())[0].child_str1(), "change1");
605 }
606 
TEST(CppGeneratedCode,RepeatedStrings)607 TEST(CppGeneratedCode, RepeatedStrings) {
608   ::hpb::Arena arena;
609   auto test_model = ::hpb::CreateMessage<TestModel>(arena);
610   EXPECT_EQ(0, test_model.repeated_string_size());
611   // Should be able to clear repeated field when empty.
612   test_model.mutable_repeated_string()->clear();
613   EXPECT_EQ(0, test_model.repeated_string_size());
614   // Add 2 children.
615   EXPECT_EQ(true, test_model.add_repeated_string("Hello"));
616   EXPECT_EQ(true, test_model.add_repeated_string("World"));
617   EXPECT_EQ(2, test_model.repeated_string_size());
618   EXPECT_EQ("Hello", test_model.repeated_string(0));
619   EXPECT_EQ("World", test_model.repeated_string(1));
620   EXPECT_EQ(true, test_model.resize_repeated_string(3));
621   EXPECT_EQ(3, test_model.repeated_string_size());
622   test_model.set_repeated_string(2, "Test");
623   EXPECT_EQ("Hello", test_model.repeated_string(0));
624   EXPECT_EQ("World", test_model.repeated_string(1));
625   EXPECT_EQ("Test", test_model.repeated_string(2));
626 }
627 
TEST(CppGeneratedCode,MessageMapInt32KeyMessageValue)628 TEST(CppGeneratedCode, MessageMapInt32KeyMessageValue) {
629   const int key_test_value = 3;
630   ::hpb::Arena arena;
631   ::hpb::Arena child_arena;
632   auto test_model = ::hpb::CreateMessage<TestModel>(arena);
633   EXPECT_EQ(0, test_model.child_map_size());
634   test_model.clear_child_map();
635   EXPECT_EQ(0, test_model.child_map_size());
636   auto child_model1 = ::hpb::CreateMessage<ChildModel1>(child_arena);
637   child_model1.set_child_str1("abc");
638   test_model.set_child_map(key_test_value, child_model1);
639   auto map_result = test_model.get_child_map(key_test_value);
640   EXPECT_EQ(true, map_result.ok());
641   EXPECT_EQ("abc", map_result.value()->child_str1());
642   // Now mutate original child model to verify that value semantics are
643   // preserved.
644   child_model1.set_child_str1("abc V2");
645   EXPECT_EQ("abc", map_result.value()->child_str1());
646   test_model.delete_child_map(key_test_value);
647   auto map_result_after_delete = test_model.get_child_map(key_test_value);
648   EXPECT_EQ(false, map_result_after_delete.ok());
649 }
650 
TEST(CppGeneratedCode,MessageMapStringKeyAndStringValue)651 TEST(CppGeneratedCode, MessageMapStringKeyAndStringValue) {
652   ::hpb::Arena arena;
653   auto test_model = ::hpb::CreateMessage<TestModel>(arena);
654   EXPECT_EQ(0, test_model.str_to_str_map_size());
655   test_model.clear_str_to_str_map();
656   EXPECT_EQ(0, test_model.str_to_str_map_size());
657   test_model.set_str_to_str_map("first", "abc");
658   test_model.set_str_to_str_map("second", "def");
659   auto result = test_model.get_str_to_str_map("second");
660   EXPECT_EQ(true, result.ok());
661   EXPECT_EQ("def", result.value());
662   test_model.delete_str_to_str_map("first");
663   auto result_after_delete = test_model.get_str_to_str_map("first");
664   EXPECT_EQ(false, result_after_delete.ok());
665 }
666 
TEST(CppGeneratedCode,MessageMapStringKeyAndInt32Value)667 TEST(CppGeneratedCode, MessageMapStringKeyAndInt32Value) {
668   ::hpb::Arena arena;
669   auto test_model = ::hpb::CreateMessage<TestModel>(arena);
670   EXPECT_EQ(0, test_model.str_to_int_map_size());
671   test_model.clear_str_to_int_map();
672   EXPECT_EQ(0, test_model.str_to_int_map_size());
673   test_model.set_str_to_int_map("first", 10);
674   EXPECT_EQ(1, test_model.str_to_int_map_size());
675   test_model.set_str_to_int_map("second", 20);
676   EXPECT_EQ(2, test_model.str_to_int_map_size());
677   auto result = test_model.get_str_to_int_map("second");
678   EXPECT_EQ(true, result.ok());
679   EXPECT_EQ(20, result.value());
680   test_model.delete_str_to_int_map("first");
681   auto result_after_delete = test_model.get_str_to_int_map("first");
682   EXPECT_EQ(false, result_after_delete.ok());
683 }
684 
TEST(CppGeneratedCode,HasExtension)685 TEST(CppGeneratedCode, HasExtension) {
686   TestModel model;
687   EXPECT_EQ(false, ::hpb::HasExtension(&model, theme));
688 }
689 
TEST(CppGeneratedCode,HasExtensionPtr)690 TEST(CppGeneratedCode, HasExtensionPtr) {
691   TestModel model;
692   EXPECT_EQ(false, ::hpb::HasExtension(model.recursive_child(), theme));
693 }
694 
TEST(CppGeneratedCode,ClearExtensionWithEmptyExtension)695 TEST(CppGeneratedCode, ClearExtensionWithEmptyExtension) {
696   TestModel model;
697   EXPECT_EQ(false, ::hpb::HasExtension(&model, theme));
698   ::hpb::ClearExtension(&model, theme);
699   EXPECT_EQ(false, ::hpb::HasExtension(&model, theme));
700 }
701 
TEST(CppGeneratedCode,ClearExtensionWithEmptyExtensionPtr)702 TEST(CppGeneratedCode, ClearExtensionWithEmptyExtensionPtr) {
703   TestModel model;
704   ::hpb::Ptr<TestModel> recursive_child = model.mutable_recursive_child();
705   ::hpb::ClearExtension(recursive_child, theme);
706   EXPECT_EQ(false, ::hpb::HasExtension(recursive_child, theme));
707 }
708 
TEST(CppGeneratedCode,SetExtension)709 TEST(CppGeneratedCode, SetExtension) {
710   TestModel model;
711   void* prior_message;
712   {
713     // Use a nested scope to make sure the arenas are fused correctly.
714     ThemeExtension extension1;
715     extension1.set_ext_name("Hello World");
716     prior_message = hpb::interop::upb::GetMessage(&extension1);
717     EXPECT_EQ(false, ::hpb::HasExtension(&model, theme));
718     EXPECT_EQ(true,
719               ::hpb::SetExtension(&model, theme, std::move(extension1)).ok());
720   }
721   EXPECT_EQ(true, ::hpb::HasExtension(&model, theme));
722   auto ext = hpb::GetExtension(&model, theme);
723   EXPECT_TRUE(ext.ok());
724   EXPECT_EQ(hpb::interop::upb::GetMessage(*ext), prior_message);
725 }
726 
TEST(CppGeneratedCode,SetExtensionWithPtr)727 TEST(CppGeneratedCode, SetExtensionWithPtr) {
728   ::hpb::Arena arena_model;
729   ::hpb::Ptr<TestModel> model = ::hpb::CreateMessage<TestModel>(arena_model);
730   void* prior_message;
731   {
732     // Use a nested scope to make sure the arenas are fused correctly.
733     ::hpb::Arena arena;
734     ::hpb::Ptr<ThemeExtension> extension1 =
735         ::hpb::CreateMessage<ThemeExtension>(arena);
736     extension1->set_ext_name("Hello World");
737     prior_message = hpb::interop::upb::GetMessage(extension1);
738     EXPECT_EQ(false, ::hpb::HasExtension(model, theme));
739     auto res = ::hpb::SetExtension(model, theme, extension1);
740     EXPECT_EQ(true, res.ok());
741   }
742   EXPECT_EQ(true, ::hpb::HasExtension(model, theme));
743   auto ext = hpb::GetExtension(model, theme);
744   EXPECT_TRUE(ext.ok());
745   EXPECT_NE(hpb::interop::upb::GetMessage(*ext), prior_message);
746 }
747 
748 #ifndef _MSC_VER
TEST(CppGeneratedCode,SetExtensionShouldNotCompileForWrongType)749 TEST(CppGeneratedCode, SetExtensionShouldNotCompileForWrongType) {
750   ::hpb::Arena arena;
751   ::hpb::Ptr<TestModel> model = ::hpb::CreateMessage<TestModel>(arena);
752   ThemeExtension extension1;
753   ContainerExtension extension2;
754 
755   const auto canSetExtension = [&](auto l) {
756     return Requires<decltype(model)>(l);
757   };
758   EXPECT_TRUE(canSetExtension(
759       [](auto p) -> decltype(::hpb::SetExtension(p, theme, extension1)) {}));
760   // Wrong extension value type should fail to compile.
761   EXPECT_TRUE(!canSetExtension(
762       [](auto p) -> decltype(::hpb::SetExtension(p, theme, extension2)) {}));
763   // Wrong extension id with correct extension type should fail to compile.
764   EXPECT_TRUE(
765       !canSetExtension([](auto p) -> decltype(::hpb::SetExtension(
766                                       p, container_ext, extension1)) {}));
767 }
768 #endif
769 
TEST(CppGeneratedCode,SetExtensionWithPtrSameArena)770 TEST(CppGeneratedCode, SetExtensionWithPtrSameArena) {
771   ::hpb::Arena arena;
772   ::hpb::Ptr<TestModel> model = ::hpb::CreateMessage<TestModel>(arena);
773   void* prior_message;
774   {
775     // Use a nested scope to make sure the arenas are fused correctly.
776     ::hpb::Ptr<ThemeExtension> extension1 =
777         ::hpb::CreateMessage<ThemeExtension>(arena);
778     extension1->set_ext_name("Hello World");
779     prior_message = hpb::interop::upb::GetMessage(extension1);
780     EXPECT_EQ(false, ::hpb::HasExtension(model, theme));
781     auto res = ::hpb::SetExtension(model, theme, extension1);
782     EXPECT_EQ(true, res.ok());
783   }
784   EXPECT_EQ(true, ::hpb::HasExtension(model, theme));
785   auto ext = hpb::GetExtension(model, theme);
786   EXPECT_TRUE(ext.ok());
787   EXPECT_NE(hpb::interop::upb::GetMessage(*ext), prior_message);
788 }
789 
TEST(CppGeneratedCode,SetExtensionFusingFailureShouldCopy)790 TEST(CppGeneratedCode, SetExtensionFusingFailureShouldCopy) {
791   // Use an initial block to disallow fusing.
792   char initial_block[1000];
793   hpb::Arena arena(initial_block, sizeof(initial_block));
794 
795   hpb::Ptr<TestModel> model = ::hpb::CreateMessage<TestModel>(arena);
796 
797   ThemeExtension extension1;
798   extension1.set_ext_name("Hello World");
799   ASSERT_FALSE(
800       upb_Arena_Fuse(arena.ptr(), hpb::interop::upb::GetArena(&extension1)));
801   EXPECT_FALSE(::hpb::HasExtension(model, theme));
802   auto status = ::hpb::SetExtension(model, theme, std::move(extension1));
803   EXPECT_TRUE(status.ok());
804   EXPECT_TRUE(::hpb::HasExtension(model, theme));
805   EXPECT_TRUE(hpb::GetExtension(model, theme).ok());
806 }
807 
TEST(CppGeneratedCode,SetExtensionShouldClone)808 TEST(CppGeneratedCode, SetExtensionShouldClone) {
809   TestModel model;
810   ThemeExtension extension1;
811   extension1.set_ext_name("Hello World");
812   EXPECT_EQ(false, ::hpb::HasExtension(&model, theme));
813   EXPECT_EQ(true, ::hpb::SetExtension(&model, theme, extension1).ok());
814   extension1.set_ext_name("Goodbye");
815   EXPECT_EQ(true, ::hpb::HasExtension(&model, theme));
816   auto ext = hpb::GetExtension(&model, theme);
817   EXPECT_TRUE(ext.ok());
818   EXPECT_EQ((*ext)->ext_name(), "Hello World");
819 }
820 
TEST(CppGeneratedCode,SetExtensionShouldCloneConst)821 TEST(CppGeneratedCode, SetExtensionShouldCloneConst) {
822   TestModel model;
823   ThemeExtension extension1;
824   extension1.set_ext_name("Hello World");
825   EXPECT_EQ(false, ::hpb::HasExtension(&model, theme));
826   EXPECT_EQ(true,
827             ::hpb::SetExtension(&model, theme, std::as_const(extension1)).ok());
828   extension1.set_ext_name("Goodbye");
829   EXPECT_EQ(true, ::hpb::HasExtension(&model, theme));
830   auto ext = hpb::GetExtension(&model, theme);
831   EXPECT_TRUE(ext.ok());
832   EXPECT_EQ((*ext)->ext_name(), "Hello World");
833 }
834 
TEST(CppGeneratedCode,SetExtensionOnMutableChild)835 TEST(CppGeneratedCode, SetExtensionOnMutableChild) {
836   TestModel model;
837   ThemeExtension extension1;
838   extension1.set_ext_name("Hello World");
839   EXPECT_EQ(false, ::hpb::HasExtension(model.mutable_recursive_child(), theme));
840   EXPECT_EQ(true, ::hpb::SetExtension(model.mutable_recursive_child(), theme,
841                                       extension1)
842                       .ok());
843   EXPECT_EQ(true, ::hpb::HasExtension(model.mutable_recursive_child(), theme));
844 }
845 
TEST(CppGeneratedCode,GetExtension)846 TEST(CppGeneratedCode, GetExtension) {
847   TestModel model;
848   ThemeExtension extension1;
849   extension1.set_ext_name("Hello World");
850   EXPECT_EQ(false, ::hpb::HasExtension(&model, theme));
851   EXPECT_EQ(true, ::hpb::SetExtension(&model, theme, extension1).ok());
852   EXPECT_EQ("Hello World",
853             hpb::GetExtension(&model, theme).value()->ext_name());
854 }
855 
TEST(CppGeneratedCode,GetExtensionOnMutableChild)856 TEST(CppGeneratedCode, GetExtensionOnMutableChild) {
857   TestModel model;
858   ThemeExtension extension1;
859   extension1.set_ext_name("Hello World");
860   ::hpb::Ptr<TestModel> mutable_recursive_child =
861       model.mutable_recursive_child();
862   EXPECT_EQ(false, ::hpb::HasExtension(mutable_recursive_child, theme));
863   EXPECT_EQ(
864       true,
865       ::hpb::SetExtension(mutable_recursive_child, theme, extension1).ok());
866   EXPECT_EQ(
867       "Hello World",
868       hpb::GetExtension(mutable_recursive_child, theme).value()->ext_name());
869 }
870 
TEST(CppGeneratedCode,GetExtensionOnImmutableChild)871 TEST(CppGeneratedCode, GetExtensionOnImmutableChild) {
872   TestModel model;
873   ThemeExtension extension1;
874   extension1.set_ext_name("Hello World");
875   ::hpb::Ptr<TestModel> mutable_recursive_child =
876       model.mutable_recursive_child();
877   EXPECT_EQ(false, ::hpb::HasExtension(mutable_recursive_child, theme));
878   EXPECT_EQ(
879       true,
880       ::hpb::SetExtension(mutable_recursive_child, theme, extension1).ok());
881   ::hpb::Ptr<const TestModel> recursive_child = model.recursive_child();
882   EXPECT_EQ("Hello World",
883             hpb::GetExtension(recursive_child, theme).value()->ext_name());
884 }
885 
TEST(CppGeneratedCode,SerializeUsingArena)886 TEST(CppGeneratedCode, SerializeUsingArena) {
887   TestModel model;
888   model.set_str1("Hello World");
889   ::upb::Arena arena;
890   absl::StatusOr<absl::string_view> bytes = ::hpb::Serialize(&model, arena);
891   EXPECT_EQ(true, bytes.ok());
892   TestModel parsed_model = ::hpb::Parse<TestModel>(bytes.value()).value();
893   EXPECT_EQ("Hello World", parsed_model.str1());
894 }
895 
TEST(CppGeneratedCode,SerializeProxyUsingArena)896 TEST(CppGeneratedCode, SerializeProxyUsingArena) {
897   ::upb::Arena message_arena;
898   TestModel::Proxy model_proxy = ::hpb::CreateMessage<TestModel>(message_arena);
899   model_proxy.set_str1("Hello World");
900   ::upb::Arena arena;
901   absl::StatusOr<absl::string_view> bytes =
902       ::hpb::Serialize(&model_proxy, arena);
903   EXPECT_EQ(true, bytes.ok());
904   TestModel parsed_model = ::hpb::Parse<TestModel>(bytes.value()).value();
905   EXPECT_EQ("Hello World", parsed_model.str1());
906 }
907 
TEST(CppGeneratedCode,SerializeNestedMessageUsingArena)908 TEST(CppGeneratedCode, SerializeNestedMessageUsingArena) {
909   TestModel model;
910   model.mutable_recursive_child()->set_str1("Hello World");
911   ::upb::Arena arena;
912   ::hpb::Ptr<const TestModel> child = model.recursive_child();
913   absl::StatusOr<absl::string_view> bytes = ::hpb::Serialize(child, arena);
914   EXPECT_EQ(true, bytes.ok());
915   TestModel parsed_model = ::hpb::Parse<TestModel>(bytes.value()).value();
916   EXPECT_EQ("Hello World", parsed_model.str1());
917 }
918 
TEST(CppGeneratedCode,Parse)919 TEST(CppGeneratedCode, Parse) {
920   TestModel model;
921   model.set_str1("Test123");
922   ThemeExtension extension1;
923   extension1.set_ext_name("Hello World");
924   EXPECT_EQ(true, ::hpb::SetExtension(&model, theme, extension1).ok());
925   ::upb::Arena arena;
926   auto bytes = ::hpb::Serialize(&model, arena);
927   EXPECT_EQ(true, bytes.ok());
928   TestModel parsed_model = ::hpb::Parse<TestModel>(bytes.value()).value();
929   EXPECT_EQ("Test123", parsed_model.str1());
930   EXPECT_EQ(true, hpb::GetExtension(&parsed_model, theme).ok());
931 }
932 
TEST(CppGeneratedCode,ParseIntoPtrToModel)933 TEST(CppGeneratedCode, ParseIntoPtrToModel) {
934   TestModel model;
935   model.set_str1("Test123");
936   ThemeExtension extension1;
937   extension1.set_ext_name("Hello World");
938   EXPECT_EQ(true, ::hpb::SetExtension(&model, theme, extension1).ok());
939   ::upb::Arena arena;
940   auto bytes = ::hpb::Serialize(&model, arena);
941   EXPECT_EQ(true, bytes.ok());
942   ::hpb::Ptr<TestModel> parsed_model = ::hpb::CreateMessage<TestModel>(arena);
943   EXPECT_TRUE(::hpb::Parse(parsed_model, bytes.value()));
944   EXPECT_EQ("Test123", parsed_model->str1());
945   // Should return an extension even if we don't pass ExtensionRegistry
946   // by promoting unknown.
947   EXPECT_EQ(true, hpb::GetExtension(parsed_model, theme).ok());
948 }
949 
TEST(CppGeneratedCode,ParseWithExtensionRegistry)950 TEST(CppGeneratedCode, ParseWithExtensionRegistry) {
951   TestModel model;
952   model.set_str1("Test123");
953   ThemeExtension extension1;
954   extension1.set_ext_name("Hello World");
955   EXPECT_EQ(true, ::hpb::SetExtension(&model, theme, extension1).ok());
956   EXPECT_EQ(true, ::hpb::SetExtension(&model, ThemeExtension::theme_extension,
957                                       extension1)
958                       .ok());
959   ::upb::Arena arena;
960   auto bytes = ::hpb::Serialize(&model, arena);
961   EXPECT_EQ(true, bytes.ok());
962   ::hpb::ExtensionRegistry extensions(
963       {&theme, &other_ext, &ThemeExtension::theme_extension}, arena);
964   TestModel parsed_model =
965       ::hpb::Parse<TestModel>(bytes.value(), extensions).value();
966   EXPECT_EQ("Test123", parsed_model.str1());
967   EXPECT_EQ(true, hpb::GetExtension(&parsed_model, theme).ok());
968   EXPECT_EQ(
969       true,
970       hpb::GetExtension(&parsed_model, ThemeExtension::theme_extension).ok());
971   EXPECT_EQ("Hello World",
972             hpb::GetExtension(&parsed_model, ThemeExtension::theme_extension)
973                 .value()
974                 ->ext_name());
975 }
976 
TEST(CppGeneratedCode,NameCollisions)977 TEST(CppGeneratedCode, NameCollisions) {
978   TestModel model;
979   model.set_template_("test");
980   EXPECT_EQ("test", model.template_());
981   model.set_arena__("test");
982   EXPECT_EQ("test", model.arena__());
983 }
984 
TEST(CppGeneratedCode,SharedPointer)985 TEST(CppGeneratedCode, SharedPointer) {
986   std::shared_ptr<TestModel> model = std::make_shared<TestModel>();
987   ::upb::Arena arena;
988   auto bytes = ::hpb::Serialize(model.get(), arena);
989   EXPECT_TRUE(::hpb::Parse(model.get(), bytes.value()));
990 }
991 
TEST(CppGeneratedCode,UniquePointer)992 TEST(CppGeneratedCode, UniquePointer) {
993   auto model = std::make_unique<TestModel>();
994   ::upb::Arena arena;
995   auto bytes = ::hpb::Serialize(model.get(), arena);
996   EXPECT_TRUE(::hpb::Parse(model.get(), bytes.value()));
997 }
998 
TEST(CppGeneratedCode,Assignment)999 TEST(CppGeneratedCode, Assignment) {
1000   TestModel model;
1001   model.set_category(5);
1002   model.mutable_child_model_1()->set_child_str1("text in child");
1003   TestModel model2 = model;
1004   EXPECT_EQ(5, model2.category());
1005   EXPECT_EQ(model2.child_model_1()->child_str1(), "text in child");
1006 }
1007 
TEST(CppGeneratedCode,PtrAssignment)1008 TEST(CppGeneratedCode, PtrAssignment) {
1009   TestModel model;
1010   model.mutable_child_model_1()->set_child_str1("text in child");
1011   ChildModel1 child_from_const_ptr = *model.child_model_1();
1012   EXPECT_EQ(child_from_const_ptr.child_str1(), "text in child");
1013   ChildModel1 child_from_ptr = *model.mutable_child_model_1();
1014   EXPECT_EQ(child_from_ptr.child_str1(), "text in child");
1015 }
1016 
TEST(CppGeneratedCode,CopyConstructor)1017 TEST(CppGeneratedCode, CopyConstructor) {
1018   TestModel model;
1019   model.set_category(6);
1020   TestModel model2(model);
1021   EXPECT_EQ(6, model2.category());
1022 }
1023 
TEST(CppGeneratedCode,PtrConstructor)1024 TEST(CppGeneratedCode, PtrConstructor) {
1025   TestModel model;
1026   model.mutable_child_model_1()->set_child_str1("text in child");
1027   ChildModel1 child_from_ptr(*model.mutable_child_model_1());
1028   EXPECT_EQ(child_from_ptr.child_str1(), "text in child");
1029   ChildModel1 child_from_const_ptr(*model.child_model_1());
1030   EXPECT_EQ(child_from_const_ptr.child_str1(), "text in child");
1031 }
1032 
TEST(CppGeneratedCode,MutableToProxy)1033 TEST(CppGeneratedCode, MutableToProxy) {
1034   TestModel model;
1035   ::hpb::Ptr<ChildModel1> child = model.mutable_child_model_1();
1036   (void)child;
1037 }
1038 
TEST(CppGeneratedCode,ProxyToCProxy)1039 TEST(CppGeneratedCode, ProxyToCProxy) {
1040   TestModel model;
1041   ::hpb::Ptr<ChildModel1> child = model.mutable_child_model_1();
1042   ::hpb::Ptr<const ChildModel1> child2 = child;
1043   (void)child2;
1044 }
1045 
TEST(CppGeneratedCode,MutableAccessorsAreHiddenInCProxy)1046 TEST(CppGeneratedCode, MutableAccessorsAreHiddenInCProxy) {
1047   TestModel model;
1048   ::hpb::Ptr<TestModel> proxy = &model;
1049   ::hpb::Ptr<const TestModel> cproxy = proxy;
1050 
1051   const auto test_const_accessors = [](auto p) {
1052     // We don't want to run it, just check it compiles.
1053     if (false) {
1054       (void)p->has_str1();
1055       (void)p->str1();
1056       (void)p->has_value();
1057       (void)p->value();
1058       (void)p->has_oneof_member1();
1059       (void)p->oneof_member1();
1060       (void)p->value_array();
1061       (void)p->value_array_size();
1062       (void)p->value_array(1);
1063       (void)p->has_nested_child_1();
1064       (void)p->nested_child_1();
1065       (void)p->child_models();
1066       (void)p->child_models_size();
1067       (void)p->child_models(1);
1068       (void)p->child_map_size();
1069       (void)p->get_child_map(1);
1070     }
1071   };
1072 
1073   test_const_accessors(proxy);
1074   test_const_accessors(cproxy);
1075 
1076   const auto test_mutable_accessors = [](auto p, bool expected) {
1077     const auto r = [&](auto l) { return Requires<decltype(p)>(l) == expected; };
1078     EXPECT_TRUE(r([](auto p) -> decltype(p->set_str1("")) {}));
1079     EXPECT_TRUE(r([](auto p) -> decltype(p->clear_str1()) {}));
1080     EXPECT_TRUE(r([](auto p) -> decltype(p->set_value(1)) {}));
1081     EXPECT_TRUE(r([](auto p) -> decltype(p->clear_value()) {}));
1082     EXPECT_TRUE(r([](auto p) -> decltype(p->set_oneof_member1("")) {}));
1083     EXPECT_TRUE(r([](auto p) -> decltype(p->clear_oneof_member1()) {}));
1084     EXPECT_TRUE(r([](auto p) -> decltype(p->mutable_nested_child_1()) {}));
1085     EXPECT_TRUE(r([](auto p) -> decltype(p->clear_nested_child_1()) {}));
1086     EXPECT_TRUE(r([](auto p) -> decltype(p->add_value_array(1)) {}));
1087     EXPECT_TRUE(r([](auto p) -> decltype(p->mutable_value_array()) {}));
1088     EXPECT_TRUE(r([](auto p) -> decltype(p->resize_value_array(1)) {}));
1089     EXPECT_TRUE(r([](auto p) -> decltype(p->set_value_array(1, 1)) {}));
1090     EXPECT_TRUE(r([](auto p) -> decltype(p->add_child_models()) {}));
1091     EXPECT_TRUE(r([](auto p) -> decltype(p->mutable_child_models(1)) {}));
1092     EXPECT_TRUE(r([](auto p) -> decltype(p->clear_child_map()) {}));
1093     EXPECT_TRUE(r([](auto p) -> decltype(p->delete_child_map(1)) {}));
1094     EXPECT_TRUE(r(
1095         [](auto p) -> decltype(p->set_child_map(1, *p->get_child_map(1))) {}));
1096   };
1097   test_mutable_accessors(proxy, true);
1098   test_mutable_accessors(cproxy, false);
1099 }
1100 
ProxyToCProxyMethod(::hpb::Ptr<const ChildModel1> child)1101 bool ProxyToCProxyMethod(::hpb::Ptr<const ChildModel1> child) {
1102   return child->child_str1() == "text in child";
1103 }
1104 
TEST(CppGeneratedCode,PassProxyToCProxy)1105 TEST(CppGeneratedCode, PassProxyToCProxy) {
1106   TestModel model;
1107   model.mutable_child_model_1()->set_child_str1("text in child");
1108   EXPECT_TRUE(ProxyToCProxyMethod(model.mutable_child_model_1()));
1109 }
1110 
TEST(CppGeneratedCode,PtrImplicitConversion)1111 TEST(CppGeneratedCode, PtrImplicitConversion) {
1112   TestModel model;
1113   model.set_int64(5);
1114   ::hpb::Ptr<TestModel> model_ptr = &model;
1115   EXPECT_EQ(model_ptr->int64(), 5);
1116 }
1117 
TEST(CppGeneratedCode,ClearSubMessage)1118 TEST(CppGeneratedCode, ClearSubMessage) {
1119   // Fill model.
1120   TestModel model;
1121   model.set_int64(5);
1122   auto new_child = model.mutable_child_model_1();
1123   new_child->set_child_str1("text in child");
1124   ThemeExtension extension1;
1125   extension1.set_ext_name("name in extension");
1126   EXPECT_TRUE(::hpb::SetExtension(&model, theme, extension1).ok());
1127   EXPECT_TRUE(model.mutable_child_model_1()->has_child_str1());
1128   // Clear using Ptr<T>
1129   ::hpb::ClearMessage(model.mutable_child_model_1());
1130   EXPECT_FALSE(model.mutable_child_model_1()->has_child_str1());
1131 }
1132 
TEST(CppGeneratedCode,ClearMessage)1133 TEST(CppGeneratedCode, ClearMessage) {
1134   // Fill model.
1135   TestModel model;
1136   model.set_int64(5);
1137   model.set_str2("Hello");
1138   auto new_child = model.add_child_models();
1139   ASSERT_TRUE(new_child.ok());
1140   new_child.value()->set_child_str1("text in child");
1141   ThemeExtension extension1;
1142   extension1.set_ext_name("name in extension");
1143   EXPECT_TRUE(::hpb::SetExtension(&model, theme, extension1).ok());
1144   // Clear using T*
1145   ::hpb::ClearMessage(&model);
1146   // Verify that scalars, repeated fields and extensions are cleared.
1147   EXPECT_FALSE(model.has_int64());
1148   EXPECT_FALSE(model.has_str2());
1149   EXPECT_TRUE(model.child_models().empty());
1150   EXPECT_FALSE(::hpb::HasExtension(&model, theme));
1151 }
1152 
TEST(CppGeneratedCode,CanInvokeClearMessageWithPtr)1153 TEST(CppGeneratedCode, CanInvokeClearMessageWithPtr) {
1154   // Fill model.
1155   TestModel model;
1156   model.set_int64(5);
1157   auto new_child = model.add_child_models();
1158   // Clear using Ptr<T>
1159   auto ptr = ::hpb::Ptr<TestModel>(&model);
1160   ::hpb::ClearMessage(ptr);
1161   // Successful clear
1162   EXPECT_FALSE(model.has_int64());
1163 }
1164 
TEST(CppGeneratedCode,CanInvokeClearMessageWithRawPtr)1165 TEST(CppGeneratedCode, CanInvokeClearMessageWithRawPtr) {
1166   // Fill model.
1167   TestModel model;
1168   model.set_int64(5);
1169   auto new_child = model.add_child_models();
1170   // Clear using T*
1171   ::hpb::ClearMessage(&model);
1172   // Successful clear
1173   EXPECT_FALSE(model.has_int64());
1174 }
1175 
1176 template <typename T>
CanCallClearMessage()1177 bool CanCallClearMessage() {
1178   return Requires<T>([](auto x) -> decltype(::hpb::ClearMessage(x)) {});
1179 }
1180 
TEST(CppGeneratedCode,CannotInvokeClearMessageWithConstPtr)1181 TEST(CppGeneratedCode, CannotInvokeClearMessageWithConstPtr) {
1182   EXPECT_TRUE(CanCallClearMessage<::hpb::Ptr<TestModel>>());
1183   EXPECT_FALSE(CanCallClearMessage<::hpb::Ptr<const TestModel>>());
1184 }
1185 
TEST(CppGeneratedCode,CannotInvokeClearMessageWithConstRawPtr)1186 TEST(CppGeneratedCode, CannotInvokeClearMessageWithConstRawPtr) {
1187   EXPECT_TRUE(CanCallClearMessage<TestModel*>());
1188   EXPECT_FALSE(CanCallClearMessage<const TestModel*>());
1189 }
1190 
TEST(CppGeneratedCode,DeepCopy)1191 TEST(CppGeneratedCode, DeepCopy) {
1192   // Fill model.
1193   TestModel model;
1194   model.set_int64(5);
1195   model.set_str2("Hello");
1196   auto new_child = model.add_child_models();
1197   ASSERT_TRUE(new_child.ok());
1198   new_child.value()->set_child_str1("text in child");
1199   ThemeExtension extension1;
1200   extension1.set_ext_name("name in extension");
1201   EXPECT_TRUE(::hpb::SetExtension(&model, theme, extension1).ok());
1202   TestModel target;
1203   target.set_b1(true);
1204   ::hpb::DeepCopy(&model, &target);
1205   EXPECT_FALSE(target.b1()) << "Target was not cleared before copying content ";
1206   EXPECT_EQ(target.str2(), "Hello");
1207   EXPECT_TRUE(::hpb::HasExtension(&target, theme));
1208 }
1209 
TEST(CppGeneratedCode,HasExtensionAndRegistry)1210 TEST(CppGeneratedCode, HasExtensionAndRegistry) {
1211   // Fill model.
1212   TestModel source;
1213   source.set_int64(5);
1214   source.set_str2("Hello");
1215   auto new_child = source.add_child_models();
1216   ASSERT_TRUE(new_child.ok());
1217   new_child.value()->set_child_str1("text in child");
1218   ThemeExtension extension1;
1219   extension1.set_ext_name("name in extension");
1220   ASSERT_TRUE(::hpb::SetExtension(&source, theme, extension1).ok());
1221 
1222   // Now that we have a source model with extension data, serialize.
1223   ::hpb::Arena arena;
1224   std::string data = std::string(::hpb::Serialize(&source, arena).value());
1225 
1226   // Test with ExtensionRegistry
1227   ::hpb::ExtensionRegistry extensions({&theme}, arena);
1228   TestModel parsed_model = ::hpb::Parse<TestModel>(data, extensions).value();
1229   EXPECT_TRUE(::hpb::HasExtension(&parsed_model, theme));
1230 }
1231 
TEST(CppGeneratedCode,FieldNumberConstants)1232 TEST(CppGeneratedCode, FieldNumberConstants) {
1233   static_assert(TestModel::kChildMapFieldNumber == 225);
1234   EXPECT_EQ(225, TestModel::kChildMapFieldNumber);
1235 }
1236 
TEST(CppGeneratedCode,ExtensionFieldNumberConstant)1237 TEST(CppGeneratedCode, ExtensionFieldNumberConstant) {
1238   EXPECT_EQ(12003, ::hpb::ExtensionNumber(ThemeExtension::theme_extension));
1239 }
1240 
TEST(CppGeneratedCode,ClearConstMessageShouldFailForConstChild)1241 TEST(CppGeneratedCode, ClearConstMessageShouldFailForConstChild) {
1242   TestModel model;
1243   EXPECT_FALSE(CanCallClearMessage<decltype(model.child_model_1())>());
1244   EXPECT_TRUE(CanCallClearMessage<decltype(model.mutable_child_model_1())>());
1245 }
1246 
1247 }  // namespace
1248