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