Home | History | Annotate | Download | only in protobuf
      1 // Protocol Buffers - Google's data interchange format
      2 // Copyright 2008 Google Inc.  All rights reserved.
      3 // http://code.google.com/p/protobuf/
      4 //
      5 // Redistribution and use in source and binary forms, with or without
      6 // modification, are permitted provided that the following conditions are
      7 // met:
      8 //
      9 //     * Redistributions of source code must retain the above copyright
     10 // notice, this list of conditions and the following disclaimer.
     11 //     * Redistributions in binary form must reproduce the above
     12 // copyright notice, this list of conditions and the following disclaimer
     13 // in the documentation and/or other materials provided with the
     14 // distribution.
     15 //     * Neither the name of Google Inc. nor the names of its
     16 // contributors may be used to endorse or promote products derived from
     17 // this software without specific prior written permission.
     18 //
     19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30 
     31 // Author: kenton (at) google.com (Kenton Varda)
     32 //  Based on original Protocol Buffers design by
     33 //  Sanjay Ghemawat, Jeff Dean, and others.
     34 
     35 #include <google/protobuf/stubs/hash.h>
     36 #include <google/protobuf/stubs/common.h>
     37 #include <google/protobuf/stubs/once.h>
     38 #include <google/protobuf/extension_set.h>
     39 #include <google/protobuf/message_lite.h>
     40 #include <google/protobuf/io/coded_stream.h>
     41 #include <google/protobuf/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>
     45 
     46 namespace google {
     47 namespace protobuf {
     48 namespace internal {
     49 
     50 namespace {
     51 
     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);
     55 }
     56 
     57 inline WireFormatLite::CppType cpp_type(FieldType type) {
     58   return WireFormatLite::FieldTypeToCppType(real_type(type));
     59 }
     60 
     61 // Registry stuff.
     62 typedef hash_map<pair<const MessageLite*, int>,
     63                  ExtensionInfo> ExtensionRegistry;
     64 ExtensionRegistry* registry_ = NULL;
     65 GOOGLE_PROTOBUF_DECLARE_ONCE(registry_init_);
     66 
     67 void DeleteRegistry() {
     68   delete registry_;
     69   registry_ = NULL;
     70 }
     71 
     72 void InitRegistry() {
     73   registry_ = new ExtensionRegistry;
     74   OnShutdown(&DeleteRegistry);
     75 }
     76 
     77 // This function is only called at startup, so there is no need for thread-
     78 // safety.
     79 void Register(const MessageLite* containing_type,
     80               int number, ExtensionInfo info) {
     81   ::google::protobuf::GoogleOnceInit(&registry_init_, &InitRegistry);
     82 
     83   if (!InsertIfNotPresent(registry_, make_pair(containing_type, number),
     84                           info)) {
     85     GOOGLE_LOG(FATAL) << "Multiple extension registrations for type \""
     86                << containing_type->GetTypeName()
     87                << "\", field number " << number << ".";
     88   }
     89 }
     90 
     91 const ExtensionInfo* FindRegisteredExtension(
     92     const MessageLite* containing_type, int number) {
     93   return (registry_ == NULL) ? NULL :
     94          FindOrNull(*registry_, make_pair(containing_type, number));
     95 }
     96 
     97 }  // namespace
     98 
     99 ExtensionFinder::~ExtensionFinder() {}
    100 
    101 bool GeneratedExtensionFinder::Find(int number, ExtensionInfo* output) {
    102   const ExtensionInfo* extension =
    103       FindRegisteredExtension(containing_type_, number);
    104   if (extension == NULL) {
    105     return false;
    106   } else {
    107     *output = *extension;
    108     return true;
    109   }
    110 }
    111 
    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);
    120 }
    121 
    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);
    133 }
    134 
    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);
    145 }
    146 
    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);
    156 }
    157 
    158 
    159 // ===================================================================
    160 // Constructors and basic methods.
    161 
    162 ExtensionSet::ExtensionSet() {}
    163 
    164 ExtensionSet::~ExtensionSet() {
    165   for (map<int, Extension>::iterator iter = extensions_.begin();
    166        iter != extensions_.end(); ++iter) {
    167     iter->second.Free();
    168   }
    169 }
    170 
    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
    175 
    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;
    181 }
    182 
    183 int ExtensionSet::NumExtensions() const {
    184   int result = 0;
    185   for (map<int, Extension>::const_iterator iter = extensions_.begin();
    186        iter != extensions_.end(); ++iter) {
    187     if (!iter->second.is_cleared) {
    188       ++result;
    189     }
    190   }
    191   return result;
    192 }
    193 
    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();
    198 }
    199 
    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). ";
    204     return 0;
    205   }
    206   if (iter->second.is_cleared) {
    207     GOOGLE_LOG(DFATAL) << "Don't lookup extension types if they aren't present (2). ";
    208   }
    209   return iter->second.type;
    210 }
    211 
    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();
    216 }
    217 
    218 // ===================================================================
    219 // Field accessors
    220 
    221 namespace {
    222 
    223 enum Cardinality {
    224   REPEATED,
    225   OPTIONAL
    226 };
    227 
    228 }  // namespace
    229 
    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)
    233 
    234 // -------------------------------------------------------------------
    235 // Primitives
    236 
    237 #define PRIMITIVE_ACCESSORS(UPPERCASE, LOWERCASE, CAMELCASE)                   \
    238                                                                                \
    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;                                                      \
    244   } else {                                                                     \
    245     GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, UPPERCASE);                            \
    246     return iter->second.LOWERCASE##_value;                                     \
    247   }                                                                            \
    248 }                                                                              \
    249                                                                                \
    250 void ExtensionSet::Set##CAMELCASE(int number, FieldType type,                  \
    251                                   LOWERCASE value,                             \
    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;                                            \
    258   } else {                                                                     \
    259     GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, UPPERCASE);                              \
    260   }                                                                            \
    261   extension->is_cleared = false;                                               \
    262   extension->LOWERCASE##_value = value;                                        \
    263 }                                                                              \
    264                                                                                \
    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);                \
    270 }                                                                              \
    271                                                                                \
    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);                \
    278 }                                                                              \
    279                                                                                \
    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>();  \
    290   } else {                                                                     \
    291     GOOGLE_DCHECK_TYPE(*extension, REPEATED, UPPERCASE);                              \
    292     GOOGLE_DCHECK_EQ(extension->is_packed, packed);                                   \
    293   }                                                                            \
    294   extension->repeated_##LOWERCASE##_value->Add(value);                         \
    295 }
    296 
    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)
    304 
    305 #undef PRIMITIVE_ACCESSORS
    306 
    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;
    313 }
    314 
    315 // -------------------------------------------------------------------
    316 // Enums
    317 
    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;
    323   } else {
    324     GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, ENUM);
    325     return iter->second.enum_value;
    326   }
    327 }
    328 
    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;
    336   } else {
    337     GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, ENUM);
    338   }
    339   extension->is_cleared = false;
    340   extension->enum_value = value;
    341 }
    342 
    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);
    348 }
    349 
    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);
    355 }
    356 
    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>();
    367   } else {
    368     GOOGLE_DCHECK_TYPE(*extension, REPEATED, ENUM);
    369     GOOGLE_DCHECK_EQ(extension->is_packed, packed);
    370   }
    371   extension->repeated_enum_value->Add(value);
    372 }
    373 
    374 // -------------------------------------------------------------------
    375 // Strings
    376 
    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;
    383   } else {
    384     GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, STRING);
    385     return *iter->second.string_value;
    386   }
    387 }
    388 
    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;
    397   } else {
    398     GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, STRING);
    399   }
    400   extension->is_cleared = false;
    401   return extension->string_value;
    402 }
    403 
    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);
    409 }
    410 
    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);
    416 }
    417 
    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>();
    427   } else {
    428     GOOGLE_DCHECK_TYPE(*extension, REPEATED, STRING);
    429   }
    430   return extension->repeated_string_value->Add();
    431 }
    432 
    433 // -------------------------------------------------------------------
    434 // Messages
    435 
    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;
    442   } else {
    443     GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
    444     if (iter->second.is_lazy) {
    445       return iter->second.lazymessage_value->GetMessage(default_value);
    446     } else {
    447       return *iter->second.message_value;
    448     }
    449   }
    450 }
    451 
    452 // Defined in extension_set_heavy.cc.
    453 // const MessageLite& ExtensionSet::GetMessage(int number,
    454 //                                             const Descriptor* message_type,
    455 //                                             MessageFactory* factory) const
    456 
    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;
    469   } else {
    470     GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
    471     extension->is_cleared = false;
    472     if (extension->is_lazy) {
    473       return extension->lazymessage_value->MutableMessage(prototype);
    474     } else {
    475       return extension->message_value;
    476     }
    477   }
    478 }
    479 
    480 // Defined in extension_set_heavy.cc.
    481 // MessageLite* ExtensionSet::MutableMessage(int number, FieldType type,
    482 //                                           const Descriptor* message_type,
    483 //                                           MessageFactory* factory)
    484 
    485 void ExtensionSet::SetAllocatedMessage(int number, FieldType type,
    486                                        const FieldDescriptor* descriptor,
    487                                        MessageLite* message) {
    488   if (message == NULL) {
    489     ClearExtension(number);
    490     return;
    491   }
    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;
    499   } else {
    500     GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
    501     if (extension->is_lazy) {
    502       extension->lazymessage_value->SetAllocatedMessage(message);
    503     } else {
    504       delete extension->message_value;
    505       extension->message_value = message;
    506     }
    507   }
    508   extension->is_cleared = false;
    509 }
    510 
    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.
    516     return NULL;
    517   } else {
    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;
    523     } else {
    524       ret = iter->second.message_value;
    525     }
    526     extensions_.erase(number);
    527     return ret;
    528   }
    529 }
    530 
    531 // Defined in extension_set_heavy.cc.
    532 // MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
    533 //                                           MessageFactory* factory);
    534 
    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);
    541 }
    542 
    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);
    548 }
    549 
    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>();
    560   } else {
    561     GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
    562   }
    563 
    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);
    571   }
    572   return result;
    573 }
    574 
    575 // Defined in extension_set_heavy.cc.
    576 // MessageLite* ExtensionSet::AddMessage(int number, FieldType type,
    577 //                                       const Descriptor* message_type,
    578 //                                       MessageFactory* factory)
    579 
    580 #undef GOOGLE_DCHECK_TYPE
    581 
    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).";
    585 
    586   Extension* extension = &iter->second;
    587   GOOGLE_DCHECK(extension->is_repeated);
    588 
    589   switch(cpp_type(extension->type)) {
    590     case WireFormatLite::CPPTYPE_INT32:
    591       extension->repeated_int32_value->RemoveLast();
    592       break;
    593     case WireFormatLite::CPPTYPE_INT64:
    594       extension->repeated_int64_value->RemoveLast();
    595       break;
    596     case WireFormatLite::CPPTYPE_UINT32:
    597       extension->repeated_uint32_value->RemoveLast();
    598       break;
    599     case WireFormatLite::CPPTYPE_UINT64:
    600       extension->repeated_uint64_value->RemoveLast();
    601       break;
    602     case WireFormatLite::CPPTYPE_FLOAT:
    603       extension->repeated_float_value->RemoveLast();
    604       break;
    605     case WireFormatLite::CPPTYPE_DOUBLE:
    606       extension->repeated_double_value->RemoveLast();
    607       break;
    608     case WireFormatLite::CPPTYPE_BOOL:
    609       extension->repeated_bool_value->RemoveLast();
    610       break;
    611     case WireFormatLite::CPPTYPE_ENUM:
    612       extension->repeated_enum_value->RemoveLast();
    613       break;
    614     case WireFormatLite::CPPTYPE_STRING:
    615       extension->repeated_string_value->RemoveLast();
    616       break;
    617     case WireFormatLite::CPPTYPE_MESSAGE:
    618       extension->repeated_message_value->RemoveLast();
    619       break;
    620   }
    621 }
    622 
    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).";
    626 
    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();
    631 }
    632 
    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).";
    636 
    637   Extension* extension = &iter->second;
    638   GOOGLE_DCHECK(extension->is_repeated);
    639 
    640   switch(cpp_type(extension->type)) {
    641     case WireFormatLite::CPPTYPE_INT32:
    642       extension->repeated_int32_value->SwapElements(index1, index2);
    643       break;
    644     case WireFormatLite::CPPTYPE_INT64:
    645       extension->repeated_int64_value->SwapElements(index1, index2);
    646       break;
    647     case WireFormatLite::CPPTYPE_UINT32:
    648       extension->repeated_uint32_value->SwapElements(index1, index2);
    649       break;
    650     case WireFormatLite::CPPTYPE_UINT64:
    651       extension->repeated_uint64_value->SwapElements(index1, index2);
    652       break;
    653     case WireFormatLite::CPPTYPE_FLOAT:
    654       extension->repeated_float_value->SwapElements(index1, index2);
    655       break;
    656     case WireFormatLite::CPPTYPE_DOUBLE:
    657       extension->repeated_double_value->SwapElements(index1, index2);
    658       break;
    659     case WireFormatLite::CPPTYPE_BOOL:
    660       extension->repeated_bool_value->SwapElements(index1, index2);
    661       break;
    662     case WireFormatLite::CPPTYPE_ENUM:
    663       extension->repeated_enum_value->SwapElements(index1, index2);
    664       break;
    665     case WireFormatLite::CPPTYPE_STRING:
    666       extension->repeated_string_value->SwapElements(index1, index2);
    667       break;
    668     case WireFormatLite::CPPTYPE_MESSAGE:
    669       extension->repeated_message_value->SwapElements(index1, index2);
    670       break;
    671   }
    672 }
    673 
    674 // ===================================================================
    675 
    676 void ExtensionSet::Clear() {
    677   for (map<int, Extension>::iterator iter = extensions_.begin();
    678        iter != extensions_.end(); ++iter) {
    679     iter->second.Clear();
    680   }
    681 }
    682 
    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;
    687 
    688     if (other_extension.is_repeated) {
    689       Extension* extension;
    690       bool is_new = MaybeNewExtension(iter->first, other_extension.descriptor,
    691                                       &extension);
    692       if (is_new) {
    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;
    697       } else {
    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);
    701       }
    702 
    703       switch (cpp_type(other_extension.type)) {
    704 #define HANDLE_TYPE(UPPERCASE, LOWERCASE, REPEATED_TYPE)             \
    705         case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
    706           if (is_new) {                                              \
    707             extension->repeated_##LOWERCASE##_value =                \
    708               new REPEATED_TYPE;                                     \
    709           }                                                          \
    710           extension->repeated_##LOWERCASE##_value->MergeFrom(        \
    711             *other_extension.repeated_##LOWERCASE##_value);          \
    712           break;
    713 
    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>);
    723 #undef HANDLE_TYPE
    724 
    725         case WireFormatLite::CPPTYPE_MESSAGE:
    726           if (is_new) {
    727             extension->repeated_message_value =
    728               new RepeatedPtrField<MessageLite>();
    729           }
    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);
    741             }
    742             target->CheckTypeAndMergeFrom(other_message);
    743           }
    744           break;
    745       }
    746     } else {
    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);                      \
    754             break;
    755 
    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);
    764 #undef HANDLE_TYPE
    765           case WireFormatLite::CPPTYPE_STRING:
    766             SetString(iter->first, other_extension.type,
    767                       *other_extension.string_value,
    768                       other_extension.descriptor);
    769             break;
    770           case WireFormatLite::CPPTYPE_MESSAGE: {
    771             Extension* extension;
    772             bool is_new = MaybeNewExtension(iter->first,
    773                                             other_extension.descriptor,
    774                                             &extension);
    775             if (is_new) {
    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);
    785               } else {
    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);
    791               }
    792             } else {
    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);
    800                 } else {
    801                   extension->message_value->CheckTypeAndMergeFrom(
    802                       other_extension.lazymessage_value->GetMessage(
    803                           *extension->message_value));
    804                 }
    805               } else {
    806                 if (extension->is_lazy) {
    807                   extension->lazymessage_value->MutableMessage(
    808                       *other_extension.message_value)->CheckTypeAndMergeFrom(
    809                           *other_extension.message_value);
    810                 } else {
    811                   extension->message_value->CheckTypeAndMergeFrom(
    812                       *other_extension.message_value);
    813                 }
    814               }
    815             }
    816             extension->is_cleared = false;
    817             break;
    818           }
    819         }
    820       }
    821     }
    822   }
    823 }
    824 
    825 void ExtensionSet::Swap(ExtensionSet* x) {
    826   extensions_.swap(x->extensions_);
    827 }
    828 
    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()) {
    839             return false;
    840           }
    841         }
    842       } else {
    843         if (!extension.is_cleared) {
    844           if (extension.is_lazy) {
    845             if (!extension.lazymessage_value->IsInitialized()) return false;
    846           } else {
    847             if (!extension.message_value->IsInitialized()) return false;
    848           }
    849         }
    850       }
    851     }
    852   }
    853 
    854   return true;
    855 }
    856 
    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);
    862 
    863   bool is_unknown;
    864   if (!extension_finder->Find(*field_number, extension)) {
    865     is_unknown = true;
    866   } else if (extension->is_packed) {
    867     is_unknown = (wire_type != WireFormatLite::WIRETYPE_LENGTH_DELIMITED);
    868   } else {
    869     WireFormatLite::WireType expected_wire_type =
    870         WireFormatLite::WireTypeForFieldType(real_type(extension->type));
    871     is_unknown = (wire_type != expected_wire_type);
    872   }
    873   return !is_unknown;
    874 }
    875 
    876 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
    877                               ExtensionFinder* extension_finder,
    878                               FieldSkipper* field_skipper) {
    879   int number;
    880   ExtensionInfo extension;
    881   if (!FindExtensionInfoFromTag(tag, extension_finder, &number, &extension)) {
    882     return field_skipper->SkipField(input, tag);
    883   } else {
    884     return ParseFieldWithExtensionInfo(number, extension, input, field_skipper);
    885   }
    886 }
    887 
    888 bool ExtensionSet::ParseFieldWithExtensionInfo(
    889     int number, const ExtensionInfo& extension,
    890     io::CodedInputStream* input,
    891     FieldSkipper* field_skipper) {
    892   if (extension.is_packed) {
    893     uint32 size;
    894     if (!input->ReadVarint32(&size)) return false;
    895     io::CodedInputStream::Limit limit = input->PushLimit(size);
    896 
    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);               \
    907         }                                                                      \
    908         break
    909 
    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);
    923 #undef HANDLE_TYPE
    924 
    925       case WireFormatLite::TYPE_ENUM:
    926         while (input->BytesUntilLimit() > 0) {
    927           int value;
    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);
    934           }
    935         }
    936         break;
    937 
    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.";
    943         break;
    944     }
    945 
    946     input->PopLimit(limit);
    947   } else {
    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);              \
    958         } else {                                                               \
    959           Set##CPP_CAMELCASE(number, WireFormatLite::TYPE_##UPPERCASE, value,  \
    960                              extension.descriptor);                            \
    961         }                                                                      \
    962       } break
    963 
    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);
    977 #undef HANDLE_TYPE
    978 
    979       case WireFormatLite::TYPE_ENUM: {
    980         int value;
    981         if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
    982                 input, &value)) return false;
    983 
    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);
    991         } else {
    992           SetEnum(number, WireFormatLite::TYPE_ENUM, value,
    993                   extension.descriptor);
    994         }
    995         break;
    996       }
    997 
    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;
   1004         break;
   1005       }
   1006 
   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;
   1013         break;
   1014       }
   1015 
   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;
   1023         break;
   1024       }
   1025 
   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;
   1033         break;
   1034       }
   1035     }
   1036   }
   1037 
   1038   return true;
   1039 }
   1040 
   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);
   1047 }
   1048 
   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)
   1053 
   1054 // Defined in extension_set_heavy.cc.
   1055 // bool ExtensionSet::ParseMessageSetHeavy(io::CodedInputStream* input,
   1056 //                                         const Message* containing_type,
   1057 //                                         UnknownFieldSet* unknown_fields);
   1058 
   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;
   1065        ++iter) {
   1066     iter->second.SerializeFieldWithCachedSizes(iter->first, output);
   1067   }
   1068 }
   1069 
   1070 int ExtensionSet::ByteSize() const {
   1071   int total_size = 0;
   1072 
   1073   for (map<int, Extension>::const_iterator iter = extensions_.begin();
   1074        iter != extensions_.end(); ++iter) {
   1075     total_size += iter->second.ByteSize(iter->first);
   1076   }
   1077 
   1078   return total_size;
   1079 }
   1080 
   1081 // Defined in extension_set_heavy.cc.
   1082 // int ExtensionSet::SpaceUsedExcludingSelf() const
   1083 
   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;
   1092 }
   1093 
   1094 // ===================================================================
   1095 // Methods of ExtensionSet::Extension
   1096 
   1097 void ExtensionSet::Extension::Clear() {
   1098   if (is_repeated) {
   1099     switch (cpp_type(type)) {
   1100 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
   1101       case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
   1102         repeated_##LOWERCASE##_value->Clear();                     \
   1103         break
   1104 
   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);
   1115 #undef HANDLE_TYPE
   1116     }
   1117   } else {
   1118     if (!is_cleared) {
   1119       switch (cpp_type(type)) {
   1120         case WireFormatLite::CPPTYPE_STRING:
   1121           string_value->clear();
   1122           break;
   1123         case WireFormatLite::CPPTYPE_MESSAGE:
   1124           if (is_lazy) {
   1125             lazymessage_value->Clear();
   1126           } else {
   1127             message_value->Clear();
   1128           }
   1129           break;
   1130         default:
   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
   1133           // previous value.
   1134           break;
   1135       }
   1136 
   1137       is_cleared = true;
   1138     }
   1139   }
   1140 }
   1141 
   1142 void ExtensionSet::Extension::SerializeFieldWithCachedSizes(
   1143     int number,
   1144     io::CodedOutputStream* output) const {
   1145   if (is_repeated) {
   1146     if (is_packed) {
   1147       if (cached_size == 0) return;
   1148 
   1149       WireFormatLite::WriteTag(number,
   1150           WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
   1151       output->WriteVarint32(cached_size);
   1152 
   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);                \
   1159           }                                                                 \
   1160           break
   1161 
   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);
   1176 #undef HANDLE_TYPE
   1177 
   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.";
   1183           break;
   1184       }
   1185     } else {
   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);                \
   1192           }                                                                 \
   1193           break
   1194 
   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);
   1213 #undef HANDLE_TYPE
   1214       }
   1215     }
   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); \
   1221         break
   1222 
   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);
   1240 #undef HANDLE_TYPE
   1241       case WireFormatLite::TYPE_MESSAGE:
   1242         if (is_lazy) {
   1243           lazymessage_value->WriteMessage(number, output);
   1244         } else {
   1245           WireFormatLite::WriteMessage(number, *message_value, output);
   1246         }
   1247         break;
   1248     }
   1249   }
   1250 }
   1251 
   1252 int ExtensionSet::Extension::ByteSize(int number) const {
   1253   int result = 0;
   1254 
   1255   if (is_repeated) {
   1256     if (is_packed) {
   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));                        \
   1263           }                                                                 \
   1264           break
   1265 
   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);
   1273 #undef HANDLE_TYPE
   1274 
   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();                   \
   1280           break
   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);
   1288 #undef HANDLE_TYPE
   1289 
   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.";
   1295           break;
   1296       }
   1297 
   1298       cached_size = result;
   1299       if (result > 0) {
   1300         result += io::CodedOutputStream::VarintSize32(result);
   1301         result += io::CodedOutputStream::VarintSize32(
   1302             WireFormatLite::MakeTag(number,
   1303                 WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
   1304       }
   1305     } else {
   1306       int tag_size = WireFormatLite::TagSize(number, real_type(type));
   1307 
   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));                        \
   1315           }                                                                 \
   1316           break
   1317 
   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);
   1329 #undef HANDLE_TYPE
   1330 
   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();                   \
   1336           break
   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);
   1344 #undef HANDLE_TYPE
   1345       }
   1346     }
   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);             \
   1353         break
   1354 
   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);
   1365 #undef HANDLE_TYPE
   1366       case WireFormatLite::TYPE_MESSAGE: {
   1367         if (is_lazy) {
   1368           int size = lazymessage_value->ByteSize();
   1369           result += io::CodedOutputStream::VarintSize32(size) + size;
   1370         } else {
   1371           result += WireFormatLite::MessageSize(*message_value);
   1372         }
   1373         break;
   1374       }
   1375 
   1376       // Stuff with fixed size.
   1377 #define HANDLE_TYPE(UPPERCASE, CAMELCASE)                                 \
   1378       case WireFormatLite::TYPE_##UPPERCASE:                              \
   1379         result += WireFormatLite::k##CAMELCASE##Size;                     \
   1380         break
   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);
   1388 #undef HANDLE_TYPE
   1389     }
   1390   }
   1391 
   1392   return result;
   1393 }
   1394 
   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()
   1401 
   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);
   1412 #undef HANDLE_TYPE
   1413   }
   1414 
   1415   GOOGLE_LOG(FATAL) << "Can't get here.";
   1416   return 0;
   1417 }
   1418 
   1419 void ExtensionSet::Extension::Free() {
   1420   if (is_repeated) {
   1421     switch (cpp_type(type)) {
   1422 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
   1423       case WireFormatLite::CPPTYPE_##UPPERCASE:                    \
   1424         delete repeated_##LOWERCASE##_value;                       \
   1425         break
   1426 
   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);
   1437 #undef HANDLE_TYPE
   1438     }
   1439   } else {
   1440     switch (cpp_type(type)) {
   1441       case WireFormatLite::CPPTYPE_STRING:
   1442         delete string_value;
   1443         break;
   1444       case WireFormatLite::CPPTYPE_MESSAGE:
   1445         if (is_lazy) {
   1446           delete lazymessage_value;
   1447         } else {
   1448           delete message_value;
   1449         }
   1450         break;
   1451       default:
   1452         break;
   1453     }
   1454   }
   1455 }
   1456 
   1457 // Defined in extension_set_heavy.cc.
   1458 // int ExtensionSet::Extension::SpaceUsedExcludingSelf() const
   1459 
   1460 }  // namespace internal
   1461 }  // namespace protobuf
   1462 }  // namespace google
   1463