1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
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
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.
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.
31 // Author: kenton@google.com (Kenton Varda)
32 // Based on original Protocol Buffers design by
33 // Sanjay Ghemawat, Jeff Dean, and others.
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>
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);
56 inline WireFormatLite::CppType cpp_type(FieldType type) {
57 return WireFormatLite::FieldTypeToCppType(real_type(type));
60 inline bool is_packable(WireFormatLite::WireType type) {
62 case WireFormatLite::WIRETYPE_VARINT:
63 case WireFormatLite::WIRETYPE_FIXED64:
64 case WireFormatLite::WIRETYPE_FIXED32:
66 case WireFormatLite::WIRETYPE_LENGTH_DELIMITED:
67 case WireFormatLite::WIRETYPE_START_GROUP:
68 case WireFormatLite::WIRETYPE_END_GROUP:
71 // Do not add a default statement. Let the compiler complain when someone
72 // adds a new wire type.
77 typedef hash_map<pair<const MessageLite*, int>,
78 ExtensionInfo> ExtensionRegistry;
79 ExtensionRegistry* registry_ = NULL;
80 GOOGLE_PROTOBUF_DECLARE_ONCE(registry_init_);
82 void DeleteRegistry() {
88 registry_ = new ExtensionRegistry;
89 OnShutdown(&DeleteRegistry);
92 // This function is only called at startup, so there is no need for thread-
94 void Register(const MessageLite* containing_type,
95 int number, ExtensionInfo info) {
96 ::google::protobuf::GoogleOnceInit(®istry_init_, &InitRegistry);
98 if (!InsertIfNotPresent(registry_, make_pair(containing_type, number),
100 GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \""
101 << containing_type->GetTypeName()
102 << "\", field number " << 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));
114 ExtensionFinder::~ExtensionFinder() {}
116 bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) {
117 const ExtensionInfo* extension =
118 FindRegisteredExtension(containing_type_, number);
119 if (extension == NULL) {
122 *output = *extension;
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);
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);
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);
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);
174 // ===================================================================
175 // Constructors and basic methods.
177 ExtensionSet::ExtensionSet() {}
179 ExtensionSet::~ExtensionSet() {
180 for (map<int, Extension>::iterator iter = extensions_.begin();
181 iter != extensions_.end(); ++iter) {
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
191 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;
198 int ExtensionSet::NumExtensions() const {
200 for (map<int, Extension>::const_iterator iter = extensions_.begin();
201 iter != extensions_.end(); ++iter) {
202 if (!iter->second.is_cleared) {
209 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();
215 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). ";
221 if (iter->second.is_cleared) {
222 GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (2). ";
224 return iter->second.type;
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();
233 // ===================================================================
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)
249 // -------------------------------------------------------------------
252 #define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE) \
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; \
260 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, UPPERCASE); \
261 return iter->second.LOWERCASE##_value; \
265 void ExtensionSet::Set##CAMELCASE(int number, FieldType type, \
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; \
274 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, UPPERCASE); \
276 extension->is_cleared = false; \
277 extension->LOWERCASE##_value = value; \
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); \
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); \
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>(); \
306 GOOGLE_DCHECK_TYPE(*extension, REPEATED, UPPERCASE); \
307 GOOGLE_DCHECK_EQ(extension->is_packed, packed); \
309 extension->repeated_##LOWERCASE##_value->Add(value); \
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)
320 #undef PRIMITIVE_ACCESSORS
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;
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;
333 void* ExtensionSet::MutableRawRepeatedField(int number, FieldType field_type,
335 const FieldDescriptor* desc) {
336 Extension* extension;
338 // We instantiate an empty Repeated{,Ptr}Field if one doesn't exist for this
340 if (MaybeNewExtension(number, desc, &extension)) {
341 extension->is_repeated = true;
342 extension->type = field_type;
343 extension->is_packed = packed;
345 switch (WireFormatLite::FieldTypeToCppType(
346 static_cast<WireFormatLite::FieldType>(field_type))) {
347 case WireFormatLite::CPPTYPE_INT32:
348 extension->repeated_int32_value = new RepeatedField<int32>();
350 case WireFormatLite::CPPTYPE_INT64:
351 extension->repeated_int64_value = new RepeatedField<int64>();
353 case WireFormatLite::CPPTYPE_UINT32:
354 extension->repeated_uint32_value = new RepeatedField<uint32>();
356 case WireFormatLite::CPPTYPE_UINT64:
357 extension->repeated_uint64_value = new RepeatedField<uint64>();
359 case WireFormatLite::CPPTYPE_DOUBLE:
360 extension->repeated_double_value = new RepeatedField<double>();
362 case WireFormatLite::CPPTYPE_FLOAT:
363 extension->repeated_float_value = new RepeatedField<float>();
365 case WireFormatLite::CPPTYPE_BOOL:
366 extension->repeated_bool_value = new RepeatedField<bool>();
368 case WireFormatLite::CPPTYPE_ENUM:
369 extension->repeated_enum_value = new RepeatedField<int>();
371 case WireFormatLite::CPPTYPE_STRING:
372 extension->repeated_string_value = new RepeatedPtrField< ::std::string>();
374 case WireFormatLite::CPPTYPE_MESSAGE:
375 extension->repeated_message_value = new RepeatedPtrField<MessageLite>();
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;
385 // Compatible version using old call signature. Does not create extensions when
386 // the don't already exist; instead, just GOOGLE_CHECK-fails.
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;
396 // -------------------------------------------------------------------
399 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;
405 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, ENUM);
406 return iter->second.enum_value;
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;
418 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, ENUM);
420 extension->is_cleared = false;
421 extension->enum_value = value;
424 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);
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);
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>();
449 GOOGLE_DCHECK_TYPE(*extension, REPEATED, ENUM);
450 GOOGLE_DCHECK_EQ(extension->is_packed, packed);
452 extension->repeated_enum_value->Add(value);
455 // -------------------------------------------------------------------
458 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;
465 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, STRING);
466 return *iter->second.string_value;
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;
479 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, STRING);
481 extension->is_cleared = false;
482 return extension->string_value;
485 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);
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);
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>();
509 GOOGLE_DCHECK_TYPE(*extension, REPEATED, STRING);
511 return extension->repeated_string_value->Add();
514 // -------------------------------------------------------------------
517 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;
524 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
525 if (iter->second.is_lazy) {
526 return iter->second.lazymessage_value->GetMessage(default_value);
528 return *iter->second.message_value;
533 // Defined in extension_set_heavy.cc.
534 // const MessageLite& ExtensionSet::GetMessage(int number,
535 // const Descriptor* message_type,
536 // MessageFactory* factory) const
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;
551 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
552 extension->is_cleared = false;
553 if (extension->is_lazy) {
554 return extension->lazymessage_value->MutableMessage(prototype);
556 return extension->message_value;
561 // Defined in extension_set_heavy.cc.
562 // MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
563 // const Descriptor* message_type,
564 // MessageFactory* factory)
566 void ExtensionSet::SetAllocatedMessage(int number, FieldType type,
567 const FieldDescriptor* descriptor,
568 MessageLite* message) {
569 if (message == NULL) {
570 ClearExtension(number);
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;
581 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
582 if (extension->is_lazy) {
583 extension->lazymessage_value->SetAllocatedMessage(message);
585 delete extension->message_value;
586 extension->message_value = message;
589 extension->is_cleared = false;
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.
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;
605 ret = iter->second.message_value;
607 extensions_.erase(number);
612 // Defined in extension_set_heavy.cc.
613 // MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
614 // MessageFactory* factory);
616 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);
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);
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>();
642 GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
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);
656 // Defined in extension_set_heavy.cc.
657 // MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
658 // const Descriptor* message_type,
659 // MessageFactory* factory)
661 #undef GOOGLE_DCHECK_TYPE
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).";
667 Extension* extension = &iter->second;
668 GOOGLE_DCHECK(extension->is_repeated);
670 switch(cpp_type(extension->type)) {
671 case WireFormatLite::CPPTYPE_INT32:
672 extension->repeated_int32_value->RemoveLast();
674 case WireFormatLite::CPPTYPE_INT64:
675 extension->repeated_int64_value->RemoveLast();
677 case WireFormatLite::CPPTYPE_UINT32:
678 extension->repeated_uint32_value->RemoveLast();
680 case WireFormatLite::CPPTYPE_UINT64:
681 extension->repeated_uint64_value->RemoveLast();
683 case WireFormatLite::CPPTYPE_FLOAT:
684 extension->repeated_float_value->RemoveLast();
686 case WireFormatLite::CPPTYPE_DOUBLE:
687 extension->repeated_double_value->RemoveLast();
689 case WireFormatLite::CPPTYPE_BOOL:
690 extension->repeated_bool_value->RemoveLast();
692 case WireFormatLite::CPPTYPE_ENUM:
693 extension->repeated_enum_value->RemoveLast();
695 case WireFormatLite::CPPTYPE_STRING:
696 extension->repeated_string_value->RemoveLast();
698 case WireFormatLite::CPPTYPE_MESSAGE:
699 extension->repeated_message_value->RemoveLast();
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).";
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();
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).";
718 Extension* extension = &iter->second;
719 GOOGLE_DCHECK(extension->is_repeated);
721 switch(cpp_type(extension->type)) {
722 case WireFormatLite::CPPTYPE_INT32:
723 extension->repeated_int32_value->SwapElements(index1, index2);
725 case WireFormatLite::CPPTYPE_INT64:
726 extension->repeated_int64_value->SwapElements(index1, index2);
728 case WireFormatLite::CPPTYPE_UINT32:
729 extension->repeated_uint32_value->SwapElements(index1, index2);
731 case WireFormatLite::CPPTYPE_UINT64:
732 extension->repeated_uint64_value->SwapElements(index1, index2);
734 case WireFormatLite::CPPTYPE_FLOAT:
735 extension->repeated_float_value->SwapElements(index1, index2);
737 case WireFormatLite::CPPTYPE_DOUBLE:
738 extension->repeated_double_value->SwapElements(index1, index2);
740 case WireFormatLite::CPPTYPE_BOOL:
741 extension->repeated_bool_value->SwapElements(index1, index2);
743 case WireFormatLite::CPPTYPE_ENUM:
744 extension->repeated_enum_value->SwapElements(index1, index2);
746 case WireFormatLite::CPPTYPE_STRING:
747 extension->repeated_string_value->SwapElements(index1, index2);
749 case WireFormatLite::CPPTYPE_MESSAGE:
750 extension->repeated_message_value->SwapElements(index1, index2);
755 // ===================================================================
757 void ExtensionSet::Clear() {
758 for (map<int, Extension>::iterator iter = extensions_.begin();
759 iter != extensions_.end(); ++iter) {
760 iter->second.Clear();
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;
769 if (other_extension.is_repeated) {
770 Extension* extension;
771 bool is_new = MaybeNewExtension(iter->first, other_extension.descriptor,
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;
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);
784 switch (cpp_type(other_extension.type)) {
785 #define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE) \
786 case WireFormatLite::CPPTYPE_##UPPERCASE: \
788 extension->repeated_##LOWERCASE##_value = \
791 extension->repeated_##LOWERCASE##_value->MergeFrom( \
792 *other_extension.repeated_##LOWERCASE##_value); \
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>);
806 case WireFormatLite::CPPTYPE_MESSAGE:
808 extension->repeated_message_value =
809 new RepeatedPtrField<MessageLite>();
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);
823 target->CheckTypeAndMergeFrom(other_message);
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); \
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);
846 case WireFormatLite::CPPTYPE_STRING:
847 SetString(iter->first, other_extension.type,
848 *other_extension.string_value,
849 other_extension.descriptor);
851 case WireFormatLite::CPPTYPE_MESSAGE: {
852 Extension* extension;
853 bool is_new = MaybeNewExtension(iter->first,
854 other_extension.descriptor,
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);
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);
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);
882 extension->message_value->CheckTypeAndMergeFrom(
883 other_extension.lazymessage_value->GetMessage(
884 *extension->message_value));
887 if (extension->is_lazy) {
888 extension->lazymessage_value->MutableMessage(
889 *other_extension.message_value)->CheckTypeAndMergeFrom(
890 *other_extension.message_value);
892 extension->message_value->CheckTypeAndMergeFrom(
893 *other_extension.message_value);
897 extension->is_cleared = false;
906 void ExtensionSet::Swap(ExtensionSet* x) {
907 extensions_.swap(x->extensions_);
910 void ExtensionSet::SwapExtension(ExtensionSet* other,
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);
916 if (this_iter == extensions_.end() &&
917 other_iter == other->extensions_.end()) {
921 if (this_iter != extensions_.end() &&
922 other_iter != other->extensions_.end()) {
923 std::swap(this_iter->second, other_iter->second);
927 if (this_iter == extensions_.end()) {
928 extensions_.insert(make_pair(number, other_iter->second));
929 other->extensions_.erase(number);
933 if (other_iter == other->extensions_.end()) {
934 other->extensions_.insert(make_pair(number, this_iter->second));
935 extensions_.erase(number);
940 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()) {
954 if (!extension.is_cleared) {
955 if (extension.is_lazy) {
956 if (!extension.lazymessage_value->IsInitialized()) return false;
958 if (!extension.message_value->IsInitialized()) return false;
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,
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)) {
985 WireFormatLite::WireType expected_wire_type =
986 WireFormatLite::WireTypeForFieldType(real_type(extension->type));
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;
996 // Otherwise the wire type must match.
997 return expected_wire_type == wire_type;
1000 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1001 ExtensionFinder* extension_finder,
1002 FieldSkipper* field_skipper) {
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);
1010 return ParseFieldWithExtensionInfo(
1011 number, was_packed_on_wire, extension, input, 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) {
1023 if (!input->ReadVarint32(&size)) return false;
1024 io::CodedInputStream::Limit limit = input->PushLimit(size);
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); \
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);
1055 case WireFormatLite::TYPE_ENUM:
1056 while (input->BytesUntilLimit() > 0) {
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);
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.";
1076 input->PopLimit(limit);
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); \
1090 Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \
1091 extension.descriptor); \
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);
1110 case WireFormatLite::TYPE_ENUM: {
1112 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
1113 input, &value)) return false;
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);
1123 SetEnum(number, WireFormatLite::TYPE_ENUM, value,
1124 extension.descriptor);
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;
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;
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;
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;
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);
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);
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)
1192 // Defined in extension_set_heavy.cc.
1193 // bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
1194 // const MessageLite* containing_type,
1195 // UnknownFieldSet* unknown_fields);
1197 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;
1204 iter->second.SerializeFieldWithCachedSizes(iter->first, output);
1208 int ExtensionSet::ByteSize() const {
1211 for (map<int, Extension>::const_iterator iter = extensions_.begin();
1212 iter != extensions_.end(); ++iter) {
1213 total_size += iter->second.ByteSize(iter->first);
1219 // Defined in extension_set_heavy.cc.
1220 // int ExtensionSet::SpaceUsedExcludingSelf() const
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;
1232 // ===================================================================
1233 // Methods of ExtensionSet::Extension
1235 void ExtensionSet::Extension::Clear() {
1237 switch (cpp_type(type)) {
1238 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1239 case WireFormatLite::CPPTYPE_##UPPERCASE: \
1240 repeated_##LOWERCASE##_value->Clear(); \
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);
1257 switch (cpp_type(type)) {
1258 case WireFormatLite::CPPTYPE_STRING:
1259 string_value->clear();
1261 case WireFormatLite::CPPTYPE_MESSAGE:
1263 lazymessage_value->Clear();
1265 message_value->Clear();
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
1280 void ExtensionSet::Extension::SerializeFieldWithCachedSizes(
1282 io::CodedOutputStream* output) const {
1285 if (cached_size == 0) return;
1287 WireFormatLite::WriteTag(number,
1288 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
1289 output->WriteVarint32(cached_size);
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); \
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);
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.";
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); \
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);
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); \
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);
1379 case WireFormatLite::TYPE_MESSAGE:
1381 lazymessage_value->WriteMessage(number, output);
1383 WireFormatLite::WriteMessage(number, *message_value, output);
1390 int ExtensionSet::Extension::ByteSize(int number) const {
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)); \
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);
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(); \
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);
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.";
1436 cached_size = result;
1438 result += io::CodedOutputStream::VarintSize32(result);
1439 result += io::CodedOutputStream::VarintSize32(
1440 WireFormatLite::MakeTag(number,
1441 WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
1444 int tag_size = WireFormatLite::TagSize(number, real_type(type));
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)); \
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);
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(); \
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);
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); \
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);
1504 case WireFormatLite::TYPE_MESSAGE: {
1506 int size = lazymessage_value->ByteSize();
1507 result += io::CodedOutputStream::VarintSize32(size) + size;
1509 result += WireFormatLite::MessageSize(*message_value);
1514 // Stuff with fixed size.
1515 #define HANDLE_TYPE(UPPERCASE, CAMELCASE) \
1516 case WireFormatLite::TYPE_##UPPERCASE: \
1517 result += WireFormatLite::k##CAMELCASE##Size; \
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);
1533 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()
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);
1553 GOOGLE_LOG(FATAL) << "Can't get here.";
1557 void ExtensionSet::Extension::Free() {
1559 switch (cpp_type(type)) {
1560 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1561 case WireFormatLite::CPPTYPE_##UPPERCASE: \
1562 delete repeated_##LOWERCASE##_value; \
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);
1578 switch (cpp_type(type)) {
1579 case WireFormatLite::CPPTYPE_STRING:
1580 delete string_value;
1582 case WireFormatLite::CPPTYPE_MESSAGE:
1584 delete lazymessage_value;
1586 delete message_value;
1595 // Defined in extension_set_heavy.cc.
1596 // int ExtensionSet::Extension::SpaceUsedExcludingSelf() const
1598 // ==================================================================
1599 // Default repeated field instances for iterator-compatible accessors
1601 const RepeatedStringTypeTraits::RepeatedFieldType*
1602 RepeatedStringTypeTraits::default_repeated_field_ = NULL;
1604 const RepeatedMessageGenericTypeTraits::RepeatedFieldType*
1605 RepeatedMessageGenericTypeTraits::default_repeated_field_ = NULL;
1607 #define PROTOBUF_DEFINE_DEFAULT_REPEATED(TYPE) \
1608 const RepeatedField<TYPE>* \
1609 RepeatedPrimitiveGenericTypeTraits::default_repeated_field_##TYPE##_ = NULL;
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)
1619 #undef PROTOBUF_DEFINE_DEFAULT_REPEATED
1621 struct StaticDefaultRepeatedFieldsInitializer {
1622 StaticDefaultRepeatedFieldsInitializer() {
1623 InitializeDefaultRepeatedFields();
1624 OnShutdown(&DestroyDefaultRepeatedFields);
1626 } static_repeated_fields_initializer;
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>;
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_;
1661 } // namespace internal
1662 } // namespace protobuf
1663 } // namespace google