1 // Copyright (c) 2009-2021, Google LLC
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are met:
6 //     * Redistributions of source code must retain the above copyright
7 //       notice, this list of conditions and the following disclaimer.
8 //     * Redistributions in binary form must reproduce the above copyright
9 //       notice, this list of conditions and the following disclaimer in the
10 //       documentation and/or other materials provided with the distribution.
11 //     * Neither the name of Google LLC nor the
12 //       names of its contributors may be used to endorse or promote products
13 //       derived from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 // ARE DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY DIRECT,
19 // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 // ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 
26 #include <limits>
27 #include <memory>
28 #include <utility>
29 
30 #include "gtest/gtest.h"
31 #include "protos/protos.h"
32 #include "protos_generator/tests/child_model.upb.proto.h"
33 #include "protos_generator/tests/no_package.upb.proto.h"
34 #include "protos_generator/tests/test_model.upb.proto.h"
35 
36 using ::protos_generator::test::protos::ChildModel1;
37 using ::protos_generator::test::protos::other_ext;
38 using ::protos_generator::test::protos::RED;
39 using ::protos_generator::test::protos::TestEnum;
40 using ::protos_generator::test::protos::TestModel;
41 using ::protos_generator::test::protos::TestModel_Category;
42 using ::protos_generator::test::protos::TestModel_Category_IMAGES;
43 using ::protos_generator::test::protos::TestModel_Category_NEWS;
44 using ::protos_generator::test::protos::TestModel_Category_VIDEO;
45 using ::protos_generator::test::protos::theme;
46 using ::protos_generator::test::protos::ThemeExtension;
47 
TEST(CppGeneratedCode,Constructor)48 TEST(CppGeneratedCode, Constructor) { TestModel test_model; }
49 
TEST(CppGeneratedCode,MessageEnum)50 TEST(CppGeneratedCode, MessageEnum) { EXPECT_EQ(5, TestModel_Category_IMAGES); }
51 
TEST(CppGeneratedCode,ImportedEnum)52 TEST(CppGeneratedCode, ImportedEnum) { EXPECT_EQ(3, TestEnum::DEVICE_MONITOR); }
53 
TEST(CppGeneratedCode,Enum)54 TEST(CppGeneratedCode, Enum) { EXPECT_EQ(1, RED); }
55 
TEST(CppGeneratedCode,EnumNoPackage)56 TEST(CppGeneratedCode, EnumNoPackage) { EXPECT_EQ(1, ::protos_CELSIUS); }
57 
TEST(CppGeneratedCode,MessageEnumType)58 TEST(CppGeneratedCode, MessageEnumType) {
59   TestModel_Category category1 = TestModel_Category_IMAGES;
60   TestModel::Category category2 = TestModel::IMAGES;
61   EXPECT_EQ(category1, category2);
62 }
63 
TEST(CppGeneratedCode,MessageEnumValue)64 TEST(CppGeneratedCode, MessageEnumValue) {
65   EXPECT_EQ(TestModel_Category_IMAGES, TestModel::IMAGES);
66 }
67 
TEST(CppGeneratedCode,ArenaConstructor)68 TEST(CppGeneratedCode, ArenaConstructor) {
69   ::protos::Arena arena;
70   auto testModel = ::protos::CreateMessage<TestModel>(arena);
71   EXPECT_EQ(false, testModel.has_b1());
72 }
73 
TEST(CppGeneratedCode,Booleans)74 TEST(CppGeneratedCode, Booleans) {
75   ::protos::Arena arena;
76   auto testModel = ::protos::CreateMessage<TestModel>(arena);
77   EXPECT_FALSE(testModel.b1());
78   testModel.set_b1(true);
79   EXPECT_TRUE(testModel.b1());
80   testModel.set_b1(false);
81   EXPECT_FALSE(testModel.b1());
82   testModel.set_b1(true);
83   EXPECT_TRUE(testModel.b1());
84   testModel.clear_b1();
85   EXPECT_FALSE(testModel.has_b1());
86 }
87 
TEST(CppGeneratedCode,ScalarInt32)88 TEST(CppGeneratedCode, ScalarInt32) {
89   ::protos::Arena arena;
90   auto testModel = ::protos::CreateMessage<TestModel>(arena);
91   // Test int32 defaults.
92   EXPECT_EQ(testModel.value(), 0);
93   EXPECT_FALSE(testModel.has_value());
94   // Floating point defautls.
95   EXPECT_EQ(std::numeric_limits<float>::infinity(),
96             testModel.float_value_with_default());
97   EXPECT_EQ(-std::numeric_limits<double>::infinity(),
98             testModel.double_value_with_default());
99 
100   // Set value.
101   testModel.set_value(5);
102   EXPECT_TRUE(testModel.has_value());
103   EXPECT_EQ(testModel.value(), 5);
104   // Change value.
105   testModel.set_value(10);
106   EXPECT_TRUE(testModel.has_value());
107   EXPECT_EQ(testModel.value(), 10);
108   // Clear value.
109   testModel.clear_value();
110   EXPECT_FALSE(testModel.has_value());
111   EXPECT_EQ(testModel.value(), 0);
112 }
113 
114 const char kTestStr1[] = "abcdefg";
115 const char kTestStr2[] = "just another test string";
116 
TEST(CppGeneratedCode,Strings)117 TEST(CppGeneratedCode, Strings) {
118   TestModel testModel;
119   testModel.set_str1(kTestStr1);
120   testModel.set_str2(kTestStr2);
121   EXPECT_EQ(testModel.str1(), kTestStr1);
122   EXPECT_EQ(testModel.str2(), kTestStr2);
123   EXPECT_TRUE(testModel.has_str1());
124   EXPECT_TRUE(testModel.has_str2());
125 
126   testModel.clear_str1();
127   EXPECT_FALSE(testModel.has_str1());
128   EXPECT_TRUE(testModel.has_str2());
129 }
130 
TEST(CppGeneratedCode,ScalarUInt32)131 TEST(CppGeneratedCode, ScalarUInt32) {
132   ::protos::Arena arena;
133   auto testModel = ::protos::CreateMessage<TestModel>(arena);
134   // Test defaults.
135   EXPECT_EQ(testModel.optional_uint32(), 0);
136   EXPECT_FALSE(testModel.has_optional_uint32());
137   // Set value.
138   testModel.set_optional_uint32(0xA0001000);
139   EXPECT_TRUE(testModel.has_optional_uint32());
140   EXPECT_EQ(testModel.optional_uint32(), 0xA0001000);
141   // Change value.
142   testModel.set_optional_uint32(0x70002000);
143   EXPECT_TRUE(testModel.has_optional_uint32());
144   EXPECT_EQ(testModel.optional_uint32(), 0x70002000);
145   // Clear value.
146   testModel.clear_optional_uint32();
147   EXPECT_FALSE(testModel.has_optional_uint32());
148   EXPECT_EQ(testModel.optional_uint32(), 0);
149 }
150 
TEST(CppGeneratedCode,ScalarInt64)151 TEST(CppGeneratedCode, ScalarInt64) {
152   ::protos::Arena arena;
153   auto testModel = ::protos::CreateMessage<TestModel>(arena);
154   // Test defaults.
155   EXPECT_EQ(testModel.optional_int64(), 0);
156   EXPECT_FALSE(testModel.has_optional_int64());
157   // Set value.
158   testModel.set_optional_int64(0xFF00CCDDA0001000);
159   EXPECT_TRUE(testModel.has_optional_int64());
160   EXPECT_EQ(testModel.optional_int64(), 0xFF00CCDDA0001000);
161   // Change value.
162   testModel.set_optional_int64(0xFF00CCDD70002000);
163   EXPECT_TRUE(testModel.has_optional_int64());
164   EXPECT_EQ(testModel.optional_int64(), 0xFF00CCDD70002000);
165   // Clear value.
166   testModel.clear_optional_int64();
167   EXPECT_FALSE(testModel.has_optional_int64());
168   EXPECT_EQ(testModel.optional_int64(), 0);
169   // Set after clear.
170   testModel.set_optional_int64(0xFF00CCDDA0001000);
171   EXPECT_TRUE(testModel.has_optional_int64());
172   EXPECT_EQ(testModel.optional_int64(), 0xFF00CCDDA0001000);
173 }
174 
TEST(CppGeneratedCode,ScalarFloat)175 TEST(CppGeneratedCode, ScalarFloat) {
176   ::protos::Arena arena;
177   auto testModel = ::protos::CreateMessage<TestModel>(arena);
178   // Test defaults.
179   EXPECT_EQ(testModel.optional_float(), 0.0f);
180   EXPECT_FALSE(testModel.has_optional_float());
181   EXPECT_EQ(std::numeric_limits<float>::infinity(),
182             testModel.float_value_with_default());
183   EXPECT_EQ(-std::numeric_limits<double>::infinity(),
184             testModel.double_value_with_default());
185   // Set value.
186   testModel.set_optional_float(3.14159265f);
187   EXPECT_TRUE(testModel.has_optional_float());
188   EXPECT_NEAR(testModel.optional_float(), 3.14159265f, 1e-9f);
189   // Change value.
190   testModel.set_optional_float(-2.0f);
191   EXPECT_TRUE(testModel.has_optional_float());
192   EXPECT_NEAR(testModel.optional_float(), -2, 1e-9f);
193   // Clear value.
194   testModel.clear_optional_float();
195   EXPECT_FALSE(testModel.has_optional_float());
196   EXPECT_EQ(testModel.optional_float(), 0.0f);
197   // Set after clear.
198   testModel.set_optional_float(3.14159265f);
199   EXPECT_TRUE(testModel.has_optional_float());
200   EXPECT_NEAR(testModel.optional_float(), 3.14159265f, 1e-9f);
201 }
202 
TEST(CppGeneratedCode,ScalarDouble)203 TEST(CppGeneratedCode, ScalarDouble) {
204   ::protos::Arena arena;
205   auto testModel = ::protos::CreateMessage<TestModel>(arena);
206   // Test defaults.
207   EXPECT_EQ(testModel.optional_double(), 0.0);
208   EXPECT_FALSE(testModel.has_optional_double());
209   // Set value.
210   testModel.set_optional_double(3.141592653589793);
211   EXPECT_TRUE(testModel.has_optional_double());
212   EXPECT_NEAR(testModel.optional_double(), 3.141592653589793, 1e-16f);
213   // Change value.
214   testModel.set_optional_double(-1.0);
215   EXPECT_TRUE(testModel.has_optional_double());
216   EXPECT_NEAR(testModel.optional_double(), -1.0, 1e-16f);
217   // Clear value.
218   testModel.clear_optional_double();
219   EXPECT_FALSE(testModel.has_optional_double());
220   EXPECT_EQ(testModel.optional_double(), 0.0f);
221   // Set after clear.
222   testModel.set_optional_double(3.141592653589793);
223   EXPECT_TRUE(testModel.has_optional_double());
224   EXPECT_NEAR(testModel.optional_double(), 3.141592653589793, 1e-16f);
225 }
226 
TEST(CppGeneratedCode,Enums)227 TEST(CppGeneratedCode, Enums) {
228   ::protos::Arena arena;
229   auto testModel = ::protos::CreateMessage<TestModel>(arena);
230 
231   // Check enum default value.
232   EXPECT_EQ(TestModel_Category_IMAGES, 5);
233 
234   // Test defaults.
235   EXPECT_FALSE(testModel.has_category());
236   EXPECT_EQ(testModel.category(), TestModel_Category_IMAGES);
237   // Set value.
238   testModel.set_category(TestModel_Category_NEWS);
239   EXPECT_TRUE(testModel.has_category());
240   EXPECT_EQ(testModel.category(), TestModel_Category_NEWS);
241   // Change value.
242   testModel.set_category(TestModel_Category_VIDEO);
243   EXPECT_TRUE(testModel.has_category());
244   EXPECT_EQ(testModel.category(), TestModel_Category_VIDEO);
245   // Clear value.
246   testModel.clear_category();
247   EXPECT_FALSE(testModel.has_category());
248   EXPECT_EQ(testModel.category(), TestModel_Category_IMAGES);
249   // Set after clear.
250   testModel.set_category(TestModel_Category_VIDEO);
251   EXPECT_TRUE(testModel.has_category());
252   EXPECT_EQ(testModel.category(), TestModel_Category_VIDEO);
253 }
254 
TEST(CppGeneratedCode,FieldWithDefaultValue)255 TEST(CppGeneratedCode, FieldWithDefaultValue) {
256   ::protos::Arena arena;
257   auto testModel = ::protos::CreateMessage<TestModel>(arena);
258 
259   EXPECT_FALSE(testModel.has_int_value_with_default());
260   EXPECT_EQ(testModel.int_value_with_default(), 65);
261   testModel.set_int_value_with_default(10);
262   EXPECT_EQ(testModel.int_value_with_default(), 10);
263 
264   EXPECT_FALSE(testModel.has_string_value_with_default());
265   EXPECT_EQ(testModel.string_value_with_default(), "hello");
266   testModel.set_string_value_with_default("new string");
267   EXPECT_EQ(testModel.string_value_with_default(), "new string");
268 }
269 
TEST(CppGeneratedCode,OneOfFields)270 TEST(CppGeneratedCode, OneOfFields) {
271   ::protos::Arena arena;
272   auto test_model = ::protos::CreateMessage<TestModel>(arena);
273 
274   EXPECT_FALSE(test_model.has_oneof_member1());
275   EXPECT_FALSE(test_model.has_oneof_member2());
276   EXPECT_EQ(TestModel::CHILD_ONEOF1_NOT_SET, test_model.child_oneof1_case());
277 
278   test_model.set_oneof_member1("one of string");
279   EXPECT_TRUE(test_model.has_oneof_member1());
280   EXPECT_FALSE(test_model.has_oneof_member2());
281   EXPECT_EQ(test_model.oneof_member1(), "one of string");
282   EXPECT_EQ(TestModel::kOneofMember1, test_model.child_oneof1_case());
283 
284   test_model.set_oneof_member2(true);
285   EXPECT_FALSE(test_model.has_oneof_member1());
286   EXPECT_TRUE(test_model.has_oneof_member2());
287   EXPECT_EQ(test_model.oneof_member2(), true);
288   EXPECT_EQ(TestModel::kOneofMember2, test_model.child_oneof1_case());
289 
290   test_model.clear_oneof_member2();
291   EXPECT_FALSE(test_model.has_oneof_member1());
292   EXPECT_FALSE(test_model.has_oneof_member2());
293   EXPECT_EQ(test_model.oneof_member1(), "");
294   EXPECT_EQ(test_model.oneof_member2(), false);
295   EXPECT_EQ(TestModel::CHILD_ONEOF1_NOT_SET, test_model.child_oneof1_case());
296 }
297 
TEST(CppGeneratedCode,Messages)298 TEST(CppGeneratedCode, Messages) {
299   ::protos::Arena arena;
300   auto test_model = ::protos::CreateMessage<TestModel>(arena);
301   EXPECT_EQ(false, test_model.has_child_model_1());
302   auto child_model = test_model.child_model_1();
303   EXPECT_EQ(false, child_model->has_child_b1());
304   EXPECT_EQ(false, child_model->child_b1());
305   auto mutable_child = test_model.mutable_child_model_1();
306   mutable_child->set_child_b1(true);
307   EXPECT_EQ(true, mutable_child->has_child_b1());
308   EXPECT_EQ(true, mutable_child->child_b1());
309   // The View should not change due to mutation since it
310   // is default_instance.
311   EXPECT_EQ(false, child_model->has_child_b1());
312   // Readonly View should now show change.
313   child_model = test_model.child_model_1();
314   EXPECT_EQ(true, child_model->has_child_b1());
315   EXPECT_EQ(true, child_model->child_b1());
316   // Clear message field.
317   EXPECT_EQ(true, test_model.has_child_model_1());
318   test_model.clear_child_model_1();
319   EXPECT_EQ(false, test_model.has_child_model_1());
320 }
321 
TEST(CppGeneratedCode,NestedMessages)322 TEST(CppGeneratedCode, NestedMessages) {
323   ::protos::Arena arena;
324   auto test_model = ::protos::CreateMessage<TestModel>(arena);
325   auto nested_child = test_model.nested_child_1();
326   EXPECT_EQ(0, nested_child->nested_child_name().size());
327   auto mutable_nested_child = test_model.mutable_nested_child_1();
328   EXPECT_EQ(false, mutable_nested_child->has_nested_child_name());
329   mutable_nested_child->set_nested_child_name(kTestStr1);
330   EXPECT_EQ(true, mutable_nested_child->has_nested_child_name());
331 }
332 
TEST(CppGeneratedCode,RepeatedMessages)333 TEST(CppGeneratedCode, RepeatedMessages) {
334   ::protos::Arena arena;
335   auto test_model = ::protos::CreateMessage<TestModel>(arena);
336   EXPECT_EQ(0, test_model.child_model_2_size());
337   // Should be able to clear repeated field when empty.
338   test_model.clear_child_model_2();
339   EXPECT_EQ(0, test_model.child_model_2_size());
340   // Add 2 children.
341   auto new_child = test_model.add_child_model_2();
342   EXPECT_EQ(true, new_child.ok());
343   new_child.value()->set_child_str1(kTestStr1);
344   new_child = test_model.add_child_model_2();
345   EXPECT_EQ(true, new_child.ok());
346   new_child.value()->set_child_str1(kTestStr2);
347   EXPECT_EQ(2, test_model.child_model_2_size());
348   // Mutable access.
349   auto mutable_first = test_model.mutable_child_model_2(0);
350   EXPECT_EQ(mutable_first->child_str1(), kTestStr1);
351   mutable_first->set_child_str1("change1");
352   auto mutable_second = test_model.mutable_child_model_2(1);
353   EXPECT_EQ(mutable_second->child_str1(), kTestStr2);
354   mutable_second->set_child_str1("change2");
355   // Check mutations using views.
356   auto view_first = test_model.child_model_2(0);
357   EXPECT_EQ(view_first->child_str1(), "change1");
358   auto view_second = test_model.child_model_2(1);
359   EXPECT_EQ(view_second->child_str1(), "change2");
360 }
361 
TEST(CppGeneratedCode,RepeatedScalar)362 TEST(CppGeneratedCode, RepeatedScalar) {
363   ::protos::Arena arena;
364   auto test_model = ::protos::CreateMessage<TestModel>(arena);
365   EXPECT_EQ(0, test_model.value_array_size());
366   // Should be able to clear repeated field when empty.
367   test_model.clear_value_array();
368   EXPECT_EQ(0, test_model.value_array_size());
369   // Add 2 children.
370   EXPECT_EQ(true, test_model.add_value_array(5));
371   EXPECT_EQ(true, test_model.add_value_array(6));
372   EXPECT_EQ(2, test_model.value_array_size());
373   EXPECT_EQ(5, test_model.value_array(0));
374   EXPECT_EQ(6, test_model.value_array(1));
375   EXPECT_EQ(true, test_model.resize_value_array(3));
376   EXPECT_EQ(3, test_model.value_array_size());
377   test_model.set_value_array(2, 7);
378   EXPECT_EQ(5, test_model.value_array(0));
379   EXPECT_EQ(6, test_model.value_array(1));
380   EXPECT_EQ(7, test_model.value_array(2));
381 }
382 
TEST(CppGeneratedCode,RepeatedStrings)383 TEST(CppGeneratedCode, RepeatedStrings) {
384   ::protos::Arena arena;
385   auto test_model = ::protos::CreateMessage<TestModel>(arena);
386   EXPECT_EQ(0, test_model.repeated_string_size());
387   // Should be able to clear repeated field when empty.
388   test_model.clear_repeated_string();
389   EXPECT_EQ(0, test_model.repeated_string_size());
390   // Add 2 children.
391   EXPECT_EQ(true, test_model.add_repeated_string("Hello"));
392   EXPECT_EQ(true, test_model.add_repeated_string("World"));
393   EXPECT_EQ(2, test_model.repeated_string_size());
394   EXPECT_EQ("Hello", test_model.repeated_string(0));
395   EXPECT_EQ("World", test_model.repeated_string(1));
396   EXPECT_EQ(true, test_model.resize_repeated_string(3));
397   EXPECT_EQ(3, test_model.repeated_string_size());
398   test_model.set_repeated_string(2, "Test");
399   EXPECT_EQ("Hello", test_model.repeated_string(0));
400   EXPECT_EQ("World", test_model.repeated_string(1));
401   EXPECT_EQ("Test", test_model.repeated_string(2));
402 }
403 
TEST(CppGeneratedCode,MessageMapInt32KeyMessageValue)404 TEST(CppGeneratedCode, MessageMapInt32KeyMessageValue) {
405   const int key_test_value = 3;
406   ::protos::Arena arena;
407   ::protos::Arena child_arena;
408   auto test_model = ::protos::CreateMessage<TestModel>(arena);
409   EXPECT_EQ(0, test_model.child_map_size());
410   test_model.clear_child_map();
411   EXPECT_EQ(0, test_model.child_map_size());
412   auto child_model1 = ::protos::CreateMessage<ChildModel1>(child_arena);
413   child_model1.set_child_str1("abc");
414   test_model.set_child_map(key_test_value, child_model1);
415   auto map_result = test_model.get_child_map(key_test_value);
416   EXPECT_EQ(true, map_result.ok());
417   EXPECT_EQ("abc", map_result.value()->child_str1());
418   // Now mutate original child model to verify that value semantics are
419   // preserved.
420   child_model1.set_child_str1("abc V2");
421   EXPECT_EQ("abc", map_result.value()->child_str1());
422   test_model.delete_child_map(key_test_value);
423   auto map_result_after_delete = test_model.get_child_map(key_test_value);
424   EXPECT_EQ(false, map_result_after_delete.ok());
425 }
426 
TEST(CppGeneratedCode,MessageMapStringKeyAndStringValue)427 TEST(CppGeneratedCode, MessageMapStringKeyAndStringValue) {
428   ::protos::Arena arena;
429   auto test_model = ::protos::CreateMessage<TestModel>(arena);
430   EXPECT_EQ(0, test_model.str_to_str_map_size());
431   test_model.clear_str_to_str_map();
432   EXPECT_EQ(0, test_model.str_to_str_map_size());
433   test_model.set_str_to_str_map("first", "abc");
434   test_model.set_str_to_str_map("second", "def");
435   auto result = test_model.get_str_to_str_map("second");
436   EXPECT_EQ(true, result.ok());
437   EXPECT_EQ("def", result.value());
438   test_model.delete_str_to_str_map("first");
439   auto result_after_delete = test_model.get_str_to_str_map("first");
440   EXPECT_EQ(false, result_after_delete.ok());
441 }
442 
TEST(CppGeneratedCode,MessageMapStringKeyAndInt32Value)443 TEST(CppGeneratedCode, MessageMapStringKeyAndInt32Value) {
444   ::protos::Arena arena;
445   auto test_model = ::protos::CreateMessage<TestModel>(arena);
446   EXPECT_EQ(0, test_model.str_to_int_map_size());
447   test_model.clear_str_to_int_map();
448   EXPECT_EQ(0, test_model.str_to_int_map_size());
449   test_model.set_str_to_int_map("first", 10);
450   EXPECT_EQ(1, test_model.str_to_int_map_size());
451   test_model.set_str_to_int_map("second", 20);
452   EXPECT_EQ(2, test_model.str_to_int_map_size());
453   auto result = test_model.get_str_to_int_map("second");
454   EXPECT_EQ(true, result.ok());
455   EXPECT_EQ(20, result.value());
456   test_model.delete_str_to_int_map("first");
457   auto result_after_delete = test_model.get_str_to_int_map("first");
458   EXPECT_EQ(false, result_after_delete.ok());
459 }
460 
TEST(CppGeneratedCode,HasExtension)461 TEST(CppGeneratedCode, HasExtension) {
462   TestModel model;
463   EXPECT_EQ(false, ::protos::HasExtension(model, theme));
464 }
465 
TEST(CppGeneratedCode,HasExtensionPtr)466 TEST(CppGeneratedCode, HasExtensionPtr) {
467   TestModel model;
468   EXPECT_EQ(false, ::protos::HasExtension(model.recursive_child(), theme));
469 }
470 
TEST(CppGeneratedCode,ClearExtensionWithEmptyExtension)471 TEST(CppGeneratedCode, ClearExtensionWithEmptyExtension) {
472   TestModel model;
473   EXPECT_EQ(false, ::protos::HasExtension(model, theme));
474   ::protos::ClearExtension(model, theme);
475   EXPECT_EQ(false, ::protos::HasExtension(model, theme));
476 }
477 
TEST(CppGeneratedCode,ClearExtensionWithEmptyExtensionPtr)478 TEST(CppGeneratedCode, ClearExtensionWithEmptyExtensionPtr) {
479   TestModel model;
480   ::protos::Ptr<TestModel> recursive_child = model.mutable_recursive_child();
481   ::protos::ClearExtension(recursive_child, theme);
482   EXPECT_EQ(false, ::protos::HasExtension(recursive_child, theme));
483 }
484 
TEST(CppGeneratedCode,SetExtension)485 TEST(CppGeneratedCode, SetExtension) {
486   TestModel model;
487   ThemeExtension extension1;
488   extension1.set_ext_name("Hello World");
489   EXPECT_EQ(false, ::protos::HasExtension(model, theme));
490   EXPECT_EQ(true, ::protos::SetExtension(model, theme, extension1).ok());
491   EXPECT_EQ(true, ::protos::HasExtension(model, theme));
492 }
493 
TEST(CppGeneratedCode,SetExtensionOnMutableChild)494 TEST(CppGeneratedCode, SetExtensionOnMutableChild) {
495   TestModel model;
496   ThemeExtension extension1;
497   extension1.set_ext_name("Hello World");
498   EXPECT_EQ(false,
499             ::protos::HasExtension(model.mutable_recursive_child(), theme));
500   EXPECT_EQ(true, ::protos::SetExtension(model.mutable_recursive_child(), theme,
501                                          extension1)
502                       .ok());
503   EXPECT_EQ(true,
504             ::protos::HasExtension(model.mutable_recursive_child(), theme));
505 }
506 
TEST(CppGeneratedCode,GetExtension)507 TEST(CppGeneratedCode, GetExtension) {
508   TestModel model;
509   ThemeExtension extension1;
510   extension1.set_ext_name("Hello World");
511   EXPECT_EQ(false, ::protos::HasExtension(model, theme));
512   EXPECT_EQ(true, ::protos::SetExtension(model, theme, extension1).ok());
513   EXPECT_EQ("Hello World",
514             ::protos::GetExtension(model, theme).value()->ext_name());
515 }
516 
TEST(CppGeneratedCode,GetExtensionOnMutableChild)517 TEST(CppGeneratedCode, GetExtensionOnMutableChild) {
518   TestModel model;
519   ThemeExtension extension1;
520   extension1.set_ext_name("Hello World");
521   ::protos::Ptr<TestModel> mutable_recursive_child =
522       model.mutable_recursive_child();
523   EXPECT_EQ(false, ::protos::HasExtension(mutable_recursive_child, theme));
524   EXPECT_EQ(
525       true,
526       ::protos::SetExtension(mutable_recursive_child, theme, extension1).ok());
527   EXPECT_EQ("Hello World",
528             ::protos::GetExtension(mutable_recursive_child, theme)
529                 .value()
530                 ->ext_name());
531 }
532 
TEST(CppGeneratedCode,GetExtensionOnImmutableChild)533 TEST(CppGeneratedCode, GetExtensionOnImmutableChild) {
534   TestModel model;
535   ThemeExtension extension1;
536   extension1.set_ext_name("Hello World");
537   ::protos::Ptr<TestModel> mutable_recursive_child =
538       model.mutable_recursive_child();
539   EXPECT_EQ(false, ::protos::HasExtension(mutable_recursive_child, theme));
540   EXPECT_EQ(
541       true,
542       ::protos::SetExtension(mutable_recursive_child, theme, extension1).ok());
543   ::protos::Ptr<const TestModel> recursive_child = model.recursive_child();
544   EXPECT_EQ("Hello World",
545             ::protos::GetExtension(recursive_child, theme).value()->ext_name());
546 }
547 
TEST(CppGeneratedCode,SerializeUsingArena)548 TEST(CppGeneratedCode, SerializeUsingArena) {
549   TestModel model;
550   model.set_str1("Hello World");
551   ::upb::Arena arena;
552   absl::StatusOr<absl::string_view> bytes = ::protos::Serialize(model, arena);
553   EXPECT_EQ(true, bytes.ok());
554   TestModel parsed_model = ::protos::Parse<TestModel>(bytes.value()).value();
555   EXPECT_EQ("Hello World", parsed_model.str1());
556 }
557 
TEST(CppGeneratedCode,SerializeNestedMessageUsingArena)558 TEST(CppGeneratedCode, SerializeNestedMessageUsingArena) {
559   TestModel model;
560   model.mutable_recursive_child()->set_str1("Hello World");
561   ::upb::Arena arena;
562   ::protos::Ptr<const TestModel> child = model.recursive_child();
563   absl::StatusOr<absl::string_view> bytes = ::protos::Serialize(child, arena);
564   EXPECT_EQ(true, bytes.ok());
565   TestModel parsed_model = ::protos::Parse<TestModel>(bytes.value()).value();
566   EXPECT_EQ("Hello World", parsed_model.str1());
567 }
568 
TEST(CppGeneratedCode,Parse)569 TEST(CppGeneratedCode, Parse) {
570   TestModel model;
571   model.set_str1("Test123");
572   ThemeExtension extension1;
573   extension1.set_ext_name("Hello World");
574   EXPECT_EQ(true, ::protos::SetExtension(model, theme, extension1).ok());
575   ::upb::Arena arena;
576   auto bytes = ::protos::Serialize(model, arena);
577   EXPECT_EQ(true, bytes.ok());
578   TestModel parsed_model = ::protos::Parse<TestModel>(bytes.value()).value();
579   EXPECT_EQ("Test123", parsed_model.str1());
580   // Should not return an extension since we did not pass ExtensionRegistry.
581   EXPECT_EQ(false, ::protos::GetExtension(parsed_model, theme).ok());
582 }
583 
TEST(CppGeneratedCode,ParseIntoPtrToModel)584 TEST(CppGeneratedCode, ParseIntoPtrToModel) {
585   TestModel model;
586   model.set_str1("Test123");
587   ThemeExtension extension1;
588   extension1.set_ext_name("Hello World");
589   EXPECT_EQ(true, ::protos::SetExtension(model, theme, extension1).ok());
590   ::upb::Arena arena;
591   auto bytes = ::protos::Serialize(model, arena);
592   EXPECT_EQ(true, bytes.ok());
593   ::protos::Ptr<TestModel> parsed_model =
594       ::protos::CreateMessage<TestModel>(arena);
595   EXPECT_TRUE(::protos::Parse(parsed_model, bytes.value()));
596   EXPECT_EQ("Test123", parsed_model->str1());
597   // Should not return an extension since we did not pass ExtensionRegistry.
598   EXPECT_EQ(false, ::protos::GetExtension(parsed_model, theme).ok());
599 }
600 
TEST(CppGeneratedCode,ParseWithExtensionRegistry)601 TEST(CppGeneratedCode, ParseWithExtensionRegistry) {
602   TestModel model;
603   model.set_str1("Test123");
604   ThemeExtension extension1;
605   extension1.set_ext_name("Hello World");
606   EXPECT_EQ(true, ::protos::SetExtension(model, theme, extension1).ok());
607   EXPECT_EQ(true, ::protos::SetExtension(model, ThemeExtension::theme_extension,
608                                          extension1)
609                       .ok());
610   ::upb::Arena arena;
611   auto bytes = ::protos::Serialize(model, arena);
612   EXPECT_EQ(true, bytes.ok());
613   ::protos::ExtensionRegistry extensions(
614       {&theme, &other_ext, &ThemeExtension::theme_extension}, arena);
615   TestModel parsed_model =
616       ::protos::Parse<TestModel>(bytes.value(), extensions).value();
617   EXPECT_EQ("Test123", parsed_model.str1());
618   EXPECT_EQ(true, ::protos::GetExtension(parsed_model, theme).ok());
619   EXPECT_EQ(true, ::protos::GetExtension(parsed_model,
620                                          ThemeExtension::theme_extension)
621                       .ok());
622   EXPECT_EQ("Hello World", ::protos::GetExtension(
623                                parsed_model, ThemeExtension::theme_extension)
624                                .value()
625                                ->ext_name());
626 }
627 
TEST(CppGeneratedCode,NameCollisions)628 TEST(CppGeneratedCode, NameCollisions) {
629   TestModel model;
630   model.set_template_("test");
631   EXPECT_EQ("test", model.template_());
632   model.set_arena__("test");
633   EXPECT_EQ("test", model.arena__());
634 }
635 
TEST(CppGeneratedCode,SharedPointer)636 TEST(CppGeneratedCode, SharedPointer) {
637   std::shared_ptr<TestModel> model = std::make_shared<TestModel>();
638   ::upb::Arena arena;
639   auto bytes = protos::Serialize(model, arena);
640   EXPECT_TRUE(protos::Parse(model, bytes.value()));
641 }
642 
TEST(CppGeneratedCode,UniquePointer)643 TEST(CppGeneratedCode, UniquePointer) {
644   auto model = std::make_unique<TestModel>();
645   ::upb::Arena arena;
646   auto bytes = protos::Serialize(model, arena);
647   EXPECT_TRUE(protos::Parse(model, bytes.value()));
648 }
649 
TEST(CppGeneratedCode,Assignment)650 TEST(CppGeneratedCode, Assignment) {
651   TestModel model;
652   model.set_category(5);
653   model.mutable_child_model_1()->set_child_str1("text in child");
654   TestModel model2 = model;
655   EXPECT_EQ(5, model2.category());
656   EXPECT_EQ(model2.child_model_1()->child_str1(), "text in child");
657 }
658 
TEST(CppGeneratedCode,PtrAssignment)659 TEST(CppGeneratedCode, PtrAssignment) {
660   TestModel model;
661   model.mutable_child_model_1()->set_child_str1("text in child");
662   ChildModel1 child_from_const_ptr = *model.child_model_1();
663   EXPECT_EQ(child_from_const_ptr.child_str1(), "text in child");
664   ChildModel1 child_from_ptr = *model.mutable_child_model_1();
665   EXPECT_EQ(child_from_ptr.child_str1(), "text in child");
666 }
667 
TEST(CppGeneratedCode,CopyConstructor)668 TEST(CppGeneratedCode, CopyConstructor) {
669   TestModel model;
670   model.set_category(6);
671   TestModel model2(model);
672   EXPECT_EQ(6, model2.category());
673 }
674 
TEST(CppGeneratedCode,PtrConstructor)675 TEST(CppGeneratedCode, PtrConstructor) {
676   TestModel model;
677   model.mutable_child_model_1()->set_child_str1("text in child");
678   ChildModel1 child_from_ptr(*model.mutable_child_model_1());
679   EXPECT_EQ(child_from_ptr.child_str1(), "text in child");
680   ChildModel1 child_from_const_ptr(*model.child_model_1());
681   EXPECT_EQ(child_from_const_ptr.child_str1(), "text in child");
682 }
683 
TEST(CppGeneratedCode,MutableToProxy)684 TEST(CppGeneratedCode, MutableToProxy) {
685   TestModel model;
686   ::protos::Ptr<ChildModel1> child = model.mutable_child_model_1();
687   (void)child;
688 }
689 
TEST(CppGeneratedCode,ProxyToCProxy)690 TEST(CppGeneratedCode, ProxyToCProxy) {
691   TestModel model;
692   ::protos::Ptr<ChildModel1> child = model.mutable_child_model_1();
693   ::protos::Ptr<const ChildModel1> child2 = child;
694   (void)child2;
695 }
696 
ProxyToCProxyMethod(::protos::Ptr<const ChildModel1> child)697 bool ProxyToCProxyMethod(::protos::Ptr<const ChildModel1> child) {
698   return child->child_str1() == "text in child";
699 }
700 
TEST(CppGeneratedCode,PassProxyToCProxy)701 TEST(CppGeneratedCode, PassProxyToCProxy) {
702   TestModel model;
703   model.mutable_child_model_1()->set_child_str1("text in child");
704   EXPECT_TRUE(ProxyToCProxyMethod(model.mutable_child_model_1()));
705 }
706