• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc.  All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 //     * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 //     * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 //     * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 #include <google/protobuf/unittest.pb.h>
32 #include <gmock/gmock.h>
33 #include <gtest/gtest.h>
34 #include <google/protobuf/descriptor.h>
35 
36 namespace google {
37 namespace protobuf {
38 namespace compiler {
39 namespace cpp {
40 
41 // Can't use an anonymous namespace here due to brokenness of Tru64 compiler.
42 namespace cpp_unittest {
43 
44 
45 #if !defined(GOOGLE_CHECK_MESSAGE_SIZE)
46 #define GOOGLE_CHECK_MESSAGE_SIZE(t, expected)
47 #endif
48 
49 // Mock structures to lock down the size of messages in a platform-independent
50 // way.  The commented sizes only apply when build with clang x86_64.
51 struct MockMessageBase {
52   virtual ~MockMessageBase() = default;  // 8 bytes vtable
53   void* internal_metadata;               // 8 bytes
54 };
55 GOOGLE_CHECK_MESSAGE_SIZE(MockMessageBase, 16);
56 
57 struct MockZeroFieldsBase : public MockMessageBase {
58   int cached_size;  // 4 bytes
59   // + 4 bytes padding
60 };
61 GOOGLE_CHECK_MESSAGE_SIZE(MockZeroFieldsBase, 24);
62 
63 struct MockExtensionSet {
64   void* arena;       // 8 bytes
65   int16_t capacity;  // 4 bytes
66   int16_t size;      // 4 bytes
67   void* data;        // 8 bytes
68 };
69 GOOGLE_CHECK_MESSAGE_SIZE(MockExtensionSet, 24);
70 
71 struct MockRepeatedPtrField {
72   void* arena;       // 8 bytes
73   int current_size;  // 4 bytes
74   int total_size;    // 4 bytes
75   void* data;        // 8 bytes
76 };
77 GOOGLE_CHECK_MESSAGE_SIZE(MockRepeatedPtrField, 24);
78 
79 struct MockRepeatedField {
80   int current_size;  // 4 bytes
81   int total_size;    // 4 bytes
82   void* data;        // 8 bytes
83 };
84 GOOGLE_CHECK_MESSAGE_SIZE(MockRepeatedField, 16);
85 
TEST(GeneratedMessageTest,MockSizes)86 TEST(GeneratedMessageTest, MockSizes) {
87   // Consistency checks -- if these fail, the tests below will definitely fail.
88   GOOGLE_CHECK_EQ(sizeof(MessageLite), sizeof(MockMessageBase));
89   GOOGLE_CHECK_EQ(sizeof(Message), sizeof(MockMessageBase));
90   GOOGLE_CHECK_EQ(sizeof(internal::ZeroFieldsBase), sizeof(MockZeroFieldsBase));
91   GOOGLE_CHECK_EQ(sizeof(internal::ExtensionSet), sizeof(MockExtensionSet));
92   GOOGLE_CHECK_EQ(sizeof(RepeatedPtrField<std::string>), sizeof(MockRepeatedPtrField));
93   GOOGLE_CHECK_EQ(sizeof(RepeatedField<int>), sizeof(MockRepeatedField));
94 }
95 
TEST(GeneratedMessageTest,EmptyMessageSize)96 TEST(GeneratedMessageTest, EmptyMessageSize) {
97   EXPECT_EQ(sizeof(protobuf_unittest::TestEmptyMessage),
98             sizeof(MockZeroFieldsBase));
99 }
100 
TEST(GeneratedMessageTest,ReservedSize)101 TEST(GeneratedMessageTest, ReservedSize) {
102   EXPECT_EQ(sizeof(protobuf_unittest::TestReservedFields),
103             sizeof(MockZeroFieldsBase));
104 }
105 
TEST(GeneratedMessageTest,EmptyMessageWithExtensionsSize)106 TEST(GeneratedMessageTest, EmptyMessageWithExtensionsSize) {
107   struct MockGenerated : public MockMessageBase {  // 16 bytes
108     MockExtensionSet extensions;                   // 24 bytes
109     int cached_size;                               // 4 bytes
110     // + 4 bytes of padding
111   };
112   GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 48);
113   EXPECT_EQ(sizeof(protobuf_unittest::TestEmptyMessageWithExtensions),
114             sizeof(MockGenerated));
115 }
116 
TEST(GeneratedMessageTest,RecursiveMessageSize)117 TEST(GeneratedMessageTest, RecursiveMessageSize) {
118   struct MockGenerated : public MockMessageBase {  // 16 bytes
119     int has_bits[1];                               // 4 bytes
120     int cached_size;                               // 4 bytes
121     void* a;                                       // 8 bytes
122     int32_t i;                                     // 4 bytes
123     // + 4 bytes padding
124   };
125   GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 40);
126   EXPECT_EQ(sizeof(protobuf_unittest::TestRecursiveMessage),
127             sizeof(MockGenerated));
128 }
129 
TEST(GeneratedMessageTest,OneStringSize)130 TEST(GeneratedMessageTest, OneStringSize) {
131   struct MockGenerated : public MockMessageBase {  // 16 bytes
132     int has_bits[1];                               // 4 bytes
133     int cached_size;                               // 4 bytes
134     void* data;                                    // 8 bytes
135   };
136   GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 32);
137   EXPECT_EQ(sizeof(protobuf_unittest::OneString), sizeof(MockGenerated));
138 }
139 
TEST(GeneratedMessageTest,MoreStringSize)140 TEST(GeneratedMessageTest, MoreStringSize) {
141   struct MockGenerated : public MockMessageBase {  // 16 bytes
142     int has_bits[1];                               // 4 bytes
143     int cached_size;                               // 4 bytes
144     MockRepeatedPtrField data;                     // 24 bytes
145   };
146   GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 48);
147   EXPECT_EQ(sizeof(protobuf_unittest::MoreString), sizeof(MockGenerated));
148 }
149 
TEST(GeneratedMessageTest,Int32MessageSize)150 TEST(GeneratedMessageTest, Int32MessageSize) {
151   struct MockGenerated : public MockMessageBase {  // 16 bytes
152     int has_bits[1];                               // 4 bytes
153     int cached_size;                               // 4 bytes
154     int32_t data;                                  // 4 bytes
155     // + 4 bytes padding
156   };
157   GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 32);
158   EXPECT_EQ(sizeof(protobuf_unittest::Int32Message), sizeof(MockGenerated));
159 }
160 
TEST(GeneratedMessageTest,Int64MessageSize)161 TEST(GeneratedMessageTest, Int64MessageSize) {
162   struct MockGenerated : public MockMessageBase {  // 16 bytes
163     int has_bits[1];                               // 4 bytes
164     int cached_size;                               // 4 bytes
165     int64_t data;                                  // 8 bytes
166   };
167   GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 32);
168   EXPECT_EQ(sizeof(protobuf_unittest::Int64Message), sizeof(MockGenerated));
169 }
170 
TEST(GeneratedMessageTest,BoolMessageSize)171 TEST(GeneratedMessageTest, BoolMessageSize) {
172   struct MockGenerated : public MockMessageBase {  // 16 bytes
173     int has_bits[1];                               // 4 bytes
174     int cached_size;                               // 4 bytes
175     bool data;                                     // 1 byte
176     // + 3 bytes padding
177   };
178   GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 32);
179   EXPECT_EQ(sizeof(protobuf_unittest::BoolMessage), sizeof(MockGenerated));
180 }
181 
TEST(GeneratedMessageTest,OneofSize)182 TEST(GeneratedMessageTest, OneofSize) {
183   struct MockGenerated : public MockMessageBase {  // 16 bytes
184     void* foo;                                     // 8 bytes
185     int cached_size;                               // 4 bytes
186     uint32_t oneof_case[1];                        // 4 bytes
187   };
188   GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 32);
189   EXPECT_EQ(sizeof(protobuf_unittest::TestOneof), sizeof(MockGenerated));
190 }
191 
TEST(GeneratedMessageTest,Oneof2Size)192 TEST(GeneratedMessageTest, Oneof2Size) {
193   struct MockGenerated : public MockMessageBase {  // 16 bytes
194     int has_bits[1];                               // 4 bytes
195     int cached_size;                               // 4 bytes
196     void* baz_string;                              // 8 bytes
197     int32_t baz_int;                               // 4 bytes
198                                                    // + 4 bytes padding
199     void* foo;                                     // 8 bytes
200     void* bar;                                     // 8 bytes
201     uint32_t oneof_case[2];                        // 8 bytes
202   };
203   GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 64);
204   EXPECT_EQ(sizeof(protobuf_unittest::TestOneof2), sizeof(MockGenerated));
205 }
206 
TEST(GeneratedMessageTest,FieldOrderingsSize)207 TEST(GeneratedMessageTest, FieldOrderingsSize) {
208   struct MockGenerated : public MockMessageBase {  // 16 bytes
209     int has_bits[1];                               // 4 bytes
210     int cached_size;                               // 4 bytes
211     MockExtensionSet extensions;                   // 24 bytes
212     void* my_string;                               // 8 bytes
213     void* optional_nested_message;                 // 8 bytes
214     int64_t my_int;                                // 8 bytes
215     float my_float;                                // 4 bytes
216     // + 4 bytes of padding
217   };
218   GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 80);
219   EXPECT_EQ(sizeof(protobuf_unittest::TestFieldOrderings), sizeof(MockGenerated));
220 }
221 
TEST(GeneratedMessageTest,TestMessageSize)222 TEST(GeneratedMessageTest, TestMessageSize) {
223   // We expect the message to contain (not in this order):
224   struct MockGenerated : public MockMessageBase {  // 16 bytes
225     int has_bits[1];                               // 4 bytes
226     int cached_size;                               // 4 bytes
227     void* m4;                                      // 8 bytes
228     int64_t m2;                                    // 8 bytes
229     bool m1;                                       // 1 bytes
230     bool m3;                                       // 1 bytes
231                                                    // + 2 bytes padding
232     int m5;                                        // 4 bytes
233     int64_t m6;                                    // 8 bytes
234   };
235   GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 56);
236   EXPECT_EQ(sizeof(protobuf_unittest::TestMessageSize), sizeof(MockGenerated));
237 }
238 
TEST(GeneratedMessageTest,PackedTypesSize)239 TEST(GeneratedMessageTest, PackedTypesSize) {
240   struct MockGenerated : public MockMessageBase {  // 16 bytes
241     MockRepeatedField packed_int32;                // 16 bytes
242     int packed_int32_cached_byte_size;             // 4 bytes + 4 bytes padding
243     MockRepeatedField packed_int64;                // 16 bytes
244     int packed_int64_cached_byte_size;             // 4 bytes + 4 bytes padding
245     MockRepeatedField packed_uint32;               // 16 bytes
246     int packed_uint32_cached_byte_size;            // 4 bytes + 4 bytes padding
247     MockRepeatedField packed_uint64;               // 16 bytes
248     int packed_uint64_cached_byte_size;            // 4 bytes + 4 bytes padding
249     MockRepeatedField packed_sint32;               // 16 bytes
250     int packed_sint32_cached_byte_size;            // 4 bytes + 4 bytes padding
251     MockRepeatedField packed_sint64;               // 16 bytes
252     int packed_sint64_cached_byte_size;            // 4 bytes + 4 bytes padding
253     MockRepeatedField packed_fixed32;              // 16 bytes
254     MockRepeatedField packed_fixed64;              // 16 bytes
255     MockRepeatedField packed_sfixed32;             // 16 bytes
256     MockRepeatedField packed_sfixed64;             // 16 bytes
257     MockRepeatedField packed_float;                // 16 bytes
258     MockRepeatedField packed_double;               // 16 bytes
259     MockRepeatedField packed_bool;                 // 16 bytes
260     MockRepeatedField packed_enum;                 // 16 bytes
261     int packed_enum_cached_byte_size;              // 4 bytes
262     int cached_size;                               // 4 bytes
263   };
264   GOOGLE_CHECK_MESSAGE_SIZE(MockGenerated, 16 * 15 + 8 * 6 + 8);
265   EXPECT_EQ(sizeof(protobuf_unittest::TestPackedTypes), sizeof(MockGenerated));
266 }
267 
268 }  // namespace cpp_unittest
269 }  // namespace cpp
270 }  // namespace compiler
271 }  // namespace protobuf
272 }  // namespace google
273