Home | History | Annotate | Download | only in protobuf
      1 // Protocol Buffers - Google's data interchange format
      2 // Copyright 2008 Google Inc.  All rights reserved.
      3 // https://developers.google.com/protocol-buffers/
      4 //
      5 // Redistribution and use in source and binary forms, with or without
      6 // modification, are permitted provided that the following conditions are
      7 // met:
      8 //
      9 //     * Redistributions of source code must retain the above copyright
     10 // notice, this list of conditions and the following disclaimer.
     11 //     * Redistributions in binary form must reproduce the above
     12 // copyright notice, this list of conditions and the following disclaimer
     13 // in the documentation and/or other materials provided with the
     14 // distribution.
     15 //     * Neither the name of Google Inc. nor the names of its
     16 // contributors may be used to endorse or promote products derived from
     17 // this software without specific prior written permission.
     18 //
     19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30 
     31 // Author: kenton (at) google.com (Kenton Varda)
     32 //  Based on original Protocol Buffers design by
     33 //  Sanjay Ghemawat, Jeff Dean, and others.
     34 //
     35 // Contains methods defined in extension_set.h which cannot be part of the
     36 // lite library because they use descriptors or reflection.
     37 
     38 #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
     39 #include <google/protobuf/descriptor.h>
     40 #include <google/protobuf/extension_set.h>
     41 #include <google/protobuf/message.h>
     42 #include <google/protobuf/repeated_field.h>
     43 #include <google/protobuf/wire_format.h>
     44 #include <google/protobuf/wire_format_lite_inl.h>
     45 
     46 namespace google {
     47 
     48 namespace protobuf {
     49 namespace internal {
     50 
     51 // A FieldSkipper used to store unknown MessageSet fields into UnknownFieldSet.
     52 class MessageSetFieldSkipper
     53     : public UnknownFieldSetFieldSkipper {
     54  public:
     55   explicit MessageSetFieldSkipper(UnknownFieldSet* unknown_fields)
     56       : UnknownFieldSetFieldSkipper(unknown_fields) {}
     57   virtual ~MessageSetFieldSkipper() {}
     58 
     59   virtual bool SkipMessageSetField(io::CodedInputStream* input,
     60                                    int field_number);
     61 };
     62 bool MessageSetFieldSkipper::SkipMessageSetField(
     63     io::CodedInputStream* input, int field_number) {
     64   uint32 length;
     65   if (!input->ReadVarint32(&length)) return false;
     66   if (unknown_fields_ == NULL) {
     67     return input->Skip(length);
     68   } else {
     69     return input->ReadString(
     70         unknown_fields_->AddLengthDelimited(field_number), length);
     71   }
     72 }
     73 
     74 
     75 // Implementation of ExtensionFinder which finds extensions in a given
     76 // DescriptorPool, using the given MessageFactory to construct sub-objects.
     77 // This class is implemented in extension_set_heavy.cc.
     78 class DescriptorPoolExtensionFinder : public ExtensionFinder {
     79  public:
     80   DescriptorPoolExtensionFinder(const DescriptorPool* pool,
     81                                 MessageFactory* factory,
     82                                 const Descriptor* containing_type)
     83       : pool_(pool), factory_(factory), containing_type_(containing_type) {}
     84   virtual ~DescriptorPoolExtensionFinder() {}
     85 
     86   virtual bool Find(int number, ExtensionInfo* output);
     87 
     88  private:
     89   const DescriptorPool* pool_;
     90   MessageFactory* factory_;
     91   const Descriptor* containing_type_;
     92 };
     93 
     94 void ExtensionSet::AppendToList(const Descriptor* containing_type,
     95                                 const DescriptorPool* pool,
     96                                 std::vector<const FieldDescriptor*>* output) const {
     97   for (map<int, Extension>::const_iterator iter = extensions_.begin();
     98        iter != extensions_.end(); ++iter) {
     99     bool has = false;
    100     if (iter->second.is_repeated) {
    101       has = iter->second.GetSize() > 0;
    102     } else {
    103       has = !iter->second.is_cleared;
    104     }
    105 
    106     if (has) {
    107       // TODO(kenton): Looking up each field by number is somewhat unfortunate.
    108       //   Is there a better way?  The problem is that descriptors are lazily-
    109       //   initialized, so they might not even be constructed until
    110       //   AppendToList() is called.
    111 
    112       if (iter->second.descriptor == NULL) {
    113         output->push_back(pool->FindExtensionByNumber(
    114             containing_type, iter->first));
    115       } else {
    116         output->push_back(iter->second.descriptor);
    117       }
    118     }
    119   }
    120 }
    121 
    122 inline FieldDescriptor::Type real_type(FieldType type) {
    123   GOOGLE_DCHECK(type > 0 && type <= FieldDescriptor::MAX_TYPE);
    124   return static_cast<FieldDescriptor::Type>(type);
    125 }
    126 
    127 inline FieldDescriptor::CppType cpp_type(FieldType type) {
    128   return FieldDescriptor::TypeToCppType(
    129       static_cast<FieldDescriptor::Type>(type));
    130 }
    131 
    132 inline WireFormatLite::FieldType field_type(FieldType type) {
    133   GOOGLE_DCHECK(type > 0 && type <= WireFormatLite::MAX_FIELD_TYPE);
    134   return static_cast<WireFormatLite::FieldType>(type);
    135 }
    136 
    137 #define GOOGLE_DCHECK_TYPE(EXTENSION, LABEL, CPPTYPE)                            \
    138   GOOGLE_DCHECK_EQ((EXTENSION).is_repeated ? FieldDescriptor::LABEL_REPEATED     \
    139                                   : FieldDescriptor::LABEL_OPTIONAL,      \
    140             FieldDescriptor::LABEL_##LABEL);                              \
    141   GOOGLE_DCHECK_EQ(cpp_type((EXTENSION).type), FieldDescriptor::CPPTYPE_##CPPTYPE)
    142 
    143 const MessageLite& ExtensionSet::GetMessage(int number,
    144                                             const Descriptor* message_type,
    145                                             MessageFactory* factory) const {
    146   map<int, Extension>::const_iterator iter = extensions_.find(number);
    147   if (iter == extensions_.end() || iter->second.is_cleared) {
    148     // Not present.  Return the default value.
    149     return *factory->GetPrototype(message_type);
    150   } else {
    151     GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
    152     if (iter->second.is_lazy) {
    153       return iter->second.lazymessage_value->GetMessage(
    154           *factory->GetPrototype(message_type));
    155     } else {
    156       return *iter->second.message_value;
    157     }
    158   }
    159 }
    160 
    161 MessageLite* ExtensionSet::MutableMessage(const FieldDescriptor* descriptor,
    162                                           MessageFactory* factory) {
    163   Extension* extension;
    164   if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
    165     extension->type = descriptor->type();
    166     GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
    167     extension->is_repeated = false;
    168     extension->is_packed = false;
    169     const MessageLite* prototype =
    170         factory->GetPrototype(descriptor->message_type());
    171     extension->is_lazy = false;
    172     extension->message_value = prototype->New();
    173     extension->is_cleared = false;
    174     return extension->message_value;
    175   } else {
    176     GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
    177     extension->is_cleared = false;
    178     if (extension->is_lazy) {
    179       return extension->lazymessage_value->MutableMessage(
    180           *factory->GetPrototype(descriptor->message_type()));
    181     } else {
    182       return extension->message_value;
    183     }
    184   }
    185 }
    186 
    187 MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
    188                                           MessageFactory* factory) {
    189   map<int, Extension>::iterator iter = extensions_.find(descriptor->number());
    190   if (iter == extensions_.end()) {
    191     // Not present.  Return NULL.
    192     return NULL;
    193   } else {
    194     GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
    195     MessageLite* ret = NULL;
    196     if (iter->second.is_lazy) {
    197       ret = iter->second.lazymessage_value->ReleaseMessage(
    198           *factory->GetPrototype(descriptor->message_type()));
    199       delete iter->second.lazymessage_value;
    200     } else {
    201       ret = iter->second.message_value;
    202     }
    203     extensions_.erase(descriptor->number());
    204     return ret;
    205   }
    206 }
    207 
    208 MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor,
    209                                       MessageFactory* factory) {
    210   Extension* extension;
    211   if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
    212     extension->type = descriptor->type();
    213     GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
    214     extension->is_repeated = true;
    215     extension->repeated_message_value =
    216       new RepeatedPtrField<MessageLite>();
    217   } else {
    218     GOOGLE_DCHECK_TYPE(*extension, REPEATED, MESSAGE);
    219   }
    220 
    221   // RepeatedPtrField<Message> does not know how to Add() since it cannot
    222   // allocate an abstract object, so we have to be tricky.
    223   MessageLite* result = extension->repeated_message_value
    224       ->AddFromCleared<GenericTypeHandler<MessageLite> >();
    225   if (result == NULL) {
    226     const MessageLite* prototype;
    227     if (extension->repeated_message_value->size() == 0) {
    228       prototype = factory->GetPrototype(descriptor->message_type());
    229       GOOGLE_CHECK(prototype != NULL);
    230     } else {
    231       prototype = &extension->repeated_message_value->Get(0);
    232     }
    233     result = prototype->New();
    234     extension->repeated_message_value->AddAllocated(result);
    235   }
    236   return result;
    237 }
    238 
    239 static bool ValidateEnumUsingDescriptor(const void* arg, int number) {
    240   return reinterpret_cast<const EnumDescriptor*>(arg)
    241       ->FindValueByNumber(number) != NULL;
    242 }
    243 
    244 bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) {
    245   const FieldDescriptor* extension =
    246       pool_->FindExtensionByNumber(containing_type_, number);
    247   if (extension == NULL) {
    248     return false;
    249   } else {
    250     output->type = extension->type();
    251     output->is_repeated = extension->is_repeated();
    252     output->is_packed = extension->options().packed();
    253     output->descriptor = extension;
    254     if (extension->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
    255       output->message_prototype =
    256           factory_->GetPrototype(extension->message_type());
    257       GOOGLE_CHECK(output->message_prototype != NULL)
    258           << "Extension factory's GetPrototype() returned NULL for extension: "
    259           << extension->full_name();
    260     } else if (extension->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
    261       output->enum_validity_check.func = ValidateEnumUsingDescriptor;
    262       output->enum_validity_check.arg = extension->enum_type();
    263     }
    264 
    265     return true;
    266   }
    267 }
    268 
    269 bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
    270                               const Message* containing_type,
    271                               UnknownFieldSet* unknown_fields) {
    272   UnknownFieldSetFieldSkipper skipper(unknown_fields);
    273   if (input->GetExtensionPool() == NULL) {
    274     GeneratedExtensionFinder finder(containing_type);
    275     return ParseField(tag, input, &finder, &skipper);
    276   } else {
    277     DescriptorPoolExtensionFinder finder(input->GetExtensionPool(),
    278                                          input->GetExtensionFactory(),
    279                                          containing_type->GetDescriptor());
    280     return ParseField(tag, input, &finder, &skipper);
    281   }
    282 }
    283 
    284 bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
    285                                    const Message* containing_type,
    286                                    UnknownFieldSet* unknown_fields) {
    287   MessageSetFieldSkipper skipper(unknown_fields);
    288   if (input->GetExtensionPool() == NULL) {
    289     GeneratedExtensionFinder finder(containing_type);
    290     return ParseMessageSet(input, &finder, &skipper);
    291   } else {
    292     DescriptorPoolExtensionFinder finder(input->GetExtensionPool(),
    293                                          input->GetExtensionFactory(),
    294                                          containing_type->GetDescriptor());
    295     return ParseMessageSet(input, &finder, &skipper);
    296   }
    297 }
    298 
    299 int ExtensionSet::SpaceUsedExcludingSelf() const {
    300   int total_size =
    301       extensions_.size() * sizeof(map<int, Extension>::value_type);
    302   for (map<int, Extension>::const_iterator iter = extensions_.begin(),
    303        end = extensions_.end();
    304        iter != end;
    305        ++iter) {
    306     total_size += iter->second.SpaceUsedExcludingSelf();
    307   }
    308   return total_size;
    309 }
    310 
    311 inline int ExtensionSet::RepeatedMessage_SpaceUsedExcludingSelf(
    312     RepeatedPtrFieldBase* field) {
    313   return field->SpaceUsedExcludingSelf<GenericTypeHandler<Message> >();
    314 }
    315 
    316 int ExtensionSet::Extension::SpaceUsedExcludingSelf() const {
    317   int total_size = 0;
    318   if (is_repeated) {
    319     switch (cpp_type(type)) {
    320 #define HANDLE_TYPE(UPPERCASE, LOWERCASE)                          \
    321       case FieldDescriptor::CPPTYPE_##UPPERCASE:                   \
    322         total_size += sizeof(*repeated_##LOWERCASE##_value) +      \
    323             repeated_##LOWERCASE##_value->SpaceUsedExcludingSelf();\
    324         break
    325 
    326       HANDLE_TYPE(  INT32,   int32);
    327       HANDLE_TYPE(  INT64,   int64);
    328       HANDLE_TYPE( UINT32,  uint32);
    329       HANDLE_TYPE( UINT64,  uint64);
    330       HANDLE_TYPE(  FLOAT,   float);
    331       HANDLE_TYPE( DOUBLE,  double);
    332       HANDLE_TYPE(   BOOL,    bool);
    333       HANDLE_TYPE(   ENUM,    enum);
    334       HANDLE_TYPE( STRING,  string);
    335 #undef HANDLE_TYPE
    336 
    337       case FieldDescriptor::CPPTYPE_MESSAGE:
    338         // repeated_message_value is actually a RepeatedPtrField<MessageLite>,
    339         // but MessageLite has no SpaceUsed(), so we must directly call
    340         // RepeatedPtrFieldBase::SpaceUsedExcludingSelf() with a different type
    341         // handler.
    342         total_size += sizeof(*repeated_message_value) +
    343             RepeatedMessage_SpaceUsedExcludingSelf(repeated_message_value);
    344         break;
    345     }
    346   } else {
    347     switch (cpp_type(type)) {
    348       case FieldDescriptor::CPPTYPE_STRING:
    349         total_size += sizeof(*string_value) +
    350                       StringSpaceUsedExcludingSelf(*string_value);
    351         break;
    352       case FieldDescriptor::CPPTYPE_MESSAGE:
    353         if (is_lazy) {
    354           total_size += lazymessage_value->SpaceUsed();
    355         } else {
    356           total_size += down_cast<Message*>(message_value)->SpaceUsed();
    357         }
    358         break;
    359       default:
    360         // No extra storage costs for primitive types.
    361         break;
    362     }
    363   }
    364   return total_size;
    365 }
    366 
    367 // The Serialize*ToArray methods are only needed in the heavy library, as
    368 // the lite library only generates SerializeWithCachedSizes.
    369 uint8* ExtensionSet::SerializeWithCachedSizesToArray(
    370     int start_field_number, int end_field_number,
    371     uint8* target) const {
    372   map<int, Extension>::const_iterator iter;
    373   for (iter = extensions_.lower_bound(start_field_number);
    374        iter != extensions_.end() && iter->first < end_field_number;
    375        ++iter) {
    376     target = iter->second.SerializeFieldWithCachedSizesToArray(iter->first,
    377                                                                target);
    378   }
    379   return target;
    380 }
    381 
    382 uint8* ExtensionSet::SerializeMessageSetWithCachedSizesToArray(
    383     uint8* target) const {
    384   map<int, Extension>::const_iterator iter;
    385   for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
    386     target = iter->second.SerializeMessageSetItemWithCachedSizesToArray(
    387         iter->first, target);
    388   }
    389   return target;
    390 }
    391 
    392 uint8* ExtensionSet::Extension::SerializeFieldWithCachedSizesToArray(
    393     int number, uint8* target) const {
    394   if (is_repeated) {
    395     if (is_packed) {
    396       if (cached_size == 0) return target;
    397 
    398       target = WireFormatLite::WriteTagToArray(number,
    399           WireFormatLite::WIRETYPE_LENGTH_DELIMITED, target);
    400       target = WireFormatLite::WriteInt32NoTagToArray(cached_size, target);
    401 
    402       switch (real_type(type)) {
    403 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
    404         case FieldDescriptor::TYPE_##UPPERCASE:                             \
    405           for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
    406             target = WireFormatLite::Write##CAMELCASE##NoTagToArray(        \
    407               repeated_##LOWERCASE##_value->Get(i), target);                \
    408           }                                                                 \
    409           break
    410 
    411         HANDLE_TYPE(   INT32,    Int32,   int32);
    412         HANDLE_TYPE(   INT64,    Int64,   int64);
    413         HANDLE_TYPE(  UINT32,   UInt32,  uint32);
    414         HANDLE_TYPE(  UINT64,   UInt64,  uint64);
    415         HANDLE_TYPE(  SINT32,   SInt32,   int32);
    416         HANDLE_TYPE(  SINT64,   SInt64,   int64);
    417         HANDLE_TYPE( FIXED32,  Fixed32,  uint32);
    418         HANDLE_TYPE( FIXED64,  Fixed64,  uint64);
    419         HANDLE_TYPE(SFIXED32, SFixed32,   int32);
    420         HANDLE_TYPE(SFIXED64, SFixed64,   int64);
    421         HANDLE_TYPE(   FLOAT,    Float,   float);
    422         HANDLE_TYPE(  DOUBLE,   Double,  double);
    423         HANDLE_TYPE(    BOOL,     Bool,    bool);
    424         HANDLE_TYPE(    ENUM,     Enum,    enum);
    425 #undef HANDLE_TYPE
    426 
    427         case WireFormatLite::TYPE_STRING:
    428         case WireFormatLite::TYPE_BYTES:
    429         case WireFormatLite::TYPE_GROUP:
    430         case WireFormatLite::TYPE_MESSAGE:
    431           GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
    432           break;
    433       }
    434     } else {
    435       switch (real_type(type)) {
    436 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, LOWERCASE)                        \
    437         case FieldDescriptor::TYPE_##UPPERCASE:                             \
    438           for (int i = 0; i < repeated_##LOWERCASE##_value->size(); i++) {  \
    439             target = WireFormatLite::Write##CAMELCASE##ToArray(number,      \
    440               repeated_##LOWERCASE##_value->Get(i), target);                \
    441           }                                                                 \
    442           break
    443 
    444         HANDLE_TYPE(   INT32,    Int32,   int32);
    445         HANDLE_TYPE(   INT64,    Int64,   int64);
    446         HANDLE_TYPE(  UINT32,   UInt32,  uint32);
    447         HANDLE_TYPE(  UINT64,   UInt64,  uint64);
    448         HANDLE_TYPE(  SINT32,   SInt32,   int32);
    449         HANDLE_TYPE(  SINT64,   SInt64,   int64);
    450         HANDLE_TYPE( FIXED32,  Fixed32,  uint32);
    451         HANDLE_TYPE( FIXED64,  Fixed64,  uint64);
    452         HANDLE_TYPE(SFIXED32, SFixed32,   int32);
    453         HANDLE_TYPE(SFIXED64, SFixed64,   int64);
    454         HANDLE_TYPE(   FLOAT,    Float,   float);
    455         HANDLE_TYPE(  DOUBLE,   Double,  double);
    456         HANDLE_TYPE(    BOOL,     Bool,    bool);
    457         HANDLE_TYPE(  STRING,   String,  string);
    458         HANDLE_TYPE(   BYTES,    Bytes,  string);
    459         HANDLE_TYPE(    ENUM,     Enum,    enum);
    460         HANDLE_TYPE(   GROUP,    Group, message);
    461         HANDLE_TYPE( MESSAGE,  Message, message);
    462 #undef HANDLE_TYPE
    463       }
    464     }
    465   } else if (!is_cleared) {
    466     switch (real_type(type)) {
    467 #define HANDLE_TYPE(UPPERCASE, CAMELCASE, VALUE)                 \
    468       case FieldDescriptor::TYPE_##UPPERCASE:                    \
    469         target = WireFormatLite::Write##CAMELCASE##ToArray(      \
    470             number, VALUE, target); \
    471         break
    472 
    473       HANDLE_TYPE(   INT32,    Int32,    int32_value);
    474       HANDLE_TYPE(   INT64,    Int64,    int64_value);
    475       HANDLE_TYPE(  UINT32,   UInt32,   uint32_value);
    476       HANDLE_TYPE(  UINT64,   UInt64,   uint64_value);
    477       HANDLE_TYPE(  SINT32,   SInt32,    int32_value);
    478       HANDLE_TYPE(  SINT64,   SInt64,    int64_value);
    479       HANDLE_TYPE( FIXED32,  Fixed32,   uint32_value);
    480       HANDLE_TYPE( FIXED64,  Fixed64,   uint64_value);
    481       HANDLE_TYPE(SFIXED32, SFixed32,    int32_value);
    482       HANDLE_TYPE(SFIXED64, SFixed64,    int64_value);
    483       HANDLE_TYPE(   FLOAT,    Float,    float_value);
    484       HANDLE_TYPE(  DOUBLE,   Double,   double_value);
    485       HANDLE_TYPE(    BOOL,     Bool,     bool_value);
    486       HANDLE_TYPE(  STRING,   String,  *string_value);
    487       HANDLE_TYPE(   BYTES,    Bytes,  *string_value);
    488       HANDLE_TYPE(    ENUM,     Enum,     enum_value);
    489       HANDLE_TYPE(   GROUP,    Group, *message_value);
    490 #undef HANDLE_TYPE
    491       case FieldDescriptor::TYPE_MESSAGE:
    492         if (is_lazy) {
    493           target = lazymessage_value->WriteMessageToArray(number, target);
    494         } else {
    495           target = WireFormatLite::WriteMessageToArray(
    496               number, *message_value, target);
    497         }
    498         break;
    499     }
    500   }
    501   return target;
    502 }
    503 
    504 uint8* ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizesToArray(
    505     int number,
    506     uint8* target) const {
    507   if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
    508     // Not a valid MessageSet extension, but serialize it the normal way.
    509     GOOGLE_LOG(WARNING) << "Invalid message set extension.";
    510     return SerializeFieldWithCachedSizesToArray(number, target);
    511   }
    512 
    513   if (is_cleared) return target;
    514 
    515   // Start group.
    516   target = io::CodedOutputStream::WriteTagToArray(
    517       WireFormatLite::kMessageSetItemStartTag, target);
    518   // Write type ID.
    519   target = WireFormatLite::WriteUInt32ToArray(
    520       WireFormatLite::kMessageSetTypeIdNumber, number, target);
    521   // Write message.
    522   if (is_lazy) {
    523     target = lazymessage_value->WriteMessageToArray(
    524         WireFormatLite::kMessageSetMessageNumber, target);
    525   } else {
    526     target = WireFormatLite::WriteMessageToArray(
    527         WireFormatLite::kMessageSetMessageNumber, *message_value, target);
    528   }
    529   // End group.
    530   target = io::CodedOutputStream::WriteTagToArray(
    531       WireFormatLite::kMessageSetItemEndTag, target);
    532   return target;
    533 }
    534 
    535 
    536 bool ExtensionSet::ParseFieldMaybeLazily(
    537     int wire_type, int field_number, io::CodedInputStream* input,
    538     ExtensionFinder* extension_finder,
    539     MessageSetFieldSkipper* field_skipper) {
    540   return ParseField(WireFormatLite::MakeTag(
    541       field_number, static_cast<WireFormatLite::WireType>(wire_type)),
    542                     input, extension_finder, field_skipper);
    543 }
    544 
    545 bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
    546                                    ExtensionFinder* extension_finder,
    547                                    MessageSetFieldSkipper* field_skipper) {
    548   while (true) {
    549     const uint32 tag = input->ReadTag();
    550     switch (tag) {
    551       case 0:
    552         return true;
    553       case WireFormatLite::kMessageSetItemStartTag:
    554         if (!ParseMessageSetItem(input, extension_finder, field_skipper)) {
    555           return false;
    556         }
    557         break;
    558       default:
    559         if (!ParseField(tag, input, extension_finder, field_skipper)) {
    560           return false;
    561         }
    562         break;
    563     }
    564   }
    565 }
    566 
    567 bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
    568                                    const MessageLite* containing_type) {
    569   MessageSetFieldSkipper skipper(NULL);
    570   GeneratedExtensionFinder finder(containing_type);
    571   return ParseMessageSet(input, &finder, &skipper);
    572 }
    573 
    574 bool ExtensionSet::ParseMessageSetItem(io::CodedInputStream* input,
    575                                        ExtensionFinder* extension_finder,
    576                                        MessageSetFieldSkipper* field_skipper) {
    577   // TODO(kenton):  It would be nice to share code between this and
    578   // WireFormatLite::ParseAndMergeMessageSetItem(), but I think the
    579   // differences would be hard to factor out.
    580 
    581   // This method parses a group which should contain two fields:
    582   //   required int32 type_id = 2;
    583   //   required data message = 3;
    584 
    585   uint32 last_type_id = 0;
    586 
    587   // If we see message data before the type_id, we'll append it to this so
    588   // we can parse it later.
    589   string message_data;
    590 
    591   while (true) {
    592     const uint32 tag = input->ReadTag();
    593     if (tag == 0) return false;
    594 
    595     switch (tag) {
    596       case WireFormatLite::kMessageSetTypeIdTag: {
    597         uint32 type_id;
    598         if (!input->ReadVarint32(&type_id)) return false;
    599         last_type_id = type_id;
    600 
    601         if (!message_data.empty()) {
    602           // We saw some message data before the type_id.  Have to parse it
    603           // now.
    604           io::CodedInputStream sub_input(
    605               reinterpret_cast<const uint8*>(message_data.data()),
    606               message_data.size());
    607           if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
    608                                      last_type_id, &sub_input,
    609                                      extension_finder, field_skipper)) {
    610             return false;
    611           }
    612           message_data.clear();
    613         }
    614 
    615         break;
    616       }
    617 
    618       case WireFormatLite::kMessageSetMessageTag: {
    619         if (last_type_id == 0) {
    620           // We haven't seen a type_id yet.  Append this data to message_data.
    621           string temp;
    622           uint32 length;
    623           if (!input->ReadVarint32(&length)) return false;
    624           if (!input->ReadString(&temp, length)) return false;
    625           io::StringOutputStream output_stream(&message_data);
    626           io::CodedOutputStream coded_output(&output_stream);
    627           coded_output.WriteVarint32(length);
    628           coded_output.WriteString(temp);
    629         } else {
    630           // Already saw type_id, so we can parse this directly.
    631           if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
    632                                      last_type_id, input,
    633                                      extension_finder, field_skipper)) {
    634             return false;
    635           }
    636         }
    637 
    638         break;
    639       }
    640 
    641       case WireFormatLite::kMessageSetItemEndTag: {
    642         return true;
    643       }
    644 
    645       default: {
    646         if (!field_skipper->SkipField(input, tag)) return false;
    647       }
    648     }
    649   }
    650 }
    651 
    652 void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes(
    653     int number,
    654     io::CodedOutputStream* output) const {
    655   if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
    656     // Not a valid MessageSet extension, but serialize it the normal way.
    657     SerializeFieldWithCachedSizes(number, output);
    658     return;
    659   }
    660 
    661   if (is_cleared) return;
    662 
    663   // Start group.
    664   output->WriteTag(WireFormatLite::kMessageSetItemStartTag);
    665 
    666   // Write type ID.
    667   WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber,
    668                               number,
    669                               output);
    670   // Write message.
    671   if (is_lazy) {
    672     lazymessage_value->WriteMessage(
    673         WireFormatLite::kMessageSetMessageNumber, output);
    674   } else {
    675     WireFormatLite::WriteMessageMaybeToArray(
    676         WireFormatLite::kMessageSetMessageNumber,
    677         *message_value,
    678         output);
    679   }
    680 
    681   // End group.
    682   output->WriteTag(WireFormatLite::kMessageSetItemEndTag);
    683 }
    684 
    685 int ExtensionSet::Extension::MessageSetItemByteSize(int number) const {
    686   if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
    687     // Not a valid MessageSet extension, but compute the byte size for it the
    688     // normal way.
    689     return ByteSize(number);
    690   }
    691 
    692   if (is_cleared) return 0;
    693 
    694   int our_size = WireFormatLite::kMessageSetItemTagsSize;
    695 
    696   // type_id
    697   our_size += io::CodedOutputStream::VarintSize32(number);
    698 
    699   // message
    700   int message_size = 0;
    701   if (is_lazy) {
    702     message_size = lazymessage_value->ByteSize();
    703   } else {
    704     message_size = message_value->ByteSize();
    705   }
    706 
    707   our_size += io::CodedOutputStream::VarintSize32(message_size);
    708   our_size += message_size;
    709 
    710   return our_size;
    711 }
    712 
    713 void ExtensionSet::SerializeMessageSetWithCachedSizes(
    714     io::CodedOutputStream* output) const {
    715   for (map<int, Extension>::const_iterator iter = extensions_.begin();
    716        iter != extensions_.end(); ++iter) {
    717     iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output);
    718   }
    719 }
    720 
    721 int ExtensionSet::MessageSetByteSize() const {
    722   int total_size = 0;
    723 
    724   for (map<int, Extension>::const_iterator iter = extensions_.begin();
    725        iter != extensions_.end(); ++iter) {
    726     total_size += iter->second.MessageSetItemByteSize(iter->first);
    727   }
    728 
    729   return total_size;
    730 }
    731 
    732 }  // namespace internal
    733 }  // namespace protobuf
    734 }  // namespace google
    735