LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf - extension_set_heavy.cc (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 32 291 11.0 %
Date: 2015-10-10 Functions: 5 30 16.7 %

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

Generated by: LCOV version 1.10