LCOV - code coverage report
Current view: top level - toolkit/components/protobuf/src/google/protobuf - extension_set_heavy.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 0 334 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 33 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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@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           0 :   explicit MessageSetFieldSkipper(UnknownFieldSet* unknown_fields)
      56           0 :       : UnknownFieldSetFieldSkipper(unknown_fields) {}
      57           0 :   virtual ~MessageSetFieldSkipper() {}
      58             : 
      59             :   virtual bool SkipMessageSetField(io::CodedInputStream* input,
      60             :                                    int field_number);
      61             : };
      62           0 : bool MessageSetFieldSkipper::SkipMessageSetField(
      63             :     io::CodedInputStream* input, int field_number) {
      64             :   uint32 length;
      65           0 :   if (!input->ReadVarint32(&length)) return false;
      66           0 :   if (unknown_fields_ == NULL) {
      67           0 :     return input->Skip(length);
      68             :   } else {
      69           0 :     return input->ReadString(
      70           0 :         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           0 :   DescriptorPoolExtensionFinder(const DescriptorPool* pool,
      81             :                                 MessageFactory* factory,
      82             :                                 const Descriptor* containing_type)
      83           0 :       : pool_(pool), factory_(factory), containing_type_(containing_type) {}
      84           0 :   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           0 : void ExtensionSet::AppendToList(const Descriptor* containing_type,
      95             :                                 const DescriptorPool* pool,
      96             :                                 vector<const FieldDescriptor*>* output) const {
      97           0 :   for (map<int, Extension>::const_iterator iter = extensions_.begin();
      98           0 :        iter != extensions_.end(); ++iter) {
      99           0 :     bool has = false;
     100           0 :     if (iter->second.is_repeated) {
     101           0 :       has = iter->second.GetSize() > 0;
     102             :     } else {
     103           0 :       has = !iter->second.is_cleared;
     104             :     }
     105             : 
     106           0 :     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           0 :       if (iter->second.descriptor == NULL) {
     113           0 :         output->push_back(pool->FindExtensionByNumber(
     114           0 :             containing_type, iter->first));
     115             :       } else {
     116           0 :         output->push_back(iter->second.descriptor);
     117             :       }
     118             :     }
     119             :   }
     120           0 : }
     121             : 
     122           0 : inline FieldDescriptor::Type real_type(FieldType type) {
     123           0 :   GOOGLE_DCHECK(type > 0 && type <= FieldDescriptor::MAX_TYPE);
     124           0 :   return static_cast<FieldDescriptor::Type>(type);
     125             : }
     126             : 
     127           0 : inline FieldDescriptor::CppType cpp_type(FieldType type) {
     128           0 :   return FieldDescriptor::TypeToCppType(
     129           0 :       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           0 : const MessageLite& ExtensionSet::GetMessage(int number,
     144             :                                             const Descriptor* message_type,
     145             :                                             MessageFactory* factory) const {
     146           0 :   map<int, Extension>::const_iterator iter = extensions_.find(number);
     147           0 :   if (iter == extensions_.end() || iter->second.is_cleared) {
     148             :     // Not present.  Return the default value.
     149           0 :     return *factory->GetPrototype(message_type);
     150             :   } else {
     151           0 :     GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
     152           0 :     if (iter->second.is_lazy) {
     153           0 :       return iter->second.lazymessage_value->GetMessage(
     154           0 :           *factory->GetPrototype(message_type));
     155             :     } else {
     156           0 :       return *iter->second.message_value;
     157             :     }
     158             :   }
     159             : }
     160             : 
     161           0 : MessageLite* ExtensionSet::MutableMessage(const FieldDescriptor* descriptor,
     162             :                                           MessageFactory* factory) {
     163             :   Extension* extension;
     164           0 :   if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
     165           0 :     extension->type = descriptor->type();
     166           0 :     GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
     167           0 :     extension->is_repeated = false;
     168           0 :     extension->is_packed = false;
     169             :     const MessageLite* prototype =
     170           0 :         factory->GetPrototype(descriptor->message_type());
     171           0 :     extension->is_lazy = false;
     172           0 :     extension->message_value = prototype->New();
     173           0 :     extension->is_cleared = false;
     174           0 :     return extension->message_value;
     175             :   } else {
     176           0 :     GOOGLE_DCHECK_TYPE(*extension, OPTIONAL, MESSAGE);
     177           0 :     extension->is_cleared = false;
     178           0 :     if (extension->is_lazy) {
     179           0 :       return extension->lazymessage_value->MutableMessage(
     180           0 :           *factory->GetPrototype(descriptor->message_type()));
     181             :     } else {
     182           0 :       return extension->message_value;
     183             :     }
     184             :   }
     185             : }
     186             : 
     187           0 : MessageLite* ExtensionSet::ReleaseMessage(const FieldDescriptor* descriptor,
     188             :                                           MessageFactory* factory) {
     189           0 :   map<int, Extension>::iterator iter = extensions_.find(descriptor->number());
     190           0 :   if (iter == extensions_.end()) {
     191             :     // Not present.  Return NULL.
     192           0 :     return NULL;
     193             :   } else {
     194           0 :     GOOGLE_DCHECK_TYPE(iter->second, OPTIONAL, MESSAGE);
     195           0 :     MessageLite* ret = NULL;
     196           0 :     if (iter->second.is_lazy) {
     197           0 :       ret = iter->second.lazymessage_value->ReleaseMessage(
     198           0 :           *factory->GetPrototype(descriptor->message_type()));
     199           0 :       delete iter->second.lazymessage_value;
     200             :     } else {
     201           0 :       ret = iter->second.message_value;
     202             :     }
     203           0 :     extensions_.erase(descriptor->number());
     204           0 :     return ret;
     205             :   }
     206             : }
     207             : 
     208           0 : MessageLite* ExtensionSet::AddMessage(const FieldDescriptor* descriptor,
     209             :                                       MessageFactory* factory) {
     210             :   Extension* extension;
     211           0 :   if (MaybeNewExtension(descriptor->number(), descriptor, &extension)) {
     212           0 :     extension->type = descriptor->type();
     213           0 :     GOOGLE_DCHECK_EQ(cpp_type(extension->type), FieldDescriptor::CPPTYPE_MESSAGE);
     214           0 :     extension->is_repeated = true;
     215           0 :     extension->repeated_message_value =
     216           0 :       new RepeatedPtrField<MessageLite>();
     217             :   } else {
     218           0 :     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           0 :   MessageLite* result = extension->repeated_message_value
     224           0 :       ->AddFromCleared<GenericTypeHandler<MessageLite> >();
     225           0 :   if (result == NULL) {
     226             :     const MessageLite* prototype;
     227           0 :     if (extension->repeated_message_value->size() == 0) {
     228           0 :       prototype = factory->GetPrototype(descriptor->message_type());
     229           0 :       GOOGLE_CHECK(prototype != NULL);
     230             :     } else {
     231           0 :       prototype = &extension->repeated_message_value->Get(0);
     232             :     }
     233           0 :     result = prototype->New();
     234           0 :     extension->repeated_message_value->AddAllocated(result);
     235             :   }
     236           0 :   return result;
     237             : }
     238             : 
     239           0 : static bool ValidateEnumUsingDescriptor(const void* arg, int number) {
     240             :   return reinterpret_cast<const EnumDescriptor*>(arg)
     241           0 :       ->FindValueByNumber(number) != NULL;
     242             : }
     243             : 
     244           0 : bool DescriptorPoolExtensionFinder::Find(int number, ExtensionInfo* output) {
     245             :   const FieldDescriptor* extension =
     246           0 :       pool_->FindExtensionByNumber(containing_type_, number);
     247           0 :   if (extension == NULL) {
     248           0 :     return false;
     249             :   } else {
     250           0 :     output->type = extension->type();
     251           0 :     output->is_repeated = extension->is_repeated();
     252           0 :     output->is_packed = extension->options().packed();
     253           0 :     output->descriptor = extension;
     254           0 :     if (extension->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
     255           0 :       output->message_prototype =
     256           0 :           factory_->GetPrototype(extension->message_type());
     257           0 :       GOOGLE_CHECK(output->message_prototype != NULL)
     258           0 :           << "Extension factory's GetPrototype() returned NULL for extension: "
     259           0 :           << extension->full_name();
     260           0 :     } else if (extension->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
     261           0 :       output->enum_validity_check.func = ValidateEnumUsingDescriptor;
     262           0 :       output->enum_validity_check.arg = extension->enum_type();
     263             :     }
     264             : 
     265           0 :     return true;
     266             :   }
     267             : }
     268             : 
     269           0 : bool ExtensionSet::ParseField(uint32 tag, io::CodedInputStream* input,
     270             :                               const Message* containing_type,
     271             :                               UnknownFieldSet* unknown_fields) {
     272           0 :   UnknownFieldSetFieldSkipper skipper(unknown_fields);
     273           0 :   if (input->GetExtensionPool() == NULL) {
     274           0 :     GeneratedExtensionFinder finder(containing_type);
     275           0 :     return ParseField(tag, input, &finder, &skipper);
     276             :   } else {
     277             :     DescriptorPoolExtensionFinder finder(input->GetExtensionPool(),
     278             :                                          input->GetExtensionFactory(),
     279           0 :                                          containing_type->GetDescriptor());
     280           0 :     return ParseField(tag, input, &finder, &skipper);
     281             :   }
     282             : }
     283             : 
     284           0 : bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
     285             :                                    const Message* containing_type,
     286             :                                    UnknownFieldSet* unknown_fields) {
     287           0 :   MessageSetFieldSkipper skipper(unknown_fields);
     288           0 :   if (input->GetExtensionPool() == NULL) {
     289           0 :     GeneratedExtensionFinder finder(containing_type);
     290           0 :     return ParseMessageSet(input, &finder, &skipper);
     291             :   } else {
     292             :     DescriptorPoolExtensionFinder finder(input->GetExtensionPool(),
     293             :                                          input->GetExtensionFactory(),
     294           0 :                                          containing_type->GetDescriptor());
     295           0 :     return ParseMessageSet(input, &finder, &skipper);
     296             :   }
     297             : }
     298             : 
     299           0 : int ExtensionSet::SpaceUsedExcludingSelf() const {
     300             :   int total_size =
     301           0 :       extensions_.size() * sizeof(map<int, Extension>::value_type);
     302           0 :   for (map<int, Extension>::const_iterator iter = extensions_.begin(),
     303           0 :        end = extensions_.end();
     304             :        iter != end;
     305             :        ++iter) {
     306           0 :     total_size += iter->second.SpaceUsedExcludingSelf();
     307             :   }
     308           0 :   return total_size;
     309             : }
     310             : 
     311           0 : inline int ExtensionSet::RepeatedMessage_SpaceUsedExcludingSelf(
     312             :     RepeatedPtrFieldBase* field) {
     313           0 :   return field->SpaceUsedExcludingSelf<GenericTypeHandler<Message> >();
     314             : }
     315             : 
     316           0 : int ExtensionSet::Extension::SpaceUsedExcludingSelf() const {
     317           0 :   int total_size = 0;
     318           0 :   if (is_repeated) {
     319           0 :     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           0 :       HANDLE_TYPE(  INT32,   int32);
     327           0 :       HANDLE_TYPE(  INT64,   int64);
     328           0 :       HANDLE_TYPE( UINT32,  uint32);
     329           0 :       HANDLE_TYPE( UINT64,  uint64);
     330           0 :       HANDLE_TYPE(  FLOAT,   float);
     331           0 :       HANDLE_TYPE( DOUBLE,  double);
     332           0 :       HANDLE_TYPE(   BOOL,    bool);
     333           0 :       HANDLE_TYPE(   ENUM,    enum);
     334           0 :       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           0 :         total_size += sizeof(*repeated_message_value) +
     343           0 :             RepeatedMessage_SpaceUsedExcludingSelf(repeated_message_value);
     344           0 :         break;
     345             :     }
     346             :   } else {
     347           0 :     switch (cpp_type(type)) {
     348             :       case FieldDescriptor::CPPTYPE_STRING:
     349           0 :         total_size += sizeof(*string_value) +
     350           0 :                       StringSpaceUsedExcludingSelf(*string_value);
     351           0 :         break;
     352             :       case FieldDescriptor::CPPTYPE_MESSAGE:
     353           0 :         if (is_lazy) {
     354           0 :           total_size += lazymessage_value->SpaceUsed();
     355             :         } else {
     356           0 :           total_size += down_cast<Message*>(message_value)->SpaceUsed();
     357             :         }
     358           0 :         break;
     359             :       default:
     360             :         // No extra storage costs for primitive types.
     361           0 :         break;
     362             :     }
     363             :   }
     364           0 :   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           0 : uint8* ExtensionSet::SerializeWithCachedSizesToArray(
     370             :     int start_field_number, int end_field_number,
     371             :     uint8* target) const {
     372           0 :   map<int, Extension>::const_iterator iter;
     373           0 :   for (iter = extensions_.lower_bound(start_field_number);
     374           0 :        iter != extensions_.end() && iter->first < end_field_number;
     375             :        ++iter) {
     376           0 :     target = iter->second.SerializeFieldWithCachedSizesToArray(iter->first,
     377           0 :                                                                target);
     378             :   }
     379           0 :   return target;
     380             : }
     381             : 
     382           0 : uint8* ExtensionSet::SerializeMessageSetWithCachedSizesToArray(
     383             :     uint8* target) const {
     384           0 :   map<int, Extension>::const_iterator iter;
     385           0 :   for (iter = extensions_.begin(); iter != extensions_.end(); ++iter) {
     386           0 :     target = iter->second.SerializeMessageSetItemWithCachedSizesToArray(
     387           0 :         iter->first, target);
     388             :   }
     389           0 :   return target;
     390             : }
     391             : 
     392           0 : uint8* ExtensionSet::Extension::SerializeFieldWithCachedSizesToArray(
     393             :     int number, uint8* target) const {
     394           0 :   if (is_repeated) {
     395           0 :     if (is_packed) {
     396           0 :       if (cached_size == 0) return target;
     397             : 
     398             :       target = WireFormatLite::WriteTagToArray(number,
     399           0 :           WireFormatLite::WIRETYPE_LENGTH_DELIMITED, target);
     400           0 :       target = WireFormatLite::WriteInt32NoTagToArray(cached_size, target);
     401             : 
     402           0 :       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           0 :         HANDLE_TYPE(   INT32,    Int32,   int32);
     412           0 :         HANDLE_TYPE(   INT64,    Int64,   int64);
     413           0 :         HANDLE_TYPE(  UINT32,   UInt32,  uint32);
     414           0 :         HANDLE_TYPE(  UINT64,   UInt64,  uint64);
     415           0 :         HANDLE_TYPE(  SINT32,   SInt32,   int32);
     416           0 :         HANDLE_TYPE(  SINT64,   SInt64,   int64);
     417           0 :         HANDLE_TYPE( FIXED32,  Fixed32,  uint32);
     418           0 :         HANDLE_TYPE( FIXED64,  Fixed64,  uint64);
     419           0 :         HANDLE_TYPE(SFIXED32, SFixed32,   int32);
     420           0 :         HANDLE_TYPE(SFIXED64, SFixed64,   int64);
     421           0 :         HANDLE_TYPE(   FLOAT,    Float,   float);
     422           0 :         HANDLE_TYPE(  DOUBLE,   Double,  double);
     423           0 :         HANDLE_TYPE(    BOOL,     Bool,    bool);
     424           0 :         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           0 :           GOOGLE_LOG(FATAL) << "Non-primitive types can't be packed.";
     432           0 :           break;
     433             :       }
     434             :     } else {
     435           0 :       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           0 :         HANDLE_TYPE(   INT32,    Int32,   int32);
     445           0 :         HANDLE_TYPE(   INT64,    Int64,   int64);
     446           0 :         HANDLE_TYPE(  UINT32,   UInt32,  uint32);
     447           0 :         HANDLE_TYPE(  UINT64,   UInt64,  uint64);
     448           0 :         HANDLE_TYPE(  SINT32,   SInt32,   int32);
     449           0 :         HANDLE_TYPE(  SINT64,   SInt64,   int64);
     450           0 :         HANDLE_TYPE( FIXED32,  Fixed32,  uint32);
     451           0 :         HANDLE_TYPE( FIXED64,  Fixed64,  uint64);
     452           0 :         HANDLE_TYPE(SFIXED32, SFixed32,   int32);
     453           0 :         HANDLE_TYPE(SFIXED64, SFixed64,   int64);
     454           0 :         HANDLE_TYPE(   FLOAT,    Float,   float);
     455           0 :         HANDLE_TYPE(  DOUBLE,   Double,  double);
     456           0 :         HANDLE_TYPE(    BOOL,     Bool,    bool);
     457           0 :         HANDLE_TYPE(  STRING,   String,  string);
     458           0 :         HANDLE_TYPE(   BYTES,    Bytes,  string);
     459           0 :         HANDLE_TYPE(    ENUM,     Enum,    enum);
     460           0 :         HANDLE_TYPE(   GROUP,    Group, message);
     461           0 :         HANDLE_TYPE( MESSAGE,  Message, message);
     462             : #undef HANDLE_TYPE
     463             :       }
     464             :     }
     465           0 :   } else if (!is_cleared) {
     466           0 :     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           0 :       HANDLE_TYPE(   INT32,    Int32,    int32_value);
     474           0 :       HANDLE_TYPE(   INT64,    Int64,    int64_value);
     475           0 :       HANDLE_TYPE(  UINT32,   UInt32,   uint32_value);
     476           0 :       HANDLE_TYPE(  UINT64,   UInt64,   uint64_value);
     477           0 :       HANDLE_TYPE(  SINT32,   SInt32,    int32_value);
     478           0 :       HANDLE_TYPE(  SINT64,   SInt64,    int64_value);
     479           0 :       HANDLE_TYPE( FIXED32,  Fixed32,   uint32_value);
     480           0 :       HANDLE_TYPE( FIXED64,  Fixed64,   uint64_value);
     481           0 :       HANDLE_TYPE(SFIXED32, SFixed32,    int32_value);
     482           0 :       HANDLE_TYPE(SFIXED64, SFixed64,    int64_value);
     483           0 :       HANDLE_TYPE(   FLOAT,    Float,    float_value);
     484           0 :       HANDLE_TYPE(  DOUBLE,   Double,   double_value);
     485           0 :       HANDLE_TYPE(    BOOL,     Bool,     bool_value);
     486           0 :       HANDLE_TYPE(  STRING,   String,  *string_value);
     487           0 :       HANDLE_TYPE(   BYTES,    Bytes,  *string_value);
     488           0 :       HANDLE_TYPE(    ENUM,     Enum,     enum_value);
     489           0 :       HANDLE_TYPE(   GROUP,    Group, *message_value);
     490             : #undef HANDLE_TYPE
     491             :       case FieldDescriptor::TYPE_MESSAGE:
     492           0 :         if (is_lazy) {
     493           0 :           target = lazymessage_value->WriteMessageToArray(number, target);
     494             :         } else {
     495             :           target = WireFormatLite::WriteMessageToArray(
     496           0 :               number, *message_value, target);
     497             :         }
     498           0 :         break;
     499             :     }
     500             :   }
     501           0 :   return target;
     502             : }
     503             : 
     504           0 : uint8* ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizesToArray(
     505             :     int number,
     506             :     uint8* target) const {
     507           0 :   if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
     508             :     // Not a valid MessageSet extension, but serialize it the normal way.
     509           0 :     GOOGLE_LOG(WARNING) << "Invalid message set extension.";
     510           0 :     return SerializeFieldWithCachedSizesToArray(number, target);
     511             :   }
     512             : 
     513           0 :   if (is_cleared) return target;
     514             : 
     515             :   // Start group.
     516             :   target = io::CodedOutputStream::WriteTagToArray(
     517           0 :       WireFormatLite::kMessageSetItemStartTag, target);
     518             :   // Write type ID.
     519           0 :   target = WireFormatLite::WriteUInt32ToArray(
     520           0 :       WireFormatLite::kMessageSetTypeIdNumber, number, target);
     521             :   // Write message.
     522           0 :   if (is_lazy) {
     523           0 :     target = lazymessage_value->WriteMessageToArray(
     524           0 :         WireFormatLite::kMessageSetMessageNumber, target);
     525             :   } else {
     526             :     target = WireFormatLite::WriteMessageToArray(
     527           0 :         WireFormatLite::kMessageSetMessageNumber, *message_value, target);
     528             :   }
     529             :   // End group.
     530             :   target = io::CodedOutputStream::WriteTagToArray(
     531           0 :       WireFormatLite::kMessageSetItemEndTag, target);
     532           0 :   return target;
     533             : }
     534             : 
     535             : 
     536           0 : bool ExtensionSet::ParseFieldMaybeLazily(
     537             :     int wire_type, int field_number, io::CodedInputStream* input,
     538             :     ExtensionFinder* extension_finder,
     539             :     MessageSetFieldSkipper* field_skipper) {
     540           0 :   return ParseField(WireFormatLite::MakeTag(
     541             :       field_number, static_cast<WireFormatLite::WireType>(wire_type)),
     542           0 :                     input, extension_finder, field_skipper);
     543             : }
     544             : 
     545           0 : bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
     546             :                                    ExtensionFinder* extension_finder,
     547             :                                    MessageSetFieldSkipper* field_skipper) {
     548             :   while (true) {
     549           0 :     const uint32 tag = input->ReadTag();
     550           0 :     switch (tag) {
     551             :       case 0:
     552           0 :         return true;
     553             :       case WireFormatLite::kMessageSetItemStartTag:
     554           0 :         if (!ParseMessageSetItem(input, extension_finder, field_skipper)) {
     555           0 :           return false;
     556             :         }
     557           0 :         break;
     558             :       default:
     559           0 :         if (!ParseField(tag, input, extension_finder, field_skipper)) {
     560           0 :           return false;
     561             :         }
     562           0 :         break;
     563             :     }
     564           0 :   }
     565             : }
     566             : 
     567           0 : bool ExtensionSet::ParseMessageSet(io::CodedInputStream* input,
     568             :                                    const MessageLite* containing_type) {
     569           0 :   MessageSetFieldSkipper skipper(NULL);
     570           0 :   GeneratedExtensionFinder finder(containing_type);
     571           0 :   return ParseMessageSet(input, &finder, &skipper);
     572             : }
     573             : 
     574           0 : 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           0 :   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           0 :   string message_data;
     590             : 
     591             :   while (true) {
     592           0 :     const uint32 tag = input->ReadTag();
     593           0 :     if (tag == 0) return false;
     594             : 
     595           0 :     switch (tag) {
     596             :       case WireFormatLite::kMessageSetTypeIdTag: {
     597             :         uint32 type_id;
     598           0 :         if (!input->ReadVarint32(&type_id)) return false;
     599           0 :         last_type_id = type_id;
     600             : 
     601           0 :         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           0 :               reinterpret_cast<const uint8*>(message_data.data()),
     606           0 :               message_data.size());
     607           0 :           if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
     608             :                                      last_type_id, &sub_input,
     609             :                                      extension_finder, field_skipper)) {
     610           0 :             return false;
     611             :           }
     612           0 :           message_data.clear();
     613             :         }
     614             : 
     615           0 :         break;
     616             :       }
     617             : 
     618             :       case WireFormatLite::kMessageSetMessageTag: {
     619           0 :         if (last_type_id == 0) {
     620             :           // We haven't seen a type_id yet.  Append this data to message_data.
     621           0 :           string temp;
     622             :           uint32 length;
     623           0 :           if (!input->ReadVarint32(&length)) return false;
     624           0 :           if (!input->ReadString(&temp, length)) return false;
     625           0 :           io::StringOutputStream output_stream(&message_data);
     626           0 :           io::CodedOutputStream coded_output(&output_stream);
     627           0 :           coded_output.WriteVarint32(length);
     628           0 :           coded_output.WriteString(temp);
     629             :         } else {
     630             :           // Already saw type_id, so we can parse this directly.
     631           0 :           if (!ParseFieldMaybeLazily(WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
     632             :                                      last_type_id, input,
     633             :                                      extension_finder, field_skipper)) {
     634           0 :             return false;
     635             :           }
     636             :         }
     637             : 
     638           0 :         break;
     639             :       }
     640             : 
     641             :       case WireFormatLite::kMessageSetItemEndTag: {
     642           0 :         return true;
     643             :       }
     644             : 
     645             :       default: {
     646           0 :         if (!field_skipper->SkipField(input, tag)) return false;
     647             :       }
     648             :     }
     649           0 :   }
     650             : }
     651             : 
     652           0 : void ExtensionSet::Extension::SerializeMessageSetItemWithCachedSizes(
     653             :     int number,
     654             :     io::CodedOutputStream* output) const {
     655           0 :   if (type != WireFormatLite::TYPE_MESSAGE || is_repeated) {
     656             :     // Not a valid MessageSet extension, but serialize it the normal way.
     657           0 :     SerializeFieldWithCachedSizes(number, output);
     658           0 :     return;
     659             :   }
     660             : 
     661           0 :   if (is_cleared) return;
     662             : 
     663             :   // Start group.
     664           0 :   output->WriteTag(WireFormatLite::kMessageSetItemStartTag);
     665             : 
     666             :   // Write type ID.
     667           0 :   WireFormatLite::WriteUInt32(WireFormatLite::kMessageSetTypeIdNumber,
     668             :                               number,
     669           0 :                               output);
     670             :   // Write message.
     671           0 :   if (is_lazy) {
     672           0 :     lazymessage_value->WriteMessage(
     673           0 :         WireFormatLite::kMessageSetMessageNumber, output);
     674             :   } else {
     675             :     WireFormatLite::WriteMessageMaybeToArray(
     676             :         WireFormatLite::kMessageSetMessageNumber,
     677           0 :         *message_value,
     678           0 :         output);
     679             :   }
     680             : 
     681             :   // End group.
     682           0 :   output->WriteTag(WireFormatLite::kMessageSetItemEndTag);
     683             : }
     684             : 
     685           0 : int ExtensionSet::Extension::MessageSetItemByteSize(int number) const {
     686           0 :   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           0 :     return ByteSize(number);
     690             :   }
     691             : 
     692           0 :   if (is_cleared) return 0;
     693             : 
     694           0 :   int our_size = WireFormatLite::kMessageSetItemTagsSize;
     695             : 
     696             :   // type_id
     697           0 :   our_size += io::CodedOutputStream::VarintSize32(number);
     698             : 
     699             :   // message
     700           0 :   int message_size = 0;
     701           0 :   if (is_lazy) {
     702           0 :     message_size = lazymessage_value->ByteSize();
     703             :   } else {
     704           0 :     message_size = message_value->ByteSize();
     705             :   }
     706             : 
     707           0 :   our_size += io::CodedOutputStream::VarintSize32(message_size);
     708           0 :   our_size += message_size;
     709             : 
     710           0 :   return our_size;
     711             : }
     712             : 
     713           0 : void ExtensionSet::SerializeMessageSetWithCachedSizes(
     714             :     io::CodedOutputStream* output) const {
     715           0 :   for (map<int, Extension>::const_iterator iter = extensions_.begin();
     716           0 :        iter != extensions_.end(); ++iter) {
     717           0 :     iter->second.SerializeMessageSetItemWithCachedSizes(iter->first, output);
     718             :   }
     719           0 : }
     720             : 
     721           0 : int ExtensionSet::MessageSetByteSize() const {
     722           0 :   int total_size = 0;
     723             : 
     724           0 :   for (map<int, Extension>::const_iterator iter = extensions_.begin();
     725           0 :        iter != extensions_.end(); ++iter) {
     726           0 :     total_size += iter->second.MessageSetItemByteSize(iter->first);
     727             :   }
     728             : 
     729           0 :   return total_size;
     730             : }
     731             : 
     732             : }  // namespace internal
     733             : }  // namespace protobuf
     734             : }  // namespace google

Generated by: LCOV version 1.13