1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
31 // Author: kenton@google.com (Kenton Varda)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
34
35 #include <google/protobuf/stubs/hash.h>
36 #include <google/protobuf/stubs/common.h>
37 #include <google/protobuf/stubs/once.h>
38 #include <google/protobuf/extension_set.h>
39 #include <google/protobuf/message_lite.h>
40 #include <google/protobuf/io/coded_stream.h>
41 #include <google/protobuf/wire_format_lite_inl.h>
42 #include <google/protobuf/repeated_field.h>
43 #include <google/protobuf/stubs/map_util.h>
44
45 namespace google {
46 namespace protobuf {
47 namespace internal {
48
49 namespace {
50
real_type(FieldType type)51 inline WireFormatLite::FieldType real_type(FieldType type) {
52 GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE);
53 return static_cast<WireFormatLite::FieldType>(type);
54 }
55
cpp_type(FieldType type)56 inline WireFormatLite::CppType cpp_type(FieldType type) {
57 return WireFormatLite::FieldTypeToCppType(real_type(type));
58 }
59
is_packable(WireFormatLite::WireType type)60 inline bool is_packable(WireFormatLite::WireType type) {
61 switch (type) {
62 case WireFormatLite::WIRETYPE_VARINT:
63 case WireFormatLite::WIRETYPE_FIXED64:
64 case WireFormatLite::WIRETYPE_FIXED32:
65 return true;
66 case WireFormatLite::WIRETYPE_LENGTH_DELIMITED:
67 case WireFormatLite::WIRETYPE_START_GROUP:
68 case WireFormatLite::WIRETYPE_END_GROUP:
69 return false;
70
71 // Do not add a default statement. Let the compiler complain when someone
72 // adds a new wire type.
73 }
74 }
75
76 // Registry stuff.
77 typedef hash_map<pair<const MessageLite*, int>,
78 ExtensionInfo> ExtensionRegistry;
79 ExtensionRegistry* registry_ = NULL;
80 GOOGLE_PROTOBUF_DECLARE_ONCE(registry_init_);
81
DeleteRegistry()82 void DeleteRegistry() {
83 delete registry_;
84 registry_ = NULL;
85 }
86
InitRegistry()87 void InitRegistry() {
88 registry_ = new ExtensionRegistry;
89 OnShutdown(&DeleteRegistry);
90 }
91
92 // This function is only called at startup, so there is no need for thread-
93 // safety.
Register(const MessageLite * containing_type,int number,ExtensionInfo info)94 void Register(const MessageLite* containing_type,
95 int number, ExtensionInfo info) {
96 ::google::protobuf::GoogleOnceInit(®istry_init_, &InitRegistry);
97
98 if (!InsertIfNotPresent(registry_, make_pair(containing_type, number),
99 info)) {
100 GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \""
101 << containing_type->GetTypeName()
102 << "\", field number " << number << ".";
103 }
104 }
105
FindRegisteredExtension(const MessageLite * containing_type,int number)106 const ExtensionInfo* FindRegisteredExtension(
107 const MessageLite* containing_type, int number) {
108 return (registry_ == NULL) ? NULL :
109 FindOrNull(*registry_, make_pair(containing_type, number));
110 }
111
112 } // namespace
113
~ExtensionFinder()114 ExtensionFinder::~ExtensionFinder() {}
115
Find(int number,ExtensionInfo * output)116 bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) {
117 const ExtensionInfo* extension =
118 FindRegisteredExtension(containing_type_, number);
119 if (extension == NULL) {
120 return false;
121 } else {
122 *output = *extension;
123 return true;
124 }
125 }
126
RegisterExtension(const MessageLite * containing_type,int number,FieldType type,bool is_repeated,bool is_packed)127 void ExtensionSet::RegisterExtension(const MessageLite* containing_type,
128 int number, FieldType type,
129 bool is_repeated, bool is_packed) {
130 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_ENUM);
131 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE);
132 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_GROUP);
133 ExtensionInfo info(type, is_repeated, is_packed);
134 Register(containing_type, number, info);
135 }
136
CallNoArgValidityFunc(const void * arg,int number)137 static bool CallNoArgValidityFunc(const void* arg, int number) {
138 // Note: Must use C-style cast here rather than reinterpret_cast because
139 // the C++ standard at one point did not allow casts between function and
140 // data pointers and some compilers enforce this for C++-style casts. No
141 // compiler enforces it for C-style casts since lots of C-style code has
142 // relied on these kinds of casts for a long time, despite being
143 // technically undefined. See:
144 // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195
145 // Also note: Some compilers do not allow function pointers to be "const".
146 // Which makes sense, I suppose, because it's meaningless.
147 return ((EnumValidityFunc*)arg)(number);
148 }
149
RegisterEnumExtension(const MessageLite * containing_type,int number,FieldType type,bool is_repeated,bool is_packed,EnumValidityFunc * is_valid)150 void ExtensionSet::RegisterEnumExtension(const MessageLite* containing_type,
151 int number, FieldType type,
152 bool is_repeated, bool is_packed,
153 EnumValidityFunc* is_valid) {
154 GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM);
155 ExtensionInfo info(type, is_repeated, is_packed);
156 info.enum_validity_check.func = CallNoArgValidityFunc;
157 // See comment in CallNoArgValidityFunc() about why we use a c-style cast.
158 info.enum_validity_check.arg = (void*)is_valid;
159 Register(containing_type, number, info);
160 }
161
RegisterMessageExtension(const MessageLite * containing_type,int number,FieldType type,bool is_repeated,bool is_packed,const MessageLite * prototype)162 void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type,
163 int number, FieldType type,
164 bool is_repeated, bool is_packed,
165 const MessageLite* prototype) {
166 GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE ||
167 type == WireFormatLite::TYPE_GROUP);
168 ExtensionInfo info(type, is_repeated, is_packed);
169 info.message_prototype = prototype;
170 Register(containing_type, number, info);
171 }
172
173
174 // ===================================================================
175 // Constructors and basic methods.
176
ExtensionSet()177 ExtensionSet::ExtensionSet() {}
178
~ExtensionSet()179 ExtensionSet::~ExtensionSet() {
180 for (map<int, Extension>::iterator iter = extensions_.begin();
181 iter != extensions_.end(); ++iter) {
182 iter->second.Free();
183 }
184 }
185
186 // Defined in extension_set_heavy.cc.
187 // void ExtensionSet::AppendToList(const Descriptor* containing_type,
188 // const DescriptorPool* pool,
189 // vector<const FieldDescriptor*>* output) const
190
Has(int number) const191 bool ExtensionSet::Has(int number) const {
192 map<int, Extension>::const_iterator iter = extensions_.find(number);
193 if (iter == extensions_.end()) return false;
194 GOOGLE_DCHECK(!iter->second.is_repeated);
195 return !iter->second.is_cleared;
196 }
197
NumExtensions() const198 int ExtensionSet::NumExtensions() const {
199 int result = 0;
200 for (map<int, Extension>::const_iterator iter = extensions_.begin();
201 iter != extensions_.end(); ++iter) {
202 if (!iter->second.is_cleared) {
203 ++result;
204 }
205 }
206 return result;
207 }
208
ExtensionSize(int number) const209 int ExtensionSet::ExtensionSize(int number) const {
210 map<int, Extension>::const_iterator iter = extensions_.find(number);
211 if (iter == extensions_.end()) return false;
212 return iter->second.GetSize();
213 }
214
ExtensionType(int number) const215 FieldType ExtensionSet::ExtensionType(int number) const {
216 map<int, Extension>::const_iterator iter = extensions_.find(number);
217 if (iter == extensions_.end()) {
218 GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (1). ";
219 return 0;
220 }
221 if (iter->second.is_cleared) {
222 GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (2). ";
223 }
224 return iter->second.type;
225 }
226
ClearExtension(int number)227 void ExtensionSet::ClearExtension(int number) {
228 map<int, Extension>::iterator iter = extensions_.find(number);
229 if (iter == extensions_.end()) return;
230 iter->second.Clear();
231 }
232
233 // ===================================================================
234 // Field accessors
235
236 namespace {
237
238 enum Cardinality {
239 REPEATED,
240 OPTIONAL
241 };
242
243 } // namespace
244
245 #define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \
246 GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? REPEATED : OPTIONAL, LABEL); \
247 GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), WireFormatLite::CPPTYPE_##CPPTYPE)
248
249 // -------------------------------------------------------------------
250 // Primitives
251
252 #define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE) \
253 \
254 LOWERCASE ExtensionSet::Get##CAMELCASE(int number, \
255 LOWERCASE default_value) const { \
256 map<int, Extension>::const_iterator iter = extensions_.find(number); \
257 if (iter == extensions_.end() || iter->second.is_cleared) { \
258 return default_value; \
259 } else { \
260 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, UPPERCASE); \
261 return iter->second.LOWERCASE##_value; \
262 } \
263 } \
264 \
265 void ExtensionSet::Set##CAMELCASE(int number, FieldType type, \
266 LOWERCASE value, \
267 const FieldDescriptor* descriptor) { \
268 Extension* extension; \
269 if (MaybeNewExtension(number, descriptor, &extension)) { \
270 extension->type = type; \
271 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
272 extension->is_repeated = false; \
273 } else { \
274 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, UPPERCASE); \
275 } \
276 extension->is_cleared = false; \
277 extension->LOWERCASE##_value = value; \
278 } \
279 \
280 LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) const { \
281 map<int, Extension>::const_iterator iter = extensions_.find(number); \
282 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
283 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \
284 return iter->second.repeated_##LOWERCASE##_value->Get(index); \
285 } \
286 \
287 void ExtensionSet::SetRepeated##CAMELCASE( \
288 int number, int index, LOWERCASE value) { \
289 map<int, Extension>::iterator iter = extensions_.find(number); \
290 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
291 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \
292 iter->second.repeated_##LOWERCASE##_value->Set(index, value); \
293 } \
294 \
295 void ExtensionSet::Add##CAMELCASE(int number, FieldType type, \
296 bool packed, LOWERCASE value, \
297 const FieldDescriptor* descriptor) { \
298 Extension* extension; \
299 if (MaybeNewExtension(number, descriptor, &extension)) { \
300 extension->type = type; \
301 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
302 extension->is_repeated = true; \
303 extension->is_packed = packed; \
304 extension->repeated_##LOWERCASE##_value = new RepeatedField<LOWERCASE>(); \
305 } else { \
306 GOOGLE_DCHECK_TYPE(*extension, REPEATED, UPPERCASE); \
307 GOOGLE_DCHECK_EQ(extension->is_packed, packed); \
308 } \
309 extension->repeated_##LOWERCASE##_value->Add(value); \
310 }
311
PRIMITIVE_ACCESSORS(INT32,int32,Int32)312 PRIMITIVE_ACCESSORS( INT32, int32, Int32)
313 PRIMITIVE_ACCESSORS( INT64, int64, Int64)
314 PRIMITIVE_ACCESSORS(UINT32, uint32, UInt32)
315 PRIMITIVE_ACCESSORS(UINT64, uint64, UInt64)
316 PRIMITIVE_ACCESSORS( FLOAT, float, Float)
317 PRIMITIVE_ACCESSORS(DOUBLE, double, Double)
318 PRIMITIVE_ACCESSORS( BOOL, bool, Bool)
319
320 #undef PRIMITIVE_ACCESSORS
321
322 const void* ExtensionSet::GetRawRepeatedField(int number,
323 const void* default_value) const {
324 map<int, Extension>::const_iterator iter = extensions_.find(number);
325 if (iter == extensions_.end()) {
326 return default_value;
327 }
328 // We assume that all the RepeatedField<>* pointers have the same
329 // size and alignment within the anonymous union in Extension.
330 return iter->second.repeated_int32_value;
331 }
332
MutableRawRepeatedField(int number,FieldType field_type,bool packed,const FieldDescriptor * desc)333 void* ExtensionSet::MutableRawRepeatedField(int number, FieldType field_type,
334 bool packed,
335 const FieldDescriptor* desc) {
336 Extension* extension;
337
338 // We instantiate an empty Repeated{,Ptr}Field if one doesn't exist for this
339 // extension.
340 if (MaybeNewExtension(number, desc, &extension)) {
341 extension->is_repeated = true;
342 extension->type = field_type;
343 extension->is_packed = packed;
344
345 switch (WireFormatLite::FieldTypeToCppType(
346 static_cast<WireFormatLite::FieldType>(field_type))) {
347 case WireFormatLite::CPPTYPE_INT32:
348 extension->repeated_int32_value = new RepeatedField<int32>();
349 break;
350 case WireFormatLite::CPPTYPE_INT64:
351 extension->repeated_int64_value = new RepeatedField<int64>();
352 break;
353 case WireFormatLite::CPPTYPE_UINT32:
354 extension->repeated_uint32_value = new RepeatedField<uint32>();
355 break;
356 case WireFormatLite::CPPTYPE_UINT64:
357 extension->repeated_uint64_value = new RepeatedField<uint64>();
358 break;
359 case WireFormatLite::CPPTYPE_DOUBLE:
360 extension->repeated_double_value = new RepeatedField<double>();
361 break;
362 case WireFormatLite::CPPTYPE_FLOAT:
363 extension->repeated_float_value = new RepeatedField<float>();
364 break;
365 case WireFormatLite::CPPTYPE_BOOL:
366 extension->repeated_bool_value = new RepeatedField<bool>();
367 break;
368 case WireFormatLite::CPPTYPE_ENUM:
369 extension->repeated_enum_value = new RepeatedField<int>();
370 break;
371 case WireFormatLite::CPPTYPE_STRING:
372 extension->repeated_string_value = new RepeatedPtrField< ::std::string>();
373 break;
374 case WireFormatLite::CPPTYPE_MESSAGE:
375 extension->repeated_message_value = new RepeatedPtrField<MessageLite>();
376 break;
377 }
378 }
379
380 // We assume that all the RepeatedField<>* pointers have the same
381 // size and alignment within the anonymous union in Extension.
382 return extension->repeated_int32_value;
383 }
384
385 // Compatible version using old call signature. Does not create extensions when
386 // the don't already exist; instead, just GOOGLE_CHECK-fails.
MutableRawRepeatedField(int number)387 void* ExtensionSet::MutableRawRepeatedField(int number) {
388 map<int, Extension>::iterator iter = extensions_.find(number);
389 GOOGLE_CHECK(iter == extensions_.end()) << "Extension not found.";
390 // We assume that all the RepeatedField<>* pointers have the same
391 // size and alignment within the anonymous union in Extension.
392 return iter->second.repeated_int32_value;
393 }
394
395
396 // -------------------------------------------------------------------
397 // Enums
398
GetEnum(int number,int default_value) const399 int ExtensionSet::GetEnum(int number, int default_value) const {
400 map<int, Extension>::const_iterator iter = extensions_.find(number);
401 if (iter == extensions_.end() || iter->second.is_cleared) {
402 // Not present. Return the default value.
403 return default_value;
404 } else {
405 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, ENUM);
406 return iter->second.enum_value;
407 }
408 }
409
SetEnum(int number,FieldType type,int value,const FieldDescriptor * descriptor)410 void ExtensionSet::SetEnum(int number, FieldType type, int value,
411 const FieldDescriptor* descriptor) {
412 Extension* extension;
413 if (MaybeNewExtension(number, descriptor, &extension)) {
414 extension->type = type;
415 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
416 extension->is_repeated = false;
417 } else {
418 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, ENUM);
419 }
420 extension->is_cleared = false;
421 extension->enum_value = value;
422 }
423
GetRepeatedEnum(int number,int index) const424 int ExtensionSet::GetRepeatedEnum(int number, int index) const {
425 map<int, Extension>::const_iterator iter = extensions_.find(number);
426 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
427 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
428 return iter->second.repeated_enum_value->Get(index);
429 }
430
SetRepeatedEnum(int number,int index,int value)431 void ExtensionSet::SetRepeatedEnum(int number, int index, int value) {
432 map<int, Extension>::iterator iter = extensions_.find(number);
433 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
434 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
435 iter->second.repeated_enum_value->Set(index, value);
436 }
437
AddEnum(int number,FieldType type,bool packed,int value,const FieldDescriptor * descriptor)438 void ExtensionSet::AddEnum(int number, FieldType type,
439 bool packed, int value,
440 const FieldDescriptor* descriptor) {
441 Extension* extension;
442 if (MaybeNewExtension(number, descriptor, &extension)) {
443 extension->type = type;
444 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
445 extension->is_repeated = true;
446 extension->is_packed = packed;
447 extension->repeated_enum_value = new RepeatedField<int>();
448 } else {
449 GOOGLE_DCHECK_TYPE(*extension, REPEATED, ENUM);
450 GOOGLE_DCHECK_EQ(extension->is_packed, packed);
451 }
452 extension->repeated_enum_value->Add(value);
453 }
454
455 // -------------------------------------------------------------------
456 // Strings
457
GetString(int number,const string & default_value) const458 const string& ExtensionSet::GetString(int number,
459 const string& default_value) const {
460 map<int, Extension>::const_iterator iter = extensions_.find(number);
461 if (iter == extensions_.end() || iter->second.is_cleared) {
462 // Not present. Return the default value.
463 return default_value;
464 } else {
465 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, STRING);
466 return *iter->second.string_value;
467 }
468 }
469
MutableString(int number,FieldType type,const FieldDescriptor * descriptor)470 string* ExtensionSet::MutableString(int number, FieldType type,
471 const FieldDescriptor* descriptor) {
472 Extension* extension;
473 if (MaybeNewExtension(number, descriptor, &extension)) {
474 extension->type = type;
475 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
476 extension->is_repeated = false;
477 extension->string_value = new string;
478 } else {
479 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, STRING);
480 }
481 extension->is_cleared = false;
482 return extension->string_value;
483 }
484
GetRepeatedString(int number,int index) const485 const string& ExtensionSet::GetRepeatedString(int number, int index) const {
486 map<int, Extension>::const_iterator iter = extensions_.find(number);
487 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
488 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
489 return iter->second.repeated_string_value->Get(index);
490 }
491
MutableRepeatedString(int number,int index)492 string* ExtensionSet::MutableRepeatedString(int number, int index) {
493 map<int, Extension>::iterator iter = extensions_.find(number);
494 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
495 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
496 return iter->second.repeated_string_value->Mutable(index);
497 }
498
AddString(int number,FieldType type,const FieldDescriptor * descriptor)499 string* ExtensionSet::AddString(int number, FieldType type,
500 const FieldDescriptor* descriptor) {
501 Extension* extension;
502 if (MaybeNewExtension(number, descriptor, &extension)) {
503 extension->type = type;
504 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
505 extension->is_repeated = true;
506 extension->is_packed = false;
507 extension->repeated_string_value = new RepeatedPtrField<string>();
508 } else {
509 GOOGLE_DCHECK_TYPE(*extension, REPEATED, STRING);
510 }
511 return extension->repeated_string_value->Add();
512 }
513
514 // -------------------------------------------------------------------
515 // Messages
516
GetMessage(int number,const MessageLite & default_value) const517 const MessageLite& ExtensionSet::GetMessage(
518 int number, const MessageLite& default_value) const {
519 map<int, Extension>::const_iterator iter = extensions_.find(number);
520 if (iter == extensions_.end()) {
521 // Not present. Return the default value.
522 return default_value;
523 } else {
524 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
525 if (iter->second.is_lazy) {
526 return iter->second.lazymessage_value->GetMessage(default_value);
527 } else {
528 return *iter->second.message_value;
529 }
530 }
531 }
532
533 // Defined in extension_set_heavy.cc.
534 // const MessageLite& ExtensionSet::GetMessage(int number,
535 // const Descriptor* message_type,
536 // MessageFactory* factory) const
537
MutableMessage(int number,FieldType type,const MessageLite & prototype,const FieldDescriptor * descriptor)538 MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
539 const MessageLite& prototype,
540 const FieldDescriptor* descriptor) {
541 Extension* extension;
542 if (MaybeNewExtension(number, descriptor, &extension)) {
543 extension->type = type;
544 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
545 extension->is_repeated = false;
546 extension->is_lazy = false;
547 extension->message_value = prototype.New();
548 extension->is_cleared = false;
549 return extension->message_value;
550 } else {
551 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
552 extension->is_cleared = false;
553 if (extension->is_lazy) {
554 return extension->lazymessage_value->MutableMessage(prototype);
555 } else {
556 return extension->message_value;
557 }
558 }
559 }
560
561 // Defined in extension_set_heavy.cc.
562 // MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
563 // const Descriptor* message_type,
564 // MessageFactory* factory)
565
SetAllocatedMessage(int number,FieldType type,const FieldDescriptor * descriptor,MessageLite * message)566 void ExtensionSet::SetAllocatedMessage(int number, FieldType type,
567 const FieldDescriptor* descriptor,
568 MessageLite* message) {
569 if (message == NULL) {
570 ClearExtension(number);
571 return;
572 }
573 Extension* extension;
574 if (MaybeNewExtension(number, descriptor, &extension)) {
575 extension->type = type;
576 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
577 extension->is_repeated = false;
578 extension->is_lazy = false;
579 extension->message_value = message;
580 } else {
581 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
582 if (extension->is_lazy) {
583 extension->lazymessage_value->SetAllocatedMessage(message);
584 } else {
585 delete extension->message_value;
586 extension->message_value = message;
587 }
588 }
589 extension->is_cleared = false;
590 }
591
ReleaseMessage(int number,const MessageLite & prototype)592 MessageLite* ExtensionSet::ReleaseMessage(int number,
593 const MessageLite& prototype) {
594 map<int, Extension>::iterator iter = extensions_.find(number);
595 if (iter == extensions_.end()) {
596 // Not present. Return NULL.
597 return NULL;
598 } else {
599 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
600 MessageLite* ret = NULL;
601 if (iter->second.is_lazy) {
602 ret = iter->second.lazymessage_value->ReleaseMessage(prototype);
603 delete iter->second.lazymessage_value;
604 } else {
605 ret = iter->second.message_value;
606 }
607 extensions_.erase(number);
608 return ret;
609 }
610 }
611
612 // Defined in extension_set_heavy.cc.
613 // MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
614 // MessageFactory* factory);
615
GetRepeatedMessage(int number,int index) const616 const MessageLite& ExtensionSet::GetRepeatedMessage(
617 int number, int index) const {
618 map<int, Extension>::const_iterator iter = extensions_.find(number);
619 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
620 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
621 return iter->second.repeated_message_value->Get(index);
622 }
623
MutableRepeatedMessage(int number,int index)624 MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) {
625 map<int, Extension>::iterator iter = extensions_.find(number);
626 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
627 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
628 return iter->second.repeated_message_value->Mutable(index);
629 }
630
AddMessage(int number,FieldType type,const MessageLite & prototype,const FieldDescriptor * descriptor)631 MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
632 const MessageLite& prototype,
633 const FieldDescriptor* descriptor) {
634 Extension* extension;
635 if (MaybeNewExtension(number, descriptor, &extension)) {
636 extension->type = type;
637 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
638 extension->is_repeated = true;
639 extension->repeated_message_value =
640 new RepeatedPtrField<MessageLite>();
641 } else {
642 GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
643 }
644
645 // RepeatedPtrField<MessageLite> does not know how to Add() since it cannot
646 // allocate an abstract object, so we have to be tricky.
647 MessageLite* result = extension->repeated_message_value
648 ->AddFromCleared<GenericTypeHandler<MessageLite> >();
649 if (result == NULL) {
650 result = prototype.New();
651 extension->repeated_message_value->AddAllocated(result);
652 }
653 return result;
654 }
655
656 // Defined in extension_set_heavy.cc.
657 // MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
658 // const Descriptor* message_type,
659 // MessageFactory* factory)
660
661 #undef GOOGLE_DCHECK_TYPE
662
RemoveLast(int number)663 void ExtensionSet::RemoveLast(int number) {
664 map<int, Extension>::iterator iter = extensions_.find(number);
665 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
666
667 Extension* extension = &iter->second;
668 GOOGLE_DCHECK(extension->is_repeated);
669
670 switch(cpp_type(extension->type)) {
671 case WireFormatLite::CPPTYPE_INT32:
672 extension->repeated_int32_value->RemoveLast();
673 break;
674 case WireFormatLite::CPPTYPE_INT64:
675 extension->repeated_int64_value->RemoveLast();
676 break;
677 case WireFormatLite::CPPTYPE_UINT32:
678 extension->repeated_uint32_value->RemoveLast();
679 break;
680 case WireFormatLite::CPPTYPE_UINT64:
681 extension->repeated_uint64_value->RemoveLast();
682 break;
683 case WireFormatLite::CPPTYPE_FLOAT:
684 extension->repeated_float_value->RemoveLast();
685 break;
686 case WireFormatLite::CPPTYPE_DOUBLE:
687 extension->repeated_double_value->RemoveLast();
688 break;
689 case WireFormatLite::CPPTYPE_BOOL:
690 extension->repeated_bool_value->RemoveLast();
691 break;
692 case WireFormatLite::CPPTYPE_ENUM:
693 extension->repeated_enum_value->RemoveLast();
694 break;
695 case WireFormatLite::CPPTYPE_STRING:
696 extension->repeated_string_value->RemoveLast();
697 break;
698 case WireFormatLite::CPPTYPE_MESSAGE:
699 extension->repeated_message_value->RemoveLast();
700 break;
701 }
702 }
703
ReleaseLast(int number)704 MessageLite* ExtensionSet::ReleaseLast(int number) {
705 map<int, Extension>::iterator iter = extensions_.find(number);
706 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
707
708 Extension* extension = &iter->second;
709 GOOGLE_DCHECK(extension->is_repeated);
710 GOOGLE_DCHECK(cpp_type(extension->type) == WireFormatLite::CPPTYPE_MESSAGE);
711 return extension->repeated_message_value->ReleaseLast();
712 }
713
SwapElements(int number,int index1,int index2)714 void ExtensionSet::SwapElements(int number, int index1, int index2) {
715 map<int, Extension>::iterator iter = extensions_.find(number);
716 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
717
718 Extension* extension = &iter->second;
719 GOOGLE_DCHECK(extension->is_repeated);
720
721 switch(cpp_type(extension->type)) {
722 case WireFormatLite::CPPTYPE_INT32:
723 extension->repeated_int32_value->SwapElements(index1, index2);
724 break;
725 case WireFormatLite::CPPTYPE_INT64:
726 extension->repeated_int64_value->SwapElements(index1, index2);
727 break;
728 case WireFormatLite::CPPTYPE_UINT32:
729 extension->repeated_uint32_value->SwapElements(index1, index2);
730 break;
731 case WireFormatLite::CPPTYPE_UINT64:
732 extension->repeated_uint64_value->SwapElements(index1, index2);
733 break;
734 case WireFormatLite::CPPTYPE_FLOAT:
735 extension->repeated_float_value->SwapElements(index1, index2);
736 break;
737 case WireFormatLite::CPPTYPE_DOUBLE:
738 extension->repeated_double_value->SwapElements(index1, index2);
739 break;
740 case WireFormatLite::CPPTYPE_BOOL:
741 extension->repeated_bool_value->SwapElements(index1, index2);
742 break;
743 case WireFormatLite::CPPTYPE_ENUM:
744 extension->repeated_enum_value->SwapElements(index1, index2);
745 break;
746 case WireFormatLite::CPPTYPE_STRING:
747 extension->repeated_string_value->SwapElements(index1, index2);
748 break;
749 case WireFormatLite::CPPTYPE_MESSAGE:
750 extension->repeated_message_value->SwapElements(index1, index2);
751 break;
752 }
753 }
754
755 // ===================================================================
756
Clear()757 void ExtensionSet::Clear() {
758 for (map<int, Extension>::iterator iter = extensions_.begin();
759 iter != extensions_.end(); ++iter) {
760 iter->second.Clear();
761 }
762 }
763
MergeFrom(const ExtensionSet & other)764 void ExtensionSet::MergeFrom(const ExtensionSet& other) {
765 for (map<int, Extension>::const_iterator iter = other.extensions_.begin();
766 iter != other.extensions_.end(); ++iter) {
767 const Extension& other_extension = iter->second;
768
769 if (other_extension.is_repeated) {
770 Extension* extension;
771 bool is_new = MaybeNewExtension(iter->first, other_extension.descriptor,
772 &extension);
773 if (is_new) {
774 // Extension did not already exist in set.
775 extension->type = other_extension.type;
776 extension->is_packed = other_extension.is_packed;
777 extension->is_repeated = true;
778 } else {
779 GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
780 GOOGLE_DCHECK_EQ(extension->is_packed, other_extension.is_packed);
781 GOOGLE_DCHECK(extension->is_repeated);
782 }
783
784 switch (cpp_type(other_extension.type)) {
785 #define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE) \
786 case WireFormatLite::CPPTYPE_##UPPERCASE: \
787 if (is_new) { \
788 extension->repeated_##LOWERCASE##_value = \
789 new REPEATED_TYPE; \
790 } \
791 extension->repeated_##LOWERCASE##_value->MergeFrom( \
792 *other_extension.repeated_##LOWERCASE##_value); \
793 break;
794
795 HANDLE_TYPE( INT32, int32, RepeatedField < int32>);
796 HANDLE_TYPE( INT64, int64, RepeatedField < int64>);
797 HANDLE_TYPE( UINT32, uint32, RepeatedField < uint32>);
798 HANDLE_TYPE( UINT64, uint64, RepeatedField < uint64>);
799 HANDLE_TYPE( FLOAT, float, RepeatedField < float>);
800 HANDLE_TYPE( DOUBLE, double, RepeatedField < double>);
801 HANDLE_TYPE( BOOL, bool, RepeatedField < bool>);
802 HANDLE_TYPE( ENUM, enum, RepeatedField < int>);
803 HANDLE_TYPE( STRING, string, RepeatedPtrField< string>);
804 #undef HANDLE_TYPE
805
806 case WireFormatLite::CPPTYPE_MESSAGE:
807 if (is_new) {
808 extension->repeated_message_value =
809 new RepeatedPtrField<MessageLite>();
810 }
811 // We can't call RepeatedPtrField<MessageLite>::MergeFrom() because
812 // it would attempt to allocate new objects.
813 RepeatedPtrField<MessageLite>* other_repeated_message =
814 other_extension.repeated_message_value;
815 for (int i = 0; i < other_repeated_message->size(); i++) {
816 const MessageLite& other_message = other_repeated_message->Get(i);
817 MessageLite* target = extension->repeated_message_value
818 ->AddFromCleared<GenericTypeHandler<MessageLite> >();
819 if (target == NULL) {
820 target = other_message.New();
821 extension->repeated_message_value->AddAllocated(target);
822 }
823 target->CheckTypeAndMergeFrom(other_message);
824 }
825 break;
826 }
827 } else {
828 if (!other_extension.is_cleared) {
829 switch (cpp_type(other_extension.type)) {
830 #define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE) \
831 case WireFormatLite::CPPTYPE_##UPPERCASE: \
832 Set##CAMELCASE(iter->first, other_extension.type, \
833 other_extension.LOWERCASE##_value, \
834 other_extension.descriptor); \
835 break;
836
837 HANDLE_TYPE( INT32, int32, Int32);
838 HANDLE_TYPE( INT64, int64, Int64);
839 HANDLE_TYPE(UINT32, uint32, UInt32);
840 HANDLE_TYPE(UINT64, uint64, UInt64);
841 HANDLE_TYPE( FLOAT, float, Float);
842 HANDLE_TYPE(DOUBLE, double, Double);
843 HANDLE_TYPE( BOOL, bool, Bool);
844 HANDLE_TYPE( ENUM, enum, Enum);
845 #undef HANDLE_TYPE
846 case WireFormatLite::CPPTYPE_STRING:
847 SetString(iter->first, other_extension.type,
848 *other_extension.string_value,
849 other_extension.descriptor);
850 break;
851 case WireFormatLite::CPPTYPE_MESSAGE: {
852 Extension* extension;
853 bool is_new = MaybeNewExtension(iter->first,
854 other_extension.descriptor,
855 &extension);
856 if (is_new) {
857 extension->type = other_extension.type;
858 extension->is_packed = other_extension.is_packed;
859 extension->is_repeated = false;
860 if (other_extension.is_lazy) {
861 extension->is_lazy = true;
862 extension->lazymessage_value =
863 other_extension.lazymessage_value->New();
864 extension->lazymessage_value->MergeFrom(
865 *other_extension.lazymessage_value);
866 } else {
867 extension->is_lazy = false;
868 extension->message_value =
869 other_extension.message_value->New();
870 extension->message_value->CheckTypeAndMergeFrom(
871 *other_extension.message_value);
872 }
873 } else {
874 GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
875 GOOGLE_DCHECK_EQ(extension->is_packed,other_extension.is_packed);
876 GOOGLE_DCHECK(!extension->is_repeated);
877 if (other_extension.is_lazy) {
878 if (extension->is_lazy) {
879 extension->lazymessage_value->MergeFrom(
880 *other_extension.lazymessage_value);
881 } else {
882 extension->message_value->CheckTypeAndMergeFrom(
883 other_extension.lazymessage_value->GetMessage(
884 *extension->message_value));
885 }
886 } else {
887 if (extension->is_lazy) {
888 extension->lazymessage_value->MutableMessage(
889 *other_extension.message_value)->CheckTypeAndMergeFrom(
890 *other_extension.message_value);
891 } else {
892 extension->message_value->CheckTypeAndMergeFrom(
893 *other_extension.message_value);
894 }
895 }
896 }
897 extension->is_cleared = false;
898 break;
899 }
900 }
901 }
902 }
903 }
904 }
905
Swap(ExtensionSet * x)906 void ExtensionSet::Swap(ExtensionSet* x) {
907 extensions_.swap(x->extensions_);
908 }
909
SwapExtension(ExtensionSet * other,int number)910 void ExtensionSet::SwapExtension(ExtensionSet* other,
911 int number) {
912 if (this == other) return;
913 map<int, Extension>::iterator this_iter = extensions_.find(number);
914 map<int, Extension>::iterator other_iter = other->extensions_.find(number);
915
916 if (this_iter == extensions_.end() &&
917 other_iter == other->extensions_.end()) {
918 return;
919 }
920
921 if (this_iter != extensions_.end() &&
922 other_iter != other->extensions_.end()) {
923 std::swap(this_iter->second, other_iter->second);
924 return;
925 }
926
927 if (this_iter == extensions_.end()) {
928 extensions_.insert(make_pair(number, other_iter->second));
929 other->extensions_.erase(number);
930 return;
931 }
932
933 if (other_iter == other->extensions_.end()) {
934 other->extensions_.insert(make_pair(number, this_iter->second));
935 extensions_.erase(number);
936 return;
937 }
938 }
939
IsInitialized() const940 bool ExtensionSet::IsInitialized() const {
941 // Extensions are never required. However, we need to check that all
942 // embedded messages are initialized.
943 for (map<int, Extension>::const_iterator iter = extensions_.begin();
944 iter != extensions_.end(); ++iter) {
945 const Extension& extension = iter->second;
946 if (cpp_type(extension.type) == WireFormatLite::CPPTYPE_MESSAGE) {
947 if (extension.is_repeated) {
948 for (int i = 0; i < extension.repeated_message_value->size(); i++) {
949 if (!extension.repeated_message_value->Get(i).IsInitialized()) {
950 return false;
951 }
952 }
953 } else {
954 if (!extension.is_cleared) {
955 if (extension.is_lazy) {
956 if (!extension.lazymessage_value->IsInitialized()) return false;
957 } else {
958 if (!extension.message_value->IsInitialized()) return false;
959 }
960 }
961 }
962 }
963 }
964
965 return true;
966 }
967
FindExtensionInfoFromTag(uint32 tag,ExtensionFinder * extension_finder,int * field_number,ExtensionInfo * extension,bool * was_packed_on_wire)968 bool ExtensionSet::FindExtensionInfoFromTag(
969 uint32 tag, ExtensionFinder* extension_finder, int* field_number,
970 ExtensionInfo* extension, bool* was_packed_on_wire) {
971 *field_number = WireFormatLite::GetTagFieldNumber(tag);
972 WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
973 return FindExtensionInfoFromFieldNumber(wire_type, *field_number,
974 extension_finder, extension,
975 was_packed_on_wire);
976 }
977
FindExtensionInfoFromFieldNumber(int wire_type,int field_number,ExtensionFinder * extension_finder,ExtensionInfo * extension,bool * was_packed_on_wire)978 bool ExtensionSet::FindExtensionInfoFromFieldNumber(
979 int wire_type, int field_number, ExtensionFinder* extension_finder,
980 ExtensionInfo* extension, bool* was_packed_on_wire) {
981 if (!extension_finder->Find(field_number, extension)) {
982 return false;
983 }
984
985 WireFormatLite::WireType expected_wire_type =
986 WireFormatLite::WireTypeForFieldType(real_type(extension->type));
987
988 // Check if this is a packed field.
989 *was_packed_on_wire = false;
990 if (extension->is_repeated &&
991 wire_type == WireFormatLite::WIRETYPE_LENGTH_DELIMITED &&
992 is_packable(expected_wire_type)) {
993 *was_packed_on_wire = true;
994 return true;
995 }
996 // Otherwise the wire type must match.
997 return expected_wire_type == wire_type;
998 }
999
ParseField(uint32 tag,io::CodedInputStream * input,ExtensionFinder * extension_finder,FieldSkipper * field_skipper)1000 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1001 ExtensionFinder* extension_finder,
1002 FieldSkipper* field_skipper) {
1003 int number;
1004 bool was_packed_on_wire;
1005 ExtensionInfo extension;
1006 if (!FindExtensionInfoFromTag(
1007 tag, extension_finder, &number, &extension, &was_packed_on_wire)) {
1008 return field_skipper->SkipField(input, tag);
1009 } else {
1010 return ParseFieldWithExtensionInfo(
1011 number, was_packed_on_wire, extension, input, field_skipper);
1012 }
1013 }
1014
ParseFieldWithExtensionInfo(int number,bool was_packed_on_wire,const ExtensionInfo & extension,io::CodedInputStream * input,FieldSkipper * field_skipper)1015 bool ExtensionSet::ParseFieldWithExtensionInfo(
1016 int number, bool was_packed_on_wire, const ExtensionInfo& extension,
1017 io::CodedInputStream* input,
1018 FieldSkipper* field_skipper) {
1019 // Explicitly not read extension.is_packed, instead check whether the field
1020 // was encoded in packed form on the wire.
1021 if (was_packed_on_wire) {
1022 uint32 size;
1023 if (!input->ReadVarint32(&size)) return false;
1024 io::CodedInputStream::Limit limit = input->PushLimit(size);
1025
1026 switch (extension.type) {
1027 #define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \
1028 case WireFormatLite::TYPE_##UPPERCASE: \
1029 while (input->BytesUntilLimit() > 0) { \
1030 CPP_LOWERCASE value; \
1031 if (!WireFormatLite::ReadPrimitive< \
1032 CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \
1033 input, &value)) return false; \
1034 Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
1035 extension.is_packed, value, \
1036 extension.descriptor); \
1037 } \
1038 break
1039
1040 HANDLE_TYPE( INT32, Int32, int32);
1041 HANDLE_TYPE( INT64, Int64, int64);
1042 HANDLE_TYPE( UINT32, UInt32, uint32);
1043 HANDLE_TYPE( UINT64, UInt64, uint64);
1044 HANDLE_TYPE( SINT32, Int32, int32);
1045 HANDLE_TYPE( SINT64, Int64, int64);
1046 HANDLE_TYPE( FIXED32, UInt32, uint32);
1047 HANDLE_TYPE( FIXED64, UInt64, uint64);
1048 HANDLE_TYPE(SFIXED32, Int32, int32);
1049 HANDLE_TYPE(SFIXED64, Int64, int64);
1050 HANDLE_TYPE( FLOAT, Float, float);
1051 HANDLE_TYPE( DOUBLE, Double, double);
1052 HANDLE_TYPE( BOOL, Bool, bool);
1053 #undef HANDLE_TYPE
1054
1055 case WireFormatLite::TYPE_ENUM:
1056 while (input->BytesUntilLimit() > 0) {
1057 int value;
1058 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
1059 input, &value)) return false;
1060 if (extension.enum_validity_check.func(
1061 extension.enum_validity_check.arg, value)) {
1062 AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed,
1063 value, extension.descriptor);
1064 }
1065 }
1066 break;
1067
1068 case WireFormatLite::TYPE_STRING:
1069 case WireFormatLite::TYPE_BYTES:
1070 case WireFormatLite::TYPE_GROUP:
1071 case WireFormatLite::TYPE_MESSAGE:
1072 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1073 break;
1074 }
1075
1076 input->PopLimit(limit);
1077 } else {
1078 switch (extension.type) {
1079 #define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \
1080 case WireFormatLite::TYPE_##UPPERCASE: { \
1081 CPP_LOWERCASE value; \
1082 if (!WireFormatLite::ReadPrimitive< \
1083 CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \
1084 input, &value)) return false; \
1085 if (extension.is_repeated) { \
1086 Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
1087 extension.is_packed, value, \
1088 extension.descriptor); \
1089 } else { \
1090 Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \
1091 extension.descriptor); \
1092 } \
1093 } break
1094
1095 HANDLE_TYPE( INT32, Int32, int32);
1096 HANDLE_TYPE( INT64, Int64, int64);
1097 HANDLE_TYPE( UINT32, UInt32, uint32);
1098 HANDLE_TYPE( UINT64, UInt64, uint64);
1099 HANDLE_TYPE( SINT32, Int32, int32);
1100 HANDLE_TYPE( SINT64, Int64, int64);
1101 HANDLE_TYPE( FIXED32, UInt32, uint32);
1102 HANDLE_TYPE( FIXED64, UInt64, uint64);
1103 HANDLE_TYPE(SFIXED32, Int32, int32);
1104 HANDLE_TYPE(SFIXED64, Int64, int64);
1105 HANDLE_TYPE( FLOAT, Float, float);
1106 HANDLE_TYPE( DOUBLE, Double, double);
1107 HANDLE_TYPE( BOOL, Bool, bool);
1108 #undef HANDLE_TYPE
1109
1110 case WireFormatLite::TYPE_ENUM: {
1111 int value;
1112 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
1113 input, &value)) return false;
1114
1115 if (!extension.enum_validity_check.func(
1116 extension.enum_validity_check.arg, value)) {
1117 // Invalid value. Treat as unknown.
1118 field_skipper->SkipUnknownEnum(number, value);
1119 } else if (extension.is_repeated) {
1120 AddEnum(number, WireFormatLite::TYPE_ENUM, extension.is_packed, value,
1121 extension.descriptor);
1122 } else {
1123 SetEnum(number, WireFormatLite::TYPE_ENUM, value,
1124 extension.descriptor);
1125 }
1126 break;
1127 }
1128
1129 case WireFormatLite::TYPE_STRING: {
1130 string* value = extension.is_repeated ?
1131 AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) :
1132 MutableString(number, WireFormatLite::TYPE_STRING,
1133 extension.descriptor);
1134 if (!WireFormatLite::ReadString(input, value)) return false;
1135 break;
1136 }
1137
1138 case WireFormatLite::TYPE_BYTES: {
1139 string* value = extension.is_repeated ?
1140 AddString(number, WireFormatLite::TYPE_BYTES, extension.descriptor) :
1141 MutableString(number, WireFormatLite::TYPE_BYTES,
1142 extension.descriptor);
1143 if (!WireFormatLite::ReadBytes(input, value)) return false;
1144 break;
1145 }
1146
1147 case WireFormatLite::TYPE_GROUP: {
1148 MessageLite* value = extension.is_repeated ?
1149 AddMessage(number, WireFormatLite::TYPE_GROUP,
1150 *extension.message_prototype, extension.descriptor) :
1151 MutableMessage(number, WireFormatLite::TYPE_GROUP,
1152 *extension.message_prototype, extension.descriptor);
1153 if (!WireFormatLite::ReadGroup(number, input, value)) return false;
1154 break;
1155 }
1156
1157 case WireFormatLite::TYPE_MESSAGE: {
1158 MessageLite* value = extension.is_repeated ?
1159 AddMessage(number, WireFormatLite::TYPE_MESSAGE,
1160 *extension.message_prototype, extension.descriptor) :
1161 MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
1162 *extension.message_prototype, extension.descriptor);
1163 if (!WireFormatLite::ReadMessage(input, value)) return false;
1164 break;
1165 }
1166 }
1167 }
1168
1169 return true;
1170 }
1171
ParseField(uint32 tag,io::CodedInputStream * input,const MessageLite * containing_type)1172 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1173 const MessageLite* containing_type) {
1174 FieldSkipper skipper;
1175 GeneratedExtensionFinder finder(containing_type);
1176 return ParseField(tag, input, &finder, &skipper);
1177 }
1178
ParseField(uint32 tag,io::CodedInputStream * input,const MessageLite * containing_type,io::CodedOutputStream * unknown_fields)1179 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1180 const MessageLite* containing_type,
1181 io::CodedOutputStream* unknown_fields) {
1182 CodedOutputStreamFieldSkipper skipper(unknown_fields);
1183 GeneratedExtensionFinder finder(containing_type);
1184 return ParseField(tag, input, &finder, &skipper);
1185 }
1186
1187 // Defined in extension_set_heavy.cc.
1188 // bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1189 // const MessageLite* containing_type,
1190 // UnknownFieldSet* unknown_fields)
1191
1192 // Defined in extension_set_heavy.cc.
1193 // bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
1194 // const MessageLite* containing_type,
1195 // UnknownFieldSet* unknown_fields);
1196
SerializeWithCachedSizes(int start_field_number,int end_field_number,io::CodedOutputStream * output) const1197 void ExtensionSet::SerializeWithCachedSizes(
1198 int start_field_number, int end_field_number,
1199 io::CodedOutputStream* output) const {
1200 map<int, Extension>::const_iterator iter;
1201 for (iter = extensions_.lower_bound(start_field_number);
1202 iter != extensions_.end() && iter->first < end_field_number;
1203 ++iter) {
1204 iter->second.SerializeFieldWithCachedSizes(iter->first, output);
1205 }
1206 }
1207
ByteSize() const1208 int ExtensionSet::ByteSize() const {
1209 int total_size = 0;
1210
1211 for (map<int, Extension>::const_iterator iter = extensions_.begin();
1212 iter != extensions_.end(); ++iter) {
1213 total_size += iter->second.ByteSize(iter->first);
1214 }
1215
1216 return total_size;
1217 }
1218
1219 // Defined in extension_set_heavy.cc.
1220 // int ExtensionSet::SpaceUsedExcludingSelf() const
1221
MaybeNewExtension(int number,const FieldDescriptor * descriptor,Extension ** result)1222 bool ExtensionSet::MaybeNewExtension(int number,
1223 const FieldDescriptor* descriptor,
1224 Extension** result) {
1225 pair<map<int, Extension>::iterator, bool> insert_result =
1226 extensions_.insert(make_pair(number, Extension()));
1227 *result = &insert_result.first->second;
1228 (*result)->descriptor = descriptor;
1229 return insert_result.second;
1230 }
1231
1232 // ===================================================================
1233 // Methods of ExtensionSet::Extension
1234
Clear()1235 void ExtensionSet::Extension::Clear() {
1236 if (is_repeated) {
1237 switch (cpp_type(type)) {
1238 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1239 case WireFormatLite::CPPTYPE_##UPPERCASE: \
1240 repeated_##LOWERCASE##_value->Clear(); \
1241 break
1242
1243 HANDLE_TYPE( INT32, int32);
1244 HANDLE_TYPE( INT64, int64);
1245 HANDLE_TYPE( UINT32, uint32);
1246 HANDLE_TYPE( UINT64, uint64);
1247 HANDLE_TYPE( FLOAT, float);
1248 HANDLE_TYPE( DOUBLE, double);
1249 HANDLE_TYPE( BOOL, bool);
1250 HANDLE_TYPE( ENUM, enum);
1251 HANDLE_TYPE( STRING, string);
1252 HANDLE_TYPE(MESSAGE, message);
1253 #undef HANDLE_TYPE
1254 }
1255 } else {
1256 if (!is_cleared) {
1257 switch (cpp_type(type)) {
1258 case WireFormatLite::CPPTYPE_STRING:
1259 string_value->clear();
1260 break;
1261 case WireFormatLite::CPPTYPE_MESSAGE:
1262 if (is_lazy) {
1263 lazymessage_value->Clear();
1264 } else {
1265 message_value->Clear();
1266 }
1267 break;
1268 default:
1269 // No need to do anything. Get*() will return the default value
1270 // as long as is_cleared is true and Set*() will overwrite the
1271 // previous value.
1272 break;
1273 }
1274
1275 is_cleared = true;
1276 }
1277 }
1278 }
1279
SerializeFieldWithCachedSizes(int number,io::CodedOutputStream * output) const1280 void ExtensionSet::Extension::SerializeFieldWithCachedSizes(
1281 int number,
1282 io::CodedOutputStream* output) const {
1283 if (is_repeated) {
1284 if (is_packed) {
1285 if (cached_size == 0) return;
1286
1287 WireFormatLite::WriteTag(number,
1288 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
1289 output->WriteVarint32(cached_size);
1290
1291 switch (real_type(type)) {
1292 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1293 case WireFormatLite::TYPE_##UPPERCASE: \
1294 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1295 WireFormatLite::Write##CAMELCASE##NoTag( \
1296 repeated_##LOWERCASE##_value->Get(i), output); \
1297 } \
1298 break
1299
1300 HANDLE_TYPE( INT32, Int32, int32);
1301 HANDLE_TYPE( INT64, Int64, int64);
1302 HANDLE_TYPE( UINT32, UInt32, uint32);
1303 HANDLE_TYPE( UINT64, UInt64, uint64);
1304 HANDLE_TYPE( SINT32, SInt32, int32);
1305 HANDLE_TYPE( SINT64, SInt64, int64);
1306 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1307 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1308 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1309 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1310 HANDLE_TYPE( FLOAT, Float, float);
1311 HANDLE_TYPE( DOUBLE, Double, double);
1312 HANDLE_TYPE( BOOL, Bool, bool);
1313 HANDLE_TYPE( ENUM, Enum, enum);
1314 #undef HANDLE_TYPE
1315
1316 case WireFormatLite::TYPE_STRING:
1317 case WireFormatLite::TYPE_BYTES:
1318 case WireFormatLite::TYPE_GROUP:
1319 case WireFormatLite::TYPE_MESSAGE:
1320 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1321 break;
1322 }
1323 } else {
1324 switch (real_type(type)) {
1325 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1326 case WireFormatLite::TYPE_##UPPERCASE: \
1327 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1328 WireFormatLite::Write##CAMELCASE(number, \
1329 repeated_##LOWERCASE##_value->Get(i), output); \
1330 } \
1331 break
1332
1333 HANDLE_TYPE( INT32, Int32, int32);
1334 HANDLE_TYPE( INT64, Int64, int64);
1335 HANDLE_TYPE( UINT32, UInt32, uint32);
1336 HANDLE_TYPE( UINT64, UInt64, uint64);
1337 HANDLE_TYPE( SINT32, SInt32, int32);
1338 HANDLE_TYPE( SINT64, SInt64, int64);
1339 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1340 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1341 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1342 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1343 HANDLE_TYPE( FLOAT, Float, float);
1344 HANDLE_TYPE( DOUBLE, Double, double);
1345 HANDLE_TYPE( BOOL, Bool, bool);
1346 HANDLE_TYPE( STRING, String, string);
1347 HANDLE_TYPE( BYTES, Bytes, string);
1348 HANDLE_TYPE( ENUM, Enum, enum);
1349 HANDLE_TYPE( GROUP, Group, message);
1350 HANDLE_TYPE( MESSAGE, Message, message);
1351 #undef HANDLE_TYPE
1352 }
1353 }
1354 } else if (!is_cleared) {
1355 switch (real_type(type)) {
1356 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \
1357 case WireFormatLite::TYPE_##UPPERCASE: \
1358 WireFormatLite::Write##CAMELCASE(number, VALUE, output); \
1359 break
1360
1361 HANDLE_TYPE( INT32, Int32, int32_value);
1362 HANDLE_TYPE( INT64, Int64, int64_value);
1363 HANDLE_TYPE( UINT32, UInt32, uint32_value);
1364 HANDLE_TYPE( UINT64, UInt64, uint64_value);
1365 HANDLE_TYPE( SINT32, SInt32, int32_value);
1366 HANDLE_TYPE( SINT64, SInt64, int64_value);
1367 HANDLE_TYPE( FIXED32, Fixed32, uint32_value);
1368 HANDLE_TYPE( FIXED64, Fixed64, uint64_value);
1369 HANDLE_TYPE(SFIXED32, SFixed32, int32_value);
1370 HANDLE_TYPE(SFIXED64, SFixed64, int64_value);
1371 HANDLE_TYPE( FLOAT, Float, float_value);
1372 HANDLE_TYPE( DOUBLE, Double, double_value);
1373 HANDLE_TYPE( BOOL, Bool, bool_value);
1374 HANDLE_TYPE( STRING, String, *string_value);
1375 HANDLE_TYPE( BYTES, Bytes, *string_value);
1376 HANDLE_TYPE( ENUM, Enum, enum_value);
1377 HANDLE_TYPE( GROUP, Group, *message_value);
1378 #undef HANDLE_TYPE
1379 case WireFormatLite::TYPE_MESSAGE:
1380 if (is_lazy) {
1381 lazymessage_value->WriteMessage(number, output);
1382 } else {
1383 WireFormatLite::WriteMessage(number, *message_value, output);
1384 }
1385 break;
1386 }
1387 }
1388 }
1389
ByteSize(int number) const1390 int ExtensionSet::Extension::ByteSize(int number) const {
1391 int result = 0;
1392
1393 if (is_repeated) {
1394 if (is_packed) {
1395 switch (real_type(type)) {
1396 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1397 case WireFormatLite::TYPE_##UPPERCASE: \
1398 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1399 result += WireFormatLite::CAMELCASE##Size( \
1400 repeated_##LOWERCASE##_value->Get(i)); \
1401 } \
1402 break
1403
1404 HANDLE_TYPE( INT32, Int32, int32);
1405 HANDLE_TYPE( INT64, Int64, int64);
1406 HANDLE_TYPE( UINT32, UInt32, uint32);
1407 HANDLE_TYPE( UINT64, UInt64, uint64);
1408 HANDLE_TYPE( SINT32, SInt32, int32);
1409 HANDLE_TYPE( SINT64, SInt64, int64);
1410 HANDLE_TYPE( ENUM, Enum, enum);
1411 #undef HANDLE_TYPE
1412
1413 // Stuff with fixed size.
1414 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1415 case WireFormatLite::TYPE_##UPPERCASE: \
1416 result += WireFormatLite::k##CAMELCASE##Size * \
1417 repeated_##LOWERCASE##_value->size(); \
1418 break
1419 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1420 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1421 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1422 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1423 HANDLE_TYPE( FLOAT, Float, float);
1424 HANDLE_TYPE( DOUBLE, Double, double);
1425 HANDLE_TYPE( BOOL, Bool, bool);
1426 #undef HANDLE_TYPE
1427
1428 case WireFormatLite::TYPE_STRING:
1429 case WireFormatLite::TYPE_BYTES:
1430 case WireFormatLite::TYPE_GROUP:
1431 case WireFormatLite::TYPE_MESSAGE:
1432 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1433 break;
1434 }
1435
1436 cached_size = result;
1437 if (result > 0) {
1438 result += io::CodedOutputStream::VarintSize32(result);
1439 result += io::CodedOutputStream::VarintSize32(
1440 WireFormatLite::MakeTag(number,
1441 WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
1442 }
1443 } else {
1444 int tag_size = WireFormatLite::TagSize(number, real_type(type));
1445
1446 switch (real_type(type)) {
1447 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1448 case WireFormatLite::TYPE_##UPPERCASE: \
1449 result += tag_size * repeated_##LOWERCASE##_value->size(); \
1450 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1451 result += WireFormatLite::CAMELCASE##Size( \
1452 repeated_##LOWERCASE##_value->Get(i)); \
1453 } \
1454 break
1455
1456 HANDLE_TYPE( INT32, Int32, int32);
1457 HANDLE_TYPE( INT64, Int64, int64);
1458 HANDLE_TYPE( UINT32, UInt32, uint32);
1459 HANDLE_TYPE( UINT64, UInt64, uint64);
1460 HANDLE_TYPE( SINT32, SInt32, int32);
1461 HANDLE_TYPE( SINT64, SInt64, int64);
1462 HANDLE_TYPE( STRING, String, string);
1463 HANDLE_TYPE( BYTES, Bytes, string);
1464 HANDLE_TYPE( ENUM, Enum, enum);
1465 HANDLE_TYPE( GROUP, Group, message);
1466 HANDLE_TYPE( MESSAGE, Message, message);
1467 #undef HANDLE_TYPE
1468
1469 // Stuff with fixed size.
1470 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1471 case WireFormatLite::TYPE_##UPPERCASE: \
1472 result += (tag_size + WireFormatLite::k##CAMELCASE##Size) * \
1473 repeated_##LOWERCASE##_value->size(); \
1474 break
1475 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1476 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1477 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1478 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1479 HANDLE_TYPE( FLOAT, Float, float);
1480 HANDLE_TYPE( DOUBLE, Double, double);
1481 HANDLE_TYPE( BOOL, Bool, bool);
1482 #undef HANDLE_TYPE
1483 }
1484 }
1485 } else if (!is_cleared) {
1486 result += WireFormatLite::TagSize(number, real_type(type));
1487 switch (real_type(type)) {
1488 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1489 case WireFormatLite::TYPE_##UPPERCASE: \
1490 result += WireFormatLite::CAMELCASE##Size(LOWERCASE); \
1491 break
1492
1493 HANDLE_TYPE( INT32, Int32, int32_value);
1494 HANDLE_TYPE( INT64, Int64, int64_value);
1495 HANDLE_TYPE( UINT32, UInt32, uint32_value);
1496 HANDLE_TYPE( UINT64, UInt64, uint64_value);
1497 HANDLE_TYPE( SINT32, SInt32, int32_value);
1498 HANDLE_TYPE( SINT64, SInt64, int64_value);
1499 HANDLE_TYPE( STRING, String, *string_value);
1500 HANDLE_TYPE( BYTES, Bytes, *string_value);
1501 HANDLE_TYPE( ENUM, Enum, enum_value);
1502 HANDLE_TYPE( GROUP, Group, *message_value);
1503 #undef HANDLE_TYPE
1504 case WireFormatLite::TYPE_MESSAGE: {
1505 if (is_lazy) {
1506 int size = lazymessage_value->ByteSize();
1507 result += io::CodedOutputStream::VarintSize32(size) + size;
1508 } else {
1509 result += WireFormatLite::MessageSize(*message_value);
1510 }
1511 break;
1512 }
1513
1514 // Stuff with fixed size.
1515 #define HANDLE_TYPE(UPPERCASE, CAMELCASE) \
1516 case WireFormatLite::TYPE_##UPPERCASE: \
1517 result += WireFormatLite::k##CAMELCASE##Size; \
1518 break
1519 HANDLE_TYPE( FIXED32, Fixed32);
1520 HANDLE_TYPE( FIXED64, Fixed64);
1521 HANDLE_TYPE(SFIXED32, SFixed32);
1522 HANDLE_TYPE(SFIXED64, SFixed64);
1523 HANDLE_TYPE( FLOAT, Float);
1524 HANDLE_TYPE( DOUBLE, Double);
1525 HANDLE_TYPE( BOOL, Bool);
1526 #undef HANDLE_TYPE
1527 }
1528 }
1529
1530 return result;
1531 }
1532
GetSize() const1533 int ExtensionSet::Extension::GetSize() const {
1534 GOOGLE_DCHECK(is_repeated);
1535 switch (cpp_type(type)) {
1536 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1537 case WireFormatLite::CPPTYPE_##UPPERCASE: \
1538 return repeated_##LOWERCASE##_value->size()
1539
1540 HANDLE_TYPE( INT32, int32);
1541 HANDLE_TYPE( INT64, int64);
1542 HANDLE_TYPE( UINT32, uint32);
1543 HANDLE_TYPE( UINT64, uint64);
1544 HANDLE_TYPE( FLOAT, float);
1545 HANDLE_TYPE( DOUBLE, double);
1546 HANDLE_TYPE( BOOL, bool);
1547 HANDLE_TYPE( ENUM, enum);
1548 HANDLE_TYPE( STRING, string);
1549 HANDLE_TYPE(MESSAGE, message);
1550 #undef HANDLE_TYPE
1551 }
1552
1553 GOOGLE_LOG(FATAL) << "Can't get here.";
1554 return 0;
1555 }
1556
Free()1557 void ExtensionSet::Extension::Free() {
1558 if (is_repeated) {
1559 switch (cpp_type(type)) {
1560 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1561 case WireFormatLite::CPPTYPE_##UPPERCASE: \
1562 delete repeated_##LOWERCASE##_value; \
1563 break
1564
1565 HANDLE_TYPE( INT32, int32);
1566 HANDLE_TYPE( INT64, int64);
1567 HANDLE_TYPE( UINT32, uint32);
1568 HANDLE_TYPE( UINT64, uint64);
1569 HANDLE_TYPE( FLOAT, float);
1570 HANDLE_TYPE( DOUBLE, double);
1571 HANDLE_TYPE( BOOL, bool);
1572 HANDLE_TYPE( ENUM, enum);
1573 HANDLE_TYPE( STRING, string);
1574 HANDLE_TYPE(MESSAGE, message);
1575 #undef HANDLE_TYPE
1576 }
1577 } else {
1578 switch (cpp_type(type)) {
1579 case WireFormatLite::CPPTYPE_STRING:
1580 delete string_value;
1581 break;
1582 case WireFormatLite::CPPTYPE_MESSAGE:
1583 if (is_lazy) {
1584 delete lazymessage_value;
1585 } else {
1586 delete message_value;
1587 }
1588 break;
1589 default:
1590 break;
1591 }
1592 }
1593 }
1594
1595 // Defined in extension_set_heavy.cc.
1596 // int ExtensionSet::Extension::SpaceUsedExcludingSelf() const
1597
1598 // ==================================================================
1599 // Default repeated field instances for iterator-compatible accessors
1600
1601 const RepeatedStringTypeTraits::RepeatedFieldType*
1602 RepeatedStringTypeTraits::default_repeated_field_ = NULL;
1603
1604 const RepeatedMessageGenericTypeTraits::RepeatedFieldType*
1605 RepeatedMessageGenericTypeTraits::default_repeated_field_ = NULL;
1606
1607 #define PROTOBUF_DEFINE_DEFAULT_REPEATED(TYPE) \
1608 const RepeatedField<TYPE>* \
1609 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_##TYPE##_ = NULL;
1610
1611 PROTOBUF_DEFINE_DEFAULT_REPEATED(int32)
1612 PROTOBUF_DEFINE_DEFAULT_REPEATED(int64)
1613 PROTOBUF_DEFINE_DEFAULT_REPEATED(uint32)
1614 PROTOBUF_DEFINE_DEFAULT_REPEATED(uint64)
1615 PROTOBUF_DEFINE_DEFAULT_REPEATED(double)
1616 PROTOBUF_DEFINE_DEFAULT_REPEATED(float)
1617 PROTOBUF_DEFINE_DEFAULT_REPEATED(bool)
1618
1619 #undef PROTOBUF_DEFINE_DEFAULT_REPEATED
1620
1621 struct StaticDefaultRepeatedFieldsInitializer {
StaticDefaultRepeatedFieldsInitializergoogle::protobuf::internal::StaticDefaultRepeatedFieldsInitializer1622 StaticDefaultRepeatedFieldsInitializer() {
1623 InitializeDefaultRepeatedFields();
1624 OnShutdown(&DestroyDefaultRepeatedFields);
1625 }
1626 } static_repeated_fields_initializer;
1627
InitializeDefaultRepeatedFields()1628 void InitializeDefaultRepeatedFields() {
1629 RepeatedStringTypeTraits::default_repeated_field_ =
1630 new RepeatedStringTypeTraits::RepeatedFieldType;
1631 RepeatedMessageGenericTypeTraits::default_repeated_field_ =
1632 new RepeatedMessageGenericTypeTraits::RepeatedFieldType;
1633 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int32_ =
1634 new RepeatedField<int32>;
1635 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int64_ =
1636 new RepeatedField<int64>;
1637 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint32_ =
1638 new RepeatedField<uint32>;
1639 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint64_ =
1640 new RepeatedField<uint64>;
1641 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_double_ =
1642 new RepeatedField<double>;
1643 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_float_ =
1644 new RepeatedField<float>;
1645 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_bool_ =
1646 new RepeatedField<bool>;
1647 }
1648
DestroyDefaultRepeatedFields()1649 void DestroyDefaultRepeatedFields() {
1650 delete RepeatedStringTypeTraits::default_repeated_field_;
1651 delete RepeatedMessageGenericTypeTraits::default_repeated_field_;
1652 delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int32_;
1653 delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_int64_;
1654 delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint32_;
1655 delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_uint64_;
1656 delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_double_;
1657 delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_float_;
1658 delete RepeatedPrimitiveGenericTypeTraits::default_repeated_field_bool_;
1659 }
1660
1661 } // namespace internal
1662 } // namespace protobuf
1663 } // namespace google
1664