1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2008 Google Inc. All rights reserved.
3 // http://code.google.com/p/protobuf/
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/io/zero_copy_stream_impl.h>
42 #include <google/protobuf/wire_format_lite_inl.h>
43 #include <google/protobuf/repeated_field.h>
44 #include <google/protobuf/stubs/map-util.h>
52 inline WireFormatLite::FieldType real_type(FieldType type) {
53 GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE);
54 return static_cast<WireFormatLite::FieldType>(type);
57 inline WireFormatLite::CppType cpp_type(FieldType type) {
58 return WireFormatLite::FieldTypeToCppType(real_type(type));
62 typedef hash_map<pair<const MessageLite*, int>,
63 ExtensionInfo> ExtensionRegistry;
64 ExtensionRegistry* registry_ = NULL;
65 GOOGLE_PROTOBUF_DECLARE_ONCE(registry_init_);
67 void DeleteRegistry() {
73 registry_ = new ExtensionRegistry;
74 OnShutdown(&DeleteRegistry);
77 // This function is only called at startup, so there is no need for thread-
79 void Register(const MessageLite* containing_type,
80 int number, ExtensionInfo info) {
81 ::google::protobuf::GoogleOnceInit(®istry_init_, &InitRegistry);
83 if (!InsertIfNotPresent(registry_, make_pair(containing_type, number),
85 GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \""
86 << containing_type->GetTypeName()
87 << "\", field number " << number << ".";
91 const ExtensionInfo* FindRegisteredExtension(
92 const MessageLite* containing_type, int number) {
93 return (registry_ == NULL) ? NULL :
94 FindOrNull(*registry_, make_pair(containing_type, number));
99 ExtensionFinder::~ExtensionFinder() {}
101 bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) {
102 const ExtensionInfo* extension =
103 FindRegisteredExtension(containing_type_, number);
104 if (extension == NULL) {
107 *output = *extension;
112 void ExtensionSet::RegisterExtension(const MessageLite* containing_type,
113 int number, FieldType type,
114 bool is_repeated, bool is_packed) {
115 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_ENUM);
116 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_MESSAGE);
117 GOOGLE_CHECK_NE(type, WireFormatLite::TYPE_GROUP);
118 ExtensionInfo info(type, is_repeated, is_packed);
119 Register(containing_type, number, info);
122 static bool CallNoArgValidityFunc(const void* arg, int number) {
123 // Note: Must use C-style cast here rather than reinterpret_cast because
124 // the C++ standard at one point did not allow casts between function and
125 // data pointers and some compilers enforce this for C++-style casts. No
126 // compiler enforces it for C-style casts since lots of C-style code has
127 // relied on these kinds of casts for a long time, despite being
128 // technically undefined. See:
129 // http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#195
130 // Also note: Some compilers do not allow function pointers to be "const".
131 // Which makes sense, I suppose, because it's meaningless.
132 return ((EnumValidityFunc*)arg)(number);
135 void ExtensionSet::RegisterEnumExtension(const MessageLite* containing_type,
136 int number, FieldType type,
137 bool is_repeated, bool is_packed,
138 EnumValidityFunc* is_valid) {
139 GOOGLE_CHECK_EQ(type, WireFormatLite::TYPE_ENUM);
140 ExtensionInfo info(type, is_repeated, is_packed);
141 info.enum_validity_check.func = CallNoArgValidityFunc;
142 // See comment in CallNoArgValidityFunc() about why we use a c-style cast.
143 info.enum_validity_check.arg = (void*)is_valid;
144 Register(containing_type, number, info);
147 void ExtensionSet::RegisterMessageExtension(const MessageLite* containing_type,
148 int number, FieldType type,
149 bool is_repeated, bool is_packed,
150 const MessageLite* prototype) {
151 GOOGLE_CHECK(type == WireFormatLite::TYPE_MESSAGE ||
152 type == WireFormatLite::TYPE_GROUP);
153 ExtensionInfo info(type, is_repeated, is_packed);
154 info.message_prototype = prototype;
155 Register(containing_type, number, info);
159 // ===================================================================
160 // Constructors and basic methods.
162 ExtensionSet::ExtensionSet() {}
164 ExtensionSet::~ExtensionSet() {
165 for (map<int, Extension>::iterator iter = extensions_.begin();
166 iter != extensions_.end(); ++iter) {
171 // Defined in extension_set_heavy.cc.
172 // void ExtensionSet::AppendToList(const Descriptor* containing_type,
173 // const DescriptorPool* pool,
174 // vector<const FieldDescriptor*>* output) const
176 bool ExtensionSet::Has(int number) const {
177 map<int, Extension>::const_iterator iter = extensions_.find(number);
178 if (iter == extensions_.end()) return false;
179 GOOGLE_DCHECK(!iter->second.is_repeated);
180 return !iter->second.is_cleared;
183 int ExtensionSet::NumExtensions() const {
185 for (map<int, Extension>::const_iterator iter = extensions_.begin();
186 iter != extensions_.end(); ++iter) {
187 if (!iter->second.is_cleared) {
194 int ExtensionSet::ExtensionSize(int number) const {
195 map<int, Extension>::const_iterator iter = extensions_.find(number);
196 if (iter == extensions_.end()) return false;
197 return iter->second.GetSize();
200 FieldType ExtensionSet::ExtensionType(int number) const {
201 map<int, Extension>::const_iterator iter = extensions_.find(number);
202 if (iter == extensions_.end()) {
203 GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (1). ";
206 if (iter->second.is_cleared) {
207 GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (2). ";
209 return iter->second.type;
212 void ExtensionSet::ClearExtension(int number) {
213 map<int, Extension>::iterator iter = extensions_.find(number);
214 if (iter == extensions_.end()) return;
215 iter->second.Clear();
218 // ===================================================================
230 #define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE) \
231 GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? REPEATED : OPTIONAL, LABEL); \
232 GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), WireFormatLite::CPPTYPE_##CPPTYPE)
234 // -------------------------------------------------------------------
237 #define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE) \
239 LOWERCASE ExtensionSet::Get##CAMELCASE(int number, \
240 LOWERCASE default_value) const { \
241 map<int, Extension>::const_iterator iter = extensions_.find(number); \
242 if (iter == extensions_.end() || iter->second.is_cleared) { \
243 return default_value; \
245 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, UPPERCASE); \
246 return iter->second.LOWERCASE##_value; \
250 void ExtensionSet::Set##CAMELCASE(int number, FieldType type, \
252 const FieldDescriptor* descriptor) { \
253 Extension* extension; \
254 if (MaybeNewExtension(number, descriptor, &extension)) { \
255 extension->type = type; \
256 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
257 extension->is_repeated = false; \
259 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, UPPERCASE); \
261 extension->is_cleared = false; \
262 extension->LOWERCASE##_value = value; \
265 LOWERCASE ExtensionSet::GetRepeated##CAMELCASE(int number, int index) const { \
266 map<int, Extension>::const_iterator iter = extensions_.find(number); \
267 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
268 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \
269 return iter->second.repeated_##LOWERCASE##_value->Get(index); \
272 void ExtensionSet::SetRepeated##CAMELCASE( \
273 int number, int index, LOWERCASE value) { \
274 map<int, Extension>::iterator iter = extensions_.find(number); \
275 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty)."; \
276 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, UPPERCASE); \
277 iter->second.repeated_##LOWERCASE##_value->Set(index, value); \
280 void ExtensionSet::Add##CAMELCASE(int number, FieldType type, \
281 bool packed, LOWERCASE value, \
282 const FieldDescriptor* descriptor) { \
283 Extension* extension; \
284 if (MaybeNewExtension(number, descriptor, &extension)) { \
285 extension->type = type; \
286 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_##UPPERCASE); \
287 extension->is_repeated = true; \
288 extension->is_packed = packed; \
289 extension->repeated_##LOWERCASE##_value = new RepeatedField<LOWERCASE>(); \
291 GOOGLE_DCHECK_TYPE(*extension, REPEATED, UPPERCASE); \
292 GOOGLE_DCHECK_EQ(extension->is_packed, packed); \
294 extension->repeated_##LOWERCASE##_value->Add(value); \
297 PRIMITIVE_ACCESSORS( INT32, int32, Int32)
298 PRIMITIVE_ACCESSORS( INT64, int64, Int64)
299 PRIMITIVE_ACCESSORS(UINT32, uint32, UInt32)
300 PRIMITIVE_ACCESSORS(UINT64, uint64, UInt64)
301 PRIMITIVE_ACCESSORS( FLOAT, float, Float)
302 PRIMITIVE_ACCESSORS(DOUBLE, double, Double)
303 PRIMITIVE_ACCESSORS( BOOL, bool, Bool)
305 #undef PRIMITIVE_ACCESSORS
307 void* ExtensionSet::MutableRawRepeatedField(int number) {
308 // We assume that all the RepeatedField<>* pointers have the same
309 // size and alignment within the anonymous union in Extension.
310 map<int, Extension>::const_iterator iter = extensions_.find(number);
311 GOOGLE_CHECK(iter != extensions_.end()) << "no extension numbered " << number;
312 return iter->second.repeated_int32_value;
315 // -------------------------------------------------------------------
318 int ExtensionSet::GetEnum(int number, int default_value) const {
319 map<int, Extension>::const_iterator iter = extensions_.find(number);
320 if (iter == extensions_.end() || iter->second.is_cleared) {
321 // Not present. Return the default value.
322 return default_value;
324 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, ENUM);
325 return iter->second.enum_value;
329 void ExtensionSet::SetEnum(int number, FieldType type, int value,
330 const FieldDescriptor* descriptor) {
331 Extension* extension;
332 if (MaybeNewExtension(number, descriptor, &extension)) {
333 extension->type = type;
334 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
335 extension->is_repeated = false;
337 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, ENUM);
339 extension->is_cleared = false;
340 extension->enum_value = value;
343 int ExtensionSet::GetRepeatedEnum(int number, int index) const {
344 map<int, Extension>::const_iterator iter = extensions_.find(number);
345 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
346 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
347 return iter->second.repeated_enum_value->Get(index);
350 void ExtensionSet::SetRepeatedEnum(int number, int index, int value) {
351 map<int, Extension>::iterator iter = extensions_.find(number);
352 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
353 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, ENUM);
354 iter->second.repeated_enum_value->Set(index, value);
357 void ExtensionSet::AddEnum(int number, FieldType type,
358 bool packed, int value,
359 const FieldDescriptor* descriptor) {
360 Extension* extension;
361 if (MaybeNewExtension(number, descriptor, &extension)) {
362 extension->type = type;
363 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_ENUM);
364 extension->is_repeated = true;
365 extension->is_packed = packed;
366 extension->repeated_enum_value = new RepeatedField<int>();
368 GOOGLE_DCHECK_TYPE(*extension, REPEATED, ENUM);
369 GOOGLE_DCHECK_EQ(extension->is_packed, packed);
371 extension->repeated_enum_value->Add(value);
374 // -------------------------------------------------------------------
377 const string& ExtensionSet::GetString(int number,
378 const string& default_value) const {
379 map<int, Extension>::const_iterator iter = extensions_.find(number);
380 if (iter == extensions_.end() || iter->second.is_cleared) {
381 // Not present. Return the default value.
382 return default_value;
384 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, STRING);
385 return *iter->second.string_value;
389 string* ExtensionSet::MutableString(int number, FieldType type,
390 const FieldDescriptor* descriptor) {
391 Extension* extension;
392 if (MaybeNewExtension(number, descriptor, &extension)) {
393 extension->type = type;
394 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
395 extension->is_repeated = false;
396 extension->string_value = new string;
398 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, STRING);
400 extension->is_cleared = false;
401 return extension->string_value;
404 const string& ExtensionSet::GetRepeatedString(int number, int index) const {
405 map<int, Extension>::const_iterator iter = extensions_.find(number);
406 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
407 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
408 return iter->second.repeated_string_value->Get(index);
411 string* ExtensionSet::MutableRepeatedString(int number, int index) {
412 map<int, Extension>::iterator iter = extensions_.find(number);
413 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
414 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, STRING);
415 return iter->second.repeated_string_value->Mutable(index);
418 string* ExtensionSet::AddString(int number, FieldType type,
419 const FieldDescriptor* descriptor) {
420 Extension* extension;
421 if (MaybeNewExtension(number, descriptor, &extension)) {
422 extension->type = type;
423 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_STRING);
424 extension->is_repeated = true;
425 extension->is_packed = false;
426 extension->repeated_string_value = new RepeatedPtrField<string>();
428 GOOGLE_DCHECK_TYPE(*extension, REPEATED, STRING);
430 return extension->repeated_string_value->Add();
433 // -------------------------------------------------------------------
436 const MessageLite& ExtensionSet::GetMessage(
437 int number, const MessageLite& default_value) const {
438 map<int, Extension>::const_iterator iter = extensions_.find(number);
439 if (iter == extensions_.end()) {
440 // Not present. Return the default value.
441 return default_value;
443 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
444 if (iter->second.is_lazy) {
445 return iter->second.lazymessage_value->GetMessage(default_value);
447 return *iter->second.message_value;
452 // Defined in extension_set_heavy.cc.
453 // const MessageLite& ExtensionSet::GetMessage(int number,
454 // const Descriptor* message_type,
455 // MessageFactory* factory) const
457 MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
458 const MessageLite& prototype,
459 const FieldDescriptor* descriptor) {
460 Extension* extension;
461 if (MaybeNewExtension(number, descriptor, &extension)) {
462 extension->type = type;
463 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
464 extension->is_repeated = false;
465 extension->is_lazy = false;
466 extension->message_value = prototype.New();
467 extension->is_cleared = false;
468 return extension->message_value;
470 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
471 extension->is_cleared = false;
472 if (extension->is_lazy) {
473 return extension->lazymessage_value->MutableMessage(prototype);
475 return extension->message_value;
480 // Defined in extension_set_heavy.cc.
481 // MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
482 // const Descriptor* message_type,
483 // MessageFactory* factory)
485 void ExtensionSet::SetAllocatedMessage(int number, FieldType type,
486 const FieldDescriptor* descriptor,
487 MessageLite* message) {
488 if (message == NULL) {
489 ClearExtension(number);
492 Extension* extension;
493 if (MaybeNewExtension(number, descriptor, &extension)) {
494 extension->type = type;
495 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
496 extension->is_repeated = false;
497 extension->is_lazy = false;
498 extension->message_value = message;
500 GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
501 if (extension->is_lazy) {
502 extension->lazymessage_value->SetAllocatedMessage(message);
504 delete extension->message_value;
505 extension->message_value = message;
508 extension->is_cleared = false;
511 MessageLite* ExtensionSet::ReleaseMessage(int number,
512 const MessageLite& prototype) {
513 map<int, Extension>::iterator iter = extensions_.find(number);
514 if (iter == extensions_.end()) {
515 // Not present. Return NULL.
518 GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
519 MessageLite* ret = NULL;
520 if (iter->second.is_lazy) {
521 ret = iter->second.lazymessage_value->ReleaseMessage(prototype);
522 delete iter->second.lazymessage_value;
524 ret = iter->second.message_value;
526 extensions_.erase(number);
531 // Defined in extension_set_heavy.cc.
532 // MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
533 // MessageFactory* factory);
535 const MessageLite& ExtensionSet::GetRepeatedMessage(
536 int number, int index) const {
537 map<int, Extension>::const_iterator iter = extensions_.find(number);
538 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
539 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
540 return iter->second.repeated_message_value->Get(index);
543 MessageLite* ExtensionSet::MutableRepeatedMessage(int number, int index) {
544 map<int, Extension>::iterator iter = extensions_.find(number);
545 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
546 GOOGLE_DCHECK_TYPE(iter->second, REPEATED, MESSAGE);
547 return iter->second.repeated_message_value->Mutable(index);
550 MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
551 const MessageLite& prototype,
552 const FieldDescriptor* descriptor) {
553 Extension* extension;
554 if (MaybeNewExtension(number, descriptor, &extension)) {
555 extension->type = type;
556 GOOGLE_DCHECK_EQ(cpp_type(extension->type), WireFormatLite::CPPTYPE_MESSAGE);
557 extension->is_repeated = true;
558 extension->repeated_message_value =
559 new RepeatedPtrField<MessageLite>();
561 GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
564 // RepeatedPtrField<MessageLite> does not know how to Add() since it cannot
565 // allocate an abstract object, so we have to be tricky.
566 MessageLite* result = extension->repeated_message_value
567 ->AddFromCleared<GenericTypeHandler<MessageLite> >();
568 if (result == NULL) {
569 result = prototype.New();
570 extension->repeated_message_value->AddAllocated(result);
575 // Defined in extension_set_heavy.cc.
576 // MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
577 // const Descriptor* message_type,
578 // MessageFactory* factory)
580 #undef GOOGLE_DCHECK_TYPE
582 void ExtensionSet::RemoveLast(int number) {
583 map<int, Extension>::iterator iter = extensions_.find(number);
584 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
586 Extension* extension = &iter->second;
587 GOOGLE_DCHECK(extension->is_repeated);
589 switch(cpp_type(extension->type)) {
590 case WireFormatLite::CPPTYPE_INT32:
591 extension->repeated_int32_value->RemoveLast();
593 case WireFormatLite::CPPTYPE_INT64:
594 extension->repeated_int64_value->RemoveLast();
596 case WireFormatLite::CPPTYPE_UINT32:
597 extension->repeated_uint32_value->RemoveLast();
599 case WireFormatLite::CPPTYPE_UINT64:
600 extension->repeated_uint64_value->RemoveLast();
602 case WireFormatLite::CPPTYPE_FLOAT:
603 extension->repeated_float_value->RemoveLast();
605 case WireFormatLite::CPPTYPE_DOUBLE:
606 extension->repeated_double_value->RemoveLast();
608 case WireFormatLite::CPPTYPE_BOOL:
609 extension->repeated_bool_value->RemoveLast();
611 case WireFormatLite::CPPTYPE_ENUM:
612 extension->repeated_enum_value->RemoveLast();
614 case WireFormatLite::CPPTYPE_STRING:
615 extension->repeated_string_value->RemoveLast();
617 case WireFormatLite::CPPTYPE_MESSAGE:
618 extension->repeated_message_value->RemoveLast();
623 MessageLite* ExtensionSet::ReleaseLast(int number) {
624 map<int, Extension>::iterator iter = extensions_.find(number);
625 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
627 Extension* extension = &iter->second;
628 GOOGLE_DCHECK(extension->is_repeated);
629 GOOGLE_DCHECK(cpp_type(extension->type) == WireFormatLite::CPPTYPE_MESSAGE);
630 return extension->repeated_message_value->ReleaseLast();
633 void ExtensionSet::SwapElements(int number, int index1, int index2) {
634 map<int, Extension>::iterator iter = extensions_.find(number);
635 GOOGLE_CHECK(iter != extensions_.end()) << "Index out-of-bounds (field is empty).";
637 Extension* extension = &iter->second;
638 GOOGLE_DCHECK(extension->is_repeated);
640 switch(cpp_type(extension->type)) {
641 case WireFormatLite::CPPTYPE_INT32:
642 extension->repeated_int32_value->SwapElements(index1, index2);
644 case WireFormatLite::CPPTYPE_INT64:
645 extension->repeated_int64_value->SwapElements(index1, index2);
647 case WireFormatLite::CPPTYPE_UINT32:
648 extension->repeated_uint32_value->SwapElements(index1, index2);
650 case WireFormatLite::CPPTYPE_UINT64:
651 extension->repeated_uint64_value->SwapElements(index1, index2);
653 case WireFormatLite::CPPTYPE_FLOAT:
654 extension->repeated_float_value->SwapElements(index1, index2);
656 case WireFormatLite::CPPTYPE_DOUBLE:
657 extension->repeated_double_value->SwapElements(index1, index2);
659 case WireFormatLite::CPPTYPE_BOOL:
660 extension->repeated_bool_value->SwapElements(index1, index2);
662 case WireFormatLite::CPPTYPE_ENUM:
663 extension->repeated_enum_value->SwapElements(index1, index2);
665 case WireFormatLite::CPPTYPE_STRING:
666 extension->repeated_string_value->SwapElements(index1, index2);
668 case WireFormatLite::CPPTYPE_MESSAGE:
669 extension->repeated_message_value->SwapElements(index1, index2);
674 // ===================================================================
676 void ExtensionSet::Clear() {
677 for (map<int, Extension>::iterator iter = extensions_.begin();
678 iter != extensions_.end(); ++iter) {
679 iter->second.Clear();
683 void ExtensionSet::MergeFrom(const ExtensionSet& other) {
684 for (map<int, Extension>::const_iterator iter = other.extensions_.begin();
685 iter != other.extensions_.end(); ++iter) {
686 const Extension& other_extension = iter->second;
688 if (other_extension.is_repeated) {
689 Extension* extension;
690 bool is_new = MaybeNewExtension(iter->first, other_extension.descriptor,
693 // Extension did not already exist in set.
694 extension->type = other_extension.type;
695 extension->is_packed = other_extension.is_packed;
696 extension->is_repeated = true;
698 GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
699 GOOGLE_DCHECK_EQ(extension->is_packed, other_extension.is_packed);
700 GOOGLE_DCHECK(extension->is_repeated);
703 switch (cpp_type(other_extension.type)) {
704 #define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE) \
705 case WireFormatLite::CPPTYPE_##UPPERCASE: \
707 extension->repeated_##LOWERCASE##_value = \
710 extension->repeated_##LOWERCASE##_value->MergeFrom( \
711 *other_extension.repeated_##LOWERCASE##_value); \
714 HANDLE_TYPE( INT32, int32, RepeatedField < int32>);
715 HANDLE_TYPE( INT64, int64, RepeatedField < int64>);
716 HANDLE_TYPE( UINT32, uint32, RepeatedField < uint32>);
717 HANDLE_TYPE( UINT64, uint64, RepeatedField < uint64>);
718 HANDLE_TYPE( FLOAT, float, RepeatedField < float>);
719 HANDLE_TYPE( DOUBLE, double, RepeatedField < double>);
720 HANDLE_TYPE( BOOL, bool, RepeatedField < bool>);
721 HANDLE_TYPE( ENUM, enum, RepeatedField < int>);
722 HANDLE_TYPE( STRING, string, RepeatedPtrField< string>);
725 case WireFormatLite::CPPTYPE_MESSAGE:
727 extension->repeated_message_value =
728 new RepeatedPtrField<MessageLite>();
730 // We can't call RepeatedPtrField<MessageLite>::MergeFrom() because
731 // it would attempt to allocate new objects.
732 RepeatedPtrField<MessageLite>* other_repeated_message =
733 other_extension.repeated_message_value;
734 for (int i = 0; i < other_repeated_message->size(); i++) {
735 const MessageLite& other_message = other_repeated_message->Get(i);
736 MessageLite* target = extension->repeated_message_value
737 ->AddFromCleared<GenericTypeHandler<MessageLite> >();
738 if (target == NULL) {
739 target = other_message.New();
740 extension->repeated_message_value->AddAllocated(target);
742 target->CheckTypeAndMergeFrom(other_message);
747 if (!other_extension.is_cleared) {
748 switch (cpp_type(other_extension.type)) {
749 #define HANDLE_TYPE(UPPERCASE, LOWERCASE, CAMELCASE) \
750 case WireFormatLite::CPPTYPE_##UPPERCASE: \
751 Set##CAMELCASE(iter->first, other_extension.type, \
752 other_extension.LOWERCASE##_value, \
753 other_extension.descriptor); \
756 HANDLE_TYPE( INT32, int32, Int32);
757 HANDLE_TYPE( INT64, int64, Int64);
758 HANDLE_TYPE(UINT32, uint32, UInt32);
759 HANDLE_TYPE(UINT64, uint64, UInt64);
760 HANDLE_TYPE( FLOAT, float, Float);
761 HANDLE_TYPE(DOUBLE, double, Double);
762 HANDLE_TYPE( BOOL, bool, Bool);
763 HANDLE_TYPE( ENUM, enum, Enum);
765 case WireFormatLite::CPPTYPE_STRING:
766 SetString(iter->first, other_extension.type,
767 *other_extension.string_value,
768 other_extension.descriptor);
770 case WireFormatLite::CPPTYPE_MESSAGE: {
771 Extension* extension;
772 bool is_new = MaybeNewExtension(iter->first,
773 other_extension.descriptor,
776 extension->type = other_extension.type;
777 extension->is_packed = other_extension.is_packed;
778 extension->is_repeated = false;
779 if (other_extension.is_lazy) {
780 extension->is_lazy = true;
781 extension->lazymessage_value =
782 other_extension.lazymessage_value->New();
783 extension->lazymessage_value->MergeFrom(
784 *other_extension.lazymessage_value);
786 extension->is_lazy = false;
787 extension->message_value =
788 other_extension.message_value->New();
789 extension->message_value->CheckTypeAndMergeFrom(
790 *other_extension.message_value);
793 GOOGLE_DCHECK_EQ(extension->type, other_extension.type);
794 GOOGLE_DCHECK_EQ(extension->is_packed,other_extension.is_packed);
795 GOOGLE_DCHECK(!extension->is_repeated);
796 if (other_extension.is_lazy) {
797 if (extension->is_lazy) {
798 extension->lazymessage_value->MergeFrom(
799 *other_extension.lazymessage_value);
801 extension->message_value->CheckTypeAndMergeFrom(
802 other_extension.lazymessage_value->GetMessage(
803 *extension->message_value));
806 if (extension->is_lazy) {
807 extension->lazymessage_value->MutableMessage(
808 *other_extension.message_value)->CheckTypeAndMergeFrom(
809 *other_extension.message_value);
811 extension->message_value->CheckTypeAndMergeFrom(
812 *other_extension.message_value);
816 extension->is_cleared = false;
825 void ExtensionSet::Swap(ExtensionSet* x) {
826 extensions_.swap(x->extensions_);
829 bool ExtensionSet::IsInitialized() const {
830 // Extensions are never required. However, we need to check that all
831 // embedded messages are initialized.
832 for (map<int, Extension>::const_iterator iter = extensions_.begin();
833 iter != extensions_.end(); ++iter) {
834 const Extension& extension = iter->second;
835 if (cpp_type(extension.type) == WireFormatLite::CPPTYPE_MESSAGE) {
836 if (extension.is_repeated) {
837 for (int i = 0; i < extension.repeated_message_value->size(); i++) {
838 if (!extension.repeated_message_value->Get(i).IsInitialized()) {
843 if (!extension.is_cleared) {
844 if (extension.is_lazy) {
845 if (!extension.lazymessage_value->IsInitialized()) return false;
847 if (!extension.message_value->IsInitialized()) return false;
857 bool ExtensionSet::FindExtensionInfoFromTag(
858 uint32 tag, ExtensionFinder* extension_finder,
859 int* field_number, ExtensionInfo* extension) {
860 *field_number = WireFormatLite::GetTagFieldNumber(tag);
861 WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
864 if (!extension_finder->Find(*field_number, extension)) {
866 } else if (extension->is_packed) {
867 is_unknown = (wire_type != WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
869 WireFormatLite::WireType expected_wire_type =
870 WireFormatLite::WireTypeForFieldType(real_type(extension->type));
871 is_unknown = (wire_type != expected_wire_type);
876 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
877 ExtensionFinder* extension_finder,
878 FieldSkipper* field_skipper) {
880 ExtensionInfo extension;
881 if (!FindExtensionInfoFromTag(tag, extension_finder, &number, &extension)) {
882 return field_skipper->SkipField(input, tag);
884 return ParseFieldWithExtensionInfo(number, extension, input, field_skipper);
888 bool ExtensionSet::ParseFieldWithExtensionInfo(
889 int number, const ExtensionInfo& extension,
890 io::CodedInputStream* input,
891 FieldSkipper* field_skipper) {
892 if (extension.is_packed) {
894 if (!input->ReadVarint32(&size)) return false;
895 io::CodedInputStream::Limit limit = input->PushLimit(size);
897 switch (extension.type) {
898 #define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \
899 case WireFormatLite::TYPE_##UPPERCASE: \
900 while (input->BytesUntilLimit() > 0) { \
901 CPP_LOWERCASE value; \
902 if (!WireFormatLite::ReadPrimitive< \
903 CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \
904 input, &value)) return false; \
905 Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
906 true, value, extension.descriptor); \
910 HANDLE_TYPE( INT32, Int32, int32);
911 HANDLE_TYPE( INT64, Int64, int64);
912 HANDLE_TYPE( UINT32, UInt32, uint32);
913 HANDLE_TYPE( UINT64, UInt64, uint64);
914 HANDLE_TYPE( SINT32, Int32, int32);
915 HANDLE_TYPE( SINT64, Int64, int64);
916 HANDLE_TYPE( FIXED32, UInt32, uint32);
917 HANDLE_TYPE( FIXED64, UInt64, uint64);
918 HANDLE_TYPE(SFIXED32, Int32, int32);
919 HANDLE_TYPE(SFIXED64, Int64, int64);
920 HANDLE_TYPE( FLOAT, Float, float);
921 HANDLE_TYPE( DOUBLE, Double, double);
922 HANDLE_TYPE( BOOL, Bool, bool);
925 case WireFormatLite::TYPE_ENUM:
926 while (input->BytesUntilLimit() > 0) {
928 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
929 input, &value)) return false;
930 if (extension.enum_validity_check.func(
931 extension.enum_validity_check.arg, value)) {
932 AddEnum(number, WireFormatLite::TYPE_ENUM, true, value,
933 extension.descriptor);
938 case WireFormatLite::TYPE_STRING:
939 case WireFormatLite::TYPE_BYTES:
940 case WireFormatLite::TYPE_GROUP:
941 case WireFormatLite::TYPE_MESSAGE:
942 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
946 input->PopLimit(limit);
948 switch (extension.type) {
949 #define HANDLE_TYPE(UPPERCASE, CPP_CAMELCASE, CPP_LOWERCASE) \
950 case WireFormatLite::TYPE_##UPPERCASE: { \
951 CPP_LOWERCASE value; \
952 if (!WireFormatLite::ReadPrimitive< \
953 CPP_LOWERCASE, WireFormatLite::TYPE_##UPPERCASE>( \
954 input, &value)) return false; \
955 if (extension.is_repeated) { \
956 Add##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, \
957 false, value, extension.descriptor); \
959 Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value, \
960 extension.descriptor); \
964 HANDLE_TYPE( INT32, Int32, int32);
965 HANDLE_TYPE( INT64, Int64, int64);
966 HANDLE_TYPE( UINT32, UInt32, uint32);
967 HANDLE_TYPE( UINT64, UInt64, uint64);
968 HANDLE_TYPE( SINT32, Int32, int32);
969 HANDLE_TYPE( SINT64, Int64, int64);
970 HANDLE_TYPE( FIXED32, UInt32, uint32);
971 HANDLE_TYPE( FIXED64, UInt64, uint64);
972 HANDLE_TYPE(SFIXED32, Int32, int32);
973 HANDLE_TYPE(SFIXED64, Int64, int64);
974 HANDLE_TYPE( FLOAT, Float, float);
975 HANDLE_TYPE( DOUBLE, Double, double);
976 HANDLE_TYPE( BOOL, Bool, bool);
979 case WireFormatLite::TYPE_ENUM: {
981 if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
982 input, &value)) return false;
984 if (!extension.enum_validity_check.func(
985 extension.enum_validity_check.arg, value)) {
986 // Invalid value. Treat as unknown.
987 field_skipper->SkipUnknownEnum(number, value);
988 } else if (extension.is_repeated) {
989 AddEnum(number, WireFormatLite::TYPE_ENUM, false, value,
990 extension.descriptor);
992 SetEnum(number, WireFormatLite::TYPE_ENUM, value,
993 extension.descriptor);
998 case WireFormatLite::TYPE_STRING: {
999 string* value = extension.is_repeated ?
1000 AddString(number, WireFormatLite::TYPE_STRING, extension.descriptor) :
1001 MutableString(number, WireFormatLite::TYPE_STRING,
1002 extension.descriptor);
1003 if (!WireFormatLite::ReadString(input, value)) return false;
1007 case WireFormatLite::TYPE_BYTES: {
1008 string* value = extension.is_repeated ?
1009 AddString(number, WireFormatLite::TYPE_BYTES, extension.descriptor) :
1010 MutableString(number, WireFormatLite::TYPE_BYTES,
1011 extension.descriptor);
1012 if (!WireFormatLite::ReadBytes(input, value)) return false;
1016 case WireFormatLite::TYPE_GROUP: {
1017 MessageLite* value = extension.is_repeated ?
1018 AddMessage(number, WireFormatLite::TYPE_GROUP,
1019 *extension.message_prototype, extension.descriptor) :
1020 MutableMessage(number, WireFormatLite::TYPE_GROUP,
1021 *extension.message_prototype, extension.descriptor);
1022 if (!WireFormatLite::ReadGroup(number, input, value)) return false;
1026 case WireFormatLite::TYPE_MESSAGE: {
1027 MessageLite* value = extension.is_repeated ?
1028 AddMessage(number, WireFormatLite::TYPE_MESSAGE,
1029 *extension.message_prototype, extension.descriptor) :
1030 MutableMessage(number, WireFormatLite::TYPE_MESSAGE,
1031 *extension.message_prototype, extension.descriptor);
1032 if (!WireFormatLite::ReadMessage(input, value)) return false;
1041 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
1042 const MessageLite* containing_type,
1043 UnknownFieldSet* unknown_fields) {
1044 FieldSkipper skipper(unknown_fields);
1045 GeneratedExtensionFinder finder(containing_type);
1046 return ParseField(tag, input, &finder, &skipper);
1049 // Defined in extension_set_heavy.cc.
1050 // bool ExtensionSet::ParseFieldHeavy(uint32 tag, io::CodedInputStream* input,
1051 // const Message* containing_type,
1052 // UnknownFieldSet* unknown_fields)
1054 // Defined in extension_set_heavy.cc.
1055 // bool ExtensionSet::ParseMessageSetHeavy(io::CodedInputStream* input,
1056 // const Message* containing_type,
1057 // UnknownFieldSet* unknown_fields);
1059 void ExtensionSet::SerializeWithCachedSizes(
1060 int start_field_number, int end_field_number,
1061 io::CodedOutputStream* output) const {
1062 map<int, Extension>::const_iterator iter;
1063 for (iter = extensions_.lower_bound(start_field_number);
1064 iter != extensions_.end() && iter->first < end_field_number;
1066 iter->second.SerializeFieldWithCachedSizes(iter->first, output);
1070 int ExtensionSet::ByteSize() const {
1073 for (map<int, Extension>::const_iterator iter = extensions_.begin();
1074 iter != extensions_.end(); ++iter) {
1075 total_size += iter->second.ByteSize(iter->first);
1081 // Defined in extension_set_heavy.cc.
1082 // int ExtensionSet::SpaceUsedExcludingSelf() const
1084 bool ExtensionSet::MaybeNewExtension(int number,
1085 const FieldDescriptor* descriptor,
1086 Extension** result) {
1087 pair<map<int, Extension>::iterator, bool> insert_result =
1088 extensions_.insert(make_pair(number, Extension()));
1089 *result = &insert_result.first->second;
1090 (*result)->descriptor = descriptor;
1091 return insert_result.second;
1094 // ===================================================================
1095 // Methods of ExtensionSet::Extension
1097 void ExtensionSet::Extension::Clear() {
1099 switch (cpp_type(type)) {
1100 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1101 case WireFormatLite::CPPTYPE_##UPPERCASE: \
1102 repeated_##LOWERCASE##_value->Clear(); \
1105 HANDLE_TYPE( INT32, int32);
1106 HANDLE_TYPE( INT64, int64);
1107 HANDLE_TYPE( UINT32, uint32);
1108 HANDLE_TYPE( UINT64, uint64);
1109 HANDLE_TYPE( FLOAT, float);
1110 HANDLE_TYPE( DOUBLE, double);
1111 HANDLE_TYPE( BOOL, bool);
1112 HANDLE_TYPE( ENUM, enum);
1113 HANDLE_TYPE( STRING, string);
1114 HANDLE_TYPE(MESSAGE, message);
1119 switch (cpp_type(type)) {
1120 case WireFormatLite::CPPTYPE_STRING:
1121 string_value->clear();
1123 case WireFormatLite::CPPTYPE_MESSAGE:
1125 lazymessage_value->Clear();
1127 message_value->Clear();
1131 // No need to do anything. Get*() will return the default value
1132 // as long as is_cleared is true and Set*() will overwrite the
1142 void ExtensionSet::Extension::SerializeFieldWithCachedSizes(
1144 io::CodedOutputStream* output) const {
1147 if (cached_size == 0) return;
1149 WireFormatLite::WriteTag(number,
1150 WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
1151 output->WriteVarint32(cached_size);
1153 switch (real_type(type)) {
1154 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1155 case WireFormatLite::TYPE_##UPPERCASE: \
1156 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1157 WireFormatLite::Write##CAMELCASE##NoTag( \
1158 repeated_##LOWERCASE##_value->Get(i), output); \
1162 HANDLE_TYPE( INT32, Int32, int32);
1163 HANDLE_TYPE( INT64, Int64, int64);
1164 HANDLE_TYPE( UINT32, UInt32, uint32);
1165 HANDLE_TYPE( UINT64, UInt64, uint64);
1166 HANDLE_TYPE( SINT32, SInt32, int32);
1167 HANDLE_TYPE( SINT64, SInt64, int64);
1168 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1169 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1170 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1171 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1172 HANDLE_TYPE( FLOAT, Float, float);
1173 HANDLE_TYPE( DOUBLE, Double, double);
1174 HANDLE_TYPE( BOOL, Bool, bool);
1175 HANDLE_TYPE( ENUM, Enum, enum);
1178 case WireFormatLite::TYPE_STRING:
1179 case WireFormatLite::TYPE_BYTES:
1180 case WireFormatLite::TYPE_GROUP:
1181 case WireFormatLite::TYPE_MESSAGE:
1182 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1186 switch (real_type(type)) {
1187 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1188 case WireFormatLite::TYPE_##UPPERCASE: \
1189 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1190 WireFormatLite::Write##CAMELCASE(number, \
1191 repeated_##LOWERCASE##_value->Get(i), output); \
1195 HANDLE_TYPE( INT32, Int32, int32);
1196 HANDLE_TYPE( INT64, Int64, int64);
1197 HANDLE_TYPE( UINT32, UInt32, uint32);
1198 HANDLE_TYPE( UINT64, UInt64, uint64);
1199 HANDLE_TYPE( SINT32, SInt32, int32);
1200 HANDLE_TYPE( SINT64, SInt64, int64);
1201 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1202 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1203 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1204 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1205 HANDLE_TYPE( FLOAT, Float, float);
1206 HANDLE_TYPE( DOUBLE, Double, double);
1207 HANDLE_TYPE( BOOL, Bool, bool);
1208 HANDLE_TYPE( STRING, String, string);
1209 HANDLE_TYPE( BYTES, Bytes, string);
1210 HANDLE_TYPE( ENUM, Enum, enum);
1211 HANDLE_TYPE( GROUP, Group, message);
1212 HANDLE_TYPE( MESSAGE, Message, message);
1216 } else if (!is_cleared) {
1217 switch (real_type(type)) {
1218 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE) \
1219 case WireFormatLite::TYPE_##UPPERCASE: \
1220 WireFormatLite::Write##CAMELCASE(number, VALUE, output); \
1223 HANDLE_TYPE( INT32, Int32, int32_value);
1224 HANDLE_TYPE( INT64, Int64, int64_value);
1225 HANDLE_TYPE( UINT32, UInt32, uint32_value);
1226 HANDLE_TYPE( UINT64, UInt64, uint64_value);
1227 HANDLE_TYPE( SINT32, SInt32, int32_value);
1228 HANDLE_TYPE( SINT64, SInt64, int64_value);
1229 HANDLE_TYPE( FIXED32, Fixed32, uint32_value);
1230 HANDLE_TYPE( FIXED64, Fixed64, uint64_value);
1231 HANDLE_TYPE(SFIXED32, SFixed32, int32_value);
1232 HANDLE_TYPE(SFIXED64, SFixed64, int64_value);
1233 HANDLE_TYPE( FLOAT, Float, float_value);
1234 HANDLE_TYPE( DOUBLE, Double, double_value);
1235 HANDLE_TYPE( BOOL, Bool, bool_value);
1236 HANDLE_TYPE( STRING, String, *string_value);
1237 HANDLE_TYPE( BYTES, Bytes, *string_value);
1238 HANDLE_TYPE( ENUM, Enum, enum_value);
1239 HANDLE_TYPE( GROUP, Group, *message_value);
1241 case WireFormatLite::TYPE_MESSAGE:
1243 lazymessage_value->WriteMessage(number, output);
1245 WireFormatLite::WriteMessage(number, *message_value, output);
1252 int ExtensionSet::Extension::ByteSize(int number) const {
1257 switch (real_type(type)) {
1258 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1259 case WireFormatLite::TYPE_##UPPERCASE: \
1260 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1261 result += WireFormatLite::CAMELCASE##Size( \
1262 repeated_##LOWERCASE##_value->Get(i)); \
1266 HANDLE_TYPE( INT32, Int32, int32);
1267 HANDLE_TYPE( INT64, Int64, int64);
1268 HANDLE_TYPE( UINT32, UInt32, uint32);
1269 HANDLE_TYPE( UINT64, UInt64, uint64);
1270 HANDLE_TYPE( SINT32, SInt32, int32);
1271 HANDLE_TYPE( SINT64, SInt64, int64);
1272 HANDLE_TYPE( ENUM, Enum, enum);
1275 // Stuff with fixed size.
1276 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1277 case WireFormatLite::TYPE_##UPPERCASE: \
1278 result += WireFormatLite::k##CAMELCASE##Size * \
1279 repeated_##LOWERCASE##_value->size(); \
1281 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1282 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1283 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1284 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1285 HANDLE_TYPE( FLOAT, Float, float);
1286 HANDLE_TYPE( DOUBLE, Double, double);
1287 HANDLE_TYPE( BOOL, Bool, bool);
1290 case WireFormatLite::TYPE_STRING:
1291 case WireFormatLite::TYPE_BYTES:
1292 case WireFormatLite::TYPE_GROUP:
1293 case WireFormatLite::TYPE_MESSAGE:
1294 GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
1298 cached_size = result;
1300 result += io::CodedOutputStream::VarintSize32(result);
1301 result += io::CodedOutputStream::VarintSize32(
1302 WireFormatLite::MakeTag(number,
1303 WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
1306 int tag_size = WireFormatLite::TagSize(number, real_type(type));
1308 switch (real_type(type)) {
1309 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1310 case WireFormatLite::TYPE_##UPPERCASE: \
1311 result += tag_size * repeated_##LOWERCASE##_value->size(); \
1312 for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) { \
1313 result += WireFormatLite::CAMELCASE##Size( \
1314 repeated_##LOWERCASE##_value->Get(i)); \
1318 HANDLE_TYPE( INT32, Int32, int32);
1319 HANDLE_TYPE( INT64, Int64, int64);
1320 HANDLE_TYPE( UINT32, UInt32, uint32);
1321 HANDLE_TYPE( UINT64, UInt64, uint64);
1322 HANDLE_TYPE( SINT32, SInt32, int32);
1323 HANDLE_TYPE( SINT64, SInt64, int64);
1324 HANDLE_TYPE( STRING, String, string);
1325 HANDLE_TYPE( BYTES, Bytes, string);
1326 HANDLE_TYPE( ENUM, Enum, enum);
1327 HANDLE_TYPE( GROUP, Group, message);
1328 HANDLE_TYPE( MESSAGE, Message, message);
1331 // Stuff with fixed size.
1332 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1333 case WireFormatLite::TYPE_##UPPERCASE: \
1334 result += (tag_size + WireFormatLite::k##CAMELCASE##Size) * \
1335 repeated_##LOWERCASE##_value->size(); \
1337 HANDLE_TYPE( FIXED32, Fixed32, uint32);
1338 HANDLE_TYPE( FIXED64, Fixed64, uint64);
1339 HANDLE_TYPE(SFIXED32, SFixed32, int32);
1340 HANDLE_TYPE(SFIXED64, SFixed64, int64);
1341 HANDLE_TYPE( FLOAT, Float, float);
1342 HANDLE_TYPE( DOUBLE, Double, double);
1343 HANDLE_TYPE( BOOL, Bool, bool);
1347 } else if (!is_cleared) {
1348 result += WireFormatLite::TagSize(number, real_type(type));
1349 switch (real_type(type)) {
1350 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE) \
1351 case WireFormatLite::TYPE_##UPPERCASE: \
1352 result += WireFormatLite::CAMELCASE##Size(LOWERCASE); \
1355 HANDLE_TYPE( INT32, Int32, int32_value);
1356 HANDLE_TYPE( INT64, Int64, int64_value);
1357 HANDLE_TYPE( UINT32, UInt32, uint32_value);
1358 HANDLE_TYPE( UINT64, UInt64, uint64_value);
1359 HANDLE_TYPE( SINT32, SInt32, int32_value);
1360 HANDLE_TYPE( SINT64, SInt64, int64_value);
1361 HANDLE_TYPE( STRING, String, *string_value);
1362 HANDLE_TYPE( BYTES, Bytes, *string_value);
1363 HANDLE_TYPE( ENUM, Enum, enum_value);
1364 HANDLE_TYPE( GROUP, Group, *message_value);
1366 case WireFormatLite::TYPE_MESSAGE: {
1368 int size = lazymessage_value->ByteSize();
1369 result += io::CodedOutputStream::VarintSize32(size) + size;
1371 result += WireFormatLite::MessageSize(*message_value);
1376 // Stuff with fixed size.
1377 #define HANDLE_TYPE(UPPERCASE, CAMELCASE) \
1378 case WireFormatLite::TYPE_##UPPERCASE: \
1379 result += WireFormatLite::k##CAMELCASE##Size; \
1381 HANDLE_TYPE( FIXED32, Fixed32);
1382 HANDLE_TYPE( FIXED64, Fixed64);
1383 HANDLE_TYPE(SFIXED32, SFixed32);
1384 HANDLE_TYPE(SFIXED64, SFixed64);
1385 HANDLE_TYPE( FLOAT, Float);
1386 HANDLE_TYPE( DOUBLE, Double);
1387 HANDLE_TYPE( BOOL, Bool);
1395 int ExtensionSet::Extension::GetSize() const {
1396 GOOGLE_DCHECK(is_repeated);
1397 switch (cpp_type(type)) {
1398 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1399 case WireFormatLite::CPPTYPE_##UPPERCASE: \
1400 return repeated_##LOWERCASE##_value->size()
1402 HANDLE_TYPE( INT32, int32);
1403 HANDLE_TYPE( INT64, int64);
1404 HANDLE_TYPE( UINT32, uint32);
1405 HANDLE_TYPE( UINT64, uint64);
1406 HANDLE_TYPE( FLOAT, float);
1407 HANDLE_TYPE( DOUBLE, double);
1408 HANDLE_TYPE( BOOL, bool);
1409 HANDLE_TYPE( ENUM, enum);
1410 HANDLE_TYPE( STRING, string);
1411 HANDLE_TYPE(MESSAGE, message);
1415 GOOGLE_LOG(FATAL) << "Can't get here.";
1419 void ExtensionSet::Extension::Free() {
1421 switch (cpp_type(type)) {
1422 #define HANDLE_TYPE(UPPERCASE, LOWERCASE) \
1423 case WireFormatLite::CPPTYPE_##UPPERCASE: \
1424 delete repeated_##LOWERCASE##_value; \
1427 HANDLE_TYPE( INT32, int32);
1428 HANDLE_TYPE( INT64, int64);
1429 HANDLE_TYPE( UINT32, uint32);
1430 HANDLE_TYPE( UINT64, uint64);
1431 HANDLE_TYPE( FLOAT, float);
1432 HANDLE_TYPE( DOUBLE, double);
1433 HANDLE_TYPE( BOOL, bool);
1434 HANDLE_TYPE( ENUM, enum);
1435 HANDLE_TYPE( STRING, string);
1436 HANDLE_TYPE(MESSAGE, message);
1440 switch (cpp_type(type)) {
1441 case WireFormatLite::CPPTYPE_STRING:
1442 delete string_value;
1444 case WireFormatLite::CPPTYPE_MESSAGE:
1446 delete lazymessage_value;
1448 delete message_value;
1457 // Defined in extension_set_heavy.cc.
1458 // int ExtensionSet::Extension::SpaceUsedExcludingSelf() const
1460 } // namespace internal
1461 } // namespace protobuf
1462 } // namespace google