LCOV - code coverage report
Current view: top level - third_party/protobuf/src/google/protobuf - wire_format.cc (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 194 440 44.1 %
Date: 2015-10-10 Functions: 15 24 62.5 %

          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             : #include <stack>
      36             : #include <string>
      37             : #include <vector>
      38             : 
      39             : #include <google/protobuf/wire_format.h>
      40             : 
      41             : #include <google/protobuf/stubs/logging.h>
      42             : #include <google/protobuf/stubs/common.h>
      43             : #include <google/protobuf/stubs/stringprintf.h>
      44             : #include <google/protobuf/descriptor.h>
      45             : #include <google/protobuf/wire_format_lite_inl.h>
      46             : #include <google/protobuf/descriptor.pb.h>
      47             : #include <google/protobuf/io/coded_stream.h>
      48             : #include <google/protobuf/io/zero_copy_stream.h>
      49             : #include <google/protobuf/io/zero_copy_stream_impl.h>
      50             : #include <google/protobuf/unknown_field_set.h>
      51             : 
      52             : 
      53             : 
      54             : namespace google {
      55             : namespace protobuf {
      56             : namespace internal {
      57             : 
      58             : // ===================================================================
      59             : 
      60          71 : bool UnknownFieldSetFieldSkipper::SkipField(
      61             :     io::CodedInputStream* input, uint32 tag) {
      62          71 :   return WireFormat::SkipField(input, tag, unknown_fields_);
      63             : }
      64             : 
      65           0 : bool UnknownFieldSetFieldSkipper::SkipMessage(io::CodedInputStream* input) {
      66           0 :   return WireFormat::SkipMessage(input, unknown_fields_);
      67             : }
      68             : 
      69           0 : void UnknownFieldSetFieldSkipper::SkipUnknownEnum(
      70             :     int field_number, int value) {
      71           0 :   unknown_fields_->AddVarint(field_number, value);
      72           0 : }
      73             : 
      74         120 : bool WireFormat::SkipField(io::CodedInputStream* input, uint32 tag,
      75             :                            UnknownFieldSet* unknown_fields) {
      76         118 :   int number = WireFormatLite::GetTagFieldNumber(tag);
      77             : 
      78         118 :   switch (WireFormatLite::GetTagWireType(tag)) {
      79             :     case WireFormatLite::WIRETYPE_VARINT: {
      80             :       uint64 value;
      81          50 :       if (!input->ReadVarint64(&value)) return false;
      82          50 :       if (unknown_fields != NULL) unknown_fields->AddVarint(number, value);
      83             :       return true;
      84             :     }
      85             :     case WireFormatLite::WIRETYPE_FIXED64: {
      86             :       uint64 value;
      87           9 :       if (!input->ReadLittleEndian64(&value)) return false;
      88           9 :       if (unknown_fields != NULL) unknown_fields->AddFixed64(number, value);
      89             :       return true;
      90             :     }
      91             :     case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
      92             :       uint32 length;
      93          49 :       if (!input->ReadVarint32(&length)) return false;
      94          49 :       if (unknown_fields == NULL) {
      95           0 :         if (!input->Skip(length)) return false;
      96             :       } else {
      97          49 :         if (!input->ReadString(unknown_fields->AddLengthDelimited(number),
      98          49 :                                length)) {
      99             :           return false;
     100             :         }
     101             :       }
     102             :       return true;
     103             :     }
     104             :     case WireFormatLite::WIRETYPE_START_GROUP: {
     105           2 :       if (!input->IncrementRecursionDepth()) return false;
     106           1 :       if (!SkipMessage(input, (unknown_fields == NULL) ?
     107           1 :                               NULL : unknown_fields->AddGroup(number))) {
     108             :         return false;
     109             :       }
     110           2 :       input->DecrementRecursionDepth();
     111             :       // Check that the ending tag matched the starting tag.
     112           1 :       if (!input->LastTagWas(WireFormatLite::MakeTag(
     113             :           WireFormatLite::GetTagFieldNumber(tag),
     114           2 :           WireFormatLite::WIRETYPE_END_GROUP))) {
     115             :         return false;
     116             :       }
     117           1 :       return true;
     118             :     }
     119             :     case WireFormatLite::WIRETYPE_END_GROUP: {
     120             :       return false;
     121             :     }
     122             :     case WireFormatLite::WIRETYPE_FIXED32: {
     123             :       uint32 value;
     124           9 :       if (!input->ReadLittleEndian32(&value)) return false;
     125           9 :       if (unknown_fields != NULL) unknown_fields->AddFixed32(number, value);
     126             :       return true;
     127             :     }
     128             :     default: {
     129             :       return false;
     130             :     }
     131             :   }
     132             : }
     133             : 
     134          47 : bool WireFormat::SkipMessage(io::CodedInputStream* input,
     135             :                              UnknownFieldSet* unknown_fields) {
     136             :   while (true) {
     137          94 :     uint32 tag = input->ReadTag();
     138          94 :     if (tag == 0) {
     139             :       // End of input.  This is a valid place to end, so return true.
     140             :       return true;
     141             :     }
     142             : 
     143          48 :     WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
     144             : 
     145          48 :     if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
     146             :       // Must be the end of the message.
     147             :       return true;
     148             :     }
     149             : 
     150          47 :     if (!SkipField(input, tag, unknown_fields)) return false;
     151             :   }
     152             : }
     153             : 
     154           0 : bool WireFormat::ReadPackedEnumPreserveUnknowns(io::CodedInputStream* input,
     155             :                                                 uint32 field_number,
     156             :                                                 bool (*is_valid)(int),
     157             :                                                 UnknownFieldSet* unknown_fields,
     158             :                                                 RepeatedField<int>* values) {
     159             :   uint32 length;
     160           0 :   if (!input->ReadVarint32(&length)) return false;
     161           0 :   io::CodedInputStream::Limit limit = input->PushLimit(length);
     162           0 :   while (input->BytesUntilLimit() > 0) {
     163             :     int value;
     164           0 :     if (!google::protobuf::internal::WireFormatLite::ReadPrimitive<
     165             :         int, WireFormatLite::TYPE_ENUM>(input, &value)) {
     166           0 :       return false;
     167             :     }
     168           0 :     if (is_valid == NULL || is_valid(value)) {
     169           0 :       values->Add(value);
     170             :     } else {
     171           0 :       unknown_fields->AddVarint(field_number, value);
     172             :     }
     173             :   }
     174           0 :   input->PopLimit(limit);
     175             :   return true;
     176             : }
     177             : 
     178             : 
     179          43 : void WireFormat::SerializeUnknownFields(const UnknownFieldSet& unknown_fields,
     180             :                                         io::CodedOutputStream* output) {
     181         146 :   for (int i = 0; i < unknown_fields.field_count(); i++) {
     182         103 :     const UnknownField& field = unknown_fields.field(i);
     183          30 :     switch (field.type()) {
     184             :       case UnknownField::TYPE_VARINT:
     185             :         output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
     186          51 :             WireFormatLite::WIRETYPE_VARINT));
     187          17 :         output->WriteVarint64(field.varint());
     188          17 :         break;
     189             :       case UnknownField::TYPE_FIXED32:
     190             :         output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
     191           0 :             WireFormatLite::WIRETYPE_FIXED32));
     192           0 :         output->WriteLittleEndian32(field.fixed32());
     193           0 :         break;
     194             :       case UnknownField::TYPE_FIXED64:
     195             :         output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
     196           0 :             WireFormatLite::WIRETYPE_FIXED64));
     197           0 :         output->WriteLittleEndian64(field.fixed64());
     198           0 :         break;
     199             :       case UnknownField::TYPE_LENGTH_DELIMITED:
     200             :         output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
     201          36 :             WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
     202          24 :         output->WriteVarint32(field.length_delimited().size());
     203          12 :         output->WriteRawMaybeAliased(field.length_delimited().data(),
     204          36 :                                      field.length_delimited().size());
     205          12 :         break;
     206             :       case UnknownField::TYPE_GROUP:
     207             :         output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
     208           3 :             WireFormatLite::WIRETYPE_START_GROUP));
     209           1 :         SerializeUnknownFields(field.group(), output);
     210             :         output->WriteVarint32(WireFormatLite::MakeTag(field.number(),
     211           3 :             WireFormatLite::WIRETYPE_END_GROUP));
     212           1 :         break;
     213             :     }
     214             :   }
     215          43 : }
     216             : 
     217         486 : uint8* WireFormat::SerializeUnknownFieldsToArray(
     218             :     const UnknownFieldSet& unknown_fields,
     219             :     uint8* target) {
     220        1928 :   for (int i = 0; i < unknown_fields.field_count(); i++) {
     221        1436 :     const UnknownField& field = unknown_fields.field(i);
     222             : 
     223         478 :     switch (field.type()) {
     224             :       case UnknownField::TYPE_VARINT:
     225             :         target = WireFormatLite::WriteInt64ToArray(
     226        1276 :             field.number(), field.varint(), target);
     227         319 :         break;
     228             :       case UnknownField::TYPE_FIXED32:
     229             :         target = WireFormatLite::WriteFixed32ToArray(
     230          72 :             field.number(), field.fixed32(), target);
     231          18 :         break;
     232             :       case UnknownField::TYPE_FIXED64:
     233             :         target = WireFormatLite::WriteFixed64ToArray(
     234          72 :             field.number(), field.fixed64(), target);
     235          18 :         break;
     236             :       case UnknownField::TYPE_LENGTH_DELIMITED:
     237             :         target = WireFormatLite::WriteBytesToArray(
     238         484 :             field.number(), field.length_delimited(), target);
     239         121 :         break;
     240             :       case UnknownField::TYPE_GROUP:
     241             :         target = WireFormatLite::WriteTagToArray(
     242           6 :             field.number(), WireFormatLite::WIRETYPE_START_GROUP, target);
     243           2 :         target = SerializeUnknownFieldsToArray(field.group(), target);
     244             :         target = WireFormatLite::WriteTagToArray(
     245           6 :             field.number(), WireFormatLite::WIRETYPE_END_GROUP, target);
     246           2 :         break;
     247             :     }
     248             :   }
     249         486 :   return target;
     250             : }
     251             : 
     252           1 : void WireFormat::SerializeUnknownMessageSetItems(
     253             :     const UnknownFieldSet& unknown_fields,
     254             :     io::CodedOutputStream* output) {
     255           2 :   for (int i = 0; i < unknown_fields.field_count(); i++) {
     256           0 :     const UnknownField& field = unknown_fields.field(i);
     257             :     // The only unknown fields that are allowed to exist in a MessageSet are
     258             :     // messages, which are length-delimited.
     259           0 :     if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) {
     260             :       // Start group.
     261           0 :       output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag);
     262             : 
     263             :       // Write type ID.
     264           0 :       output->WriteVarint32(WireFormatLite::kMessageSetTypeIdTag);
     265           0 :       output->WriteVarint32(field.number());
     266             : 
     267             :       // Write message.
     268           0 :       output->WriteVarint32(WireFormatLite::kMessageSetMessageTag);
     269           0 :       field.SerializeLengthDelimitedNoTag(output);
     270             : 
     271             :       // End group.
     272           0 :       output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag);
     273             :     }
     274             :   }
     275           1 : }
     276             : 
     277           0 : uint8* WireFormat::SerializeUnknownMessageSetItemsToArray(
     278             :     const UnknownFieldSet& unknown_fields,
     279             :     uint8* target) {
     280           0 :   for (int i = 0; i < unknown_fields.field_count(); i++) {
     281           0 :     const UnknownField& field = unknown_fields.field(i);
     282             : 
     283             :     // The only unknown fields that are allowed to exist in a MessageSet are
     284             :     // messages, which are length-delimited.
     285           0 :     if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) {
     286             :       // Start group.
     287             :       target = io::CodedOutputStream::WriteTagToArray(
     288           0 :           WireFormatLite::kMessageSetItemStartTag, target);
     289             : 
     290             :       // Write type ID.
     291             :       target = io::CodedOutputStream::WriteTagToArray(
     292           0 :           WireFormatLite::kMessageSetTypeIdTag, target);
     293             :       target = io::CodedOutputStream::WriteVarint32ToArray(
     294           0 :           field.number(), target);
     295             : 
     296             :       // Write message.
     297             :       target = io::CodedOutputStream::WriteTagToArray(
     298           0 :           WireFormatLite::kMessageSetMessageTag, target);
     299           0 :       target = field.SerializeLengthDelimitedNoTagToArray(target);
     300             : 
     301             :       // End group.
     302             :       target = io::CodedOutputStream::WriteTagToArray(
     303           0 :           WireFormatLite::kMessageSetItemEndTag, target);
     304             :     }
     305             :   }
     306             : 
     307           0 :   return target;
     308             : }
     309             : 
     310         499 : int WireFormat::ComputeUnknownFieldsSize(
     311             :     const UnknownFieldSet& unknown_fields) {
     312         499 :   int size = 0;
     313        1954 :   for (int i = 0; i < unknown_fields.field_count(); i++) {
     314        1521 :     const UnknownField& field = unknown_fields.field(i);
     315             : 
     316         478 :     switch (field.type()) {
     317             :       case UnknownField::TYPE_VARINT:
     318             :         size += io::CodedOutputStream::VarintSize32(
     319             :             WireFormatLite::MakeTag(field.number(),
     320        1276 :             WireFormatLite::WIRETYPE_VARINT));
     321         319 :         size += io::CodedOutputStream::VarintSize64(field.varint());
     322         319 :         break;
     323             :       case UnknownField::TYPE_FIXED32:
     324             :         size += io::CodedOutputStream::VarintSize32(
     325             :             WireFormatLite::MakeTag(field.number(),
     326          72 :             WireFormatLite::WIRETYPE_FIXED32));
     327          18 :         size += sizeof(int32);
     328          18 :         break;
     329             :       case UnknownField::TYPE_FIXED64:
     330             :         size += io::CodedOutputStream::VarintSize32(
     331             :             WireFormatLite::MakeTag(field.number(),
     332          72 :             WireFormatLite::WIRETYPE_FIXED64));
     333          18 :         size += sizeof(int64);
     334          18 :         break;
     335             :       case UnknownField::TYPE_LENGTH_DELIMITED:
     336             :         size += io::CodedOutputStream::VarintSize32(
     337             :             WireFormatLite::MakeTag(field.number(),
     338         484 :             WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
     339             :         size += io::CodedOutputStream::VarintSize32(
     340         363 :             field.length_delimited().size());
     341         242 :         size += field.length_delimited().size();
     342         121 :         break;
     343             :       case UnknownField::TYPE_GROUP:
     344             :         size += io::CodedOutputStream::VarintSize32(
     345             :             WireFormatLite::MakeTag(field.number(),
     346           8 :             WireFormatLite::WIRETYPE_START_GROUP));
     347           2 :         size += ComputeUnknownFieldsSize(field.group());
     348             :         size += io::CodedOutputStream::VarintSize32(
     349             :             WireFormatLite::MakeTag(field.number(),
     350           8 :             WireFormatLite::WIRETYPE_END_GROUP));
     351           2 :         break;
     352             :     }
     353             :   }
     354             : 
     355         499 :   return size;
     356             : }
     357             : 
     358           1 : int WireFormat::ComputeUnknownMessageSetItemsSize(
     359             :     const UnknownFieldSet& unknown_fields) {
     360           1 :   int size = 0;
     361           2 :   for (int i = 0; i < unknown_fields.field_count(); i++) {
     362           0 :     const UnknownField& field = unknown_fields.field(i);
     363             : 
     364             :     // The only unknown fields that are allowed to exist in a MessageSet are
     365             :     // messages, which are length-delimited.
     366           0 :     if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) {
     367           0 :       size += WireFormatLite::kMessageSetItemTagsSize;
     368           0 :       size += io::CodedOutputStream::VarintSize32(field.number());
     369             : 
     370           0 :       int field_size = field.GetLengthDelimitedSize();
     371           0 :       size += io::CodedOutputStream::VarintSize32(field_size);
     372           0 :       size += field_size;
     373             :     }
     374             :   }
     375             : 
     376           1 :   return size;
     377             : }
     378             : 
     379             : // ===================================================================
     380             : 
     381           0 : bool WireFormat::ParseAndMergePartial(io::CodedInputStream* input,
     382             :                                       Message* message) {
     383           0 :   const Descriptor* descriptor = message->GetDescriptor();
     384           0 :   const Reflection* message_reflection = message->GetReflection();
     385             : 
     386             :   while(true) {
     387           0 :     uint32 tag = input->ReadTag();
     388           0 :     if (tag == 0) {
     389             :       // End of input.  This is a valid place to end, so return true.
     390             :       return true;
     391             :     }
     392             : 
     393           0 :     if (WireFormatLite::GetTagWireType(tag) ==
     394             :         WireFormatLite::WIRETYPE_END_GROUP) {
     395             :       // Must be the end of the message.
     396             :       return true;
     397             :     }
     398             : 
     399           0 :     const FieldDescriptor* field = NULL;
     400             : 
     401           0 :     if (descriptor != NULL) {
     402           0 :       int field_number = WireFormatLite::GetTagFieldNumber(tag);
     403           0 :       field = descriptor->FindFieldByNumber(field_number);
     404             : 
     405             :       // If that failed, check if the field is an extension.
     406           0 :       if (field == NULL && descriptor->IsExtensionNumber(field_number)) {
     407           0 :         if (input->GetExtensionPool() == NULL) {
     408           0 :           field = message_reflection->FindKnownExtensionByNumber(field_number);
     409             :         } else {
     410             :           field = input->GetExtensionPool()
     411           0 :                        ->FindExtensionByNumber(descriptor, field_number);
     412             :         }
     413             :       }
     414             : 
     415             :       // If that failed, but we're a MessageSet, and this is the tag for a
     416             :       // MessageSet item, then parse that.
     417           0 :       if (field == NULL &&
     418           0 :           descriptor->options().message_set_wire_format() &&
     419             :           tag == WireFormatLite::kMessageSetItemStartTag) {
     420           0 :         if (!ParseAndMergeMessageSetItem(input, message)) {
     421             :           return false;
     422             :         }
     423             :         continue;  // Skip ParseAndMergeField(); already taken care of.
     424             :       }
     425             :     }
     426             : 
     427           0 :     if (!ParseAndMergeField(tag, field, message, input)) {
     428             :       return false;
     429             :     }
     430             :   }
     431             : }
     432             : 
     433           0 : bool WireFormat::SkipMessageSetField(io::CodedInputStream* input,
     434             :                                      uint32 field_number,
     435             :                                      UnknownFieldSet* unknown_fields) {
     436             :   uint32 length;
     437           0 :   if (!input->ReadVarint32(&length)) return false;
     438             :   return input->ReadString(
     439           0 :       unknown_fields->AddLengthDelimited(field_number), length);
     440             : }
     441             : 
     442           0 : bool WireFormat::ParseAndMergeMessageSetField(uint32 field_number,
     443           0 :                                               const FieldDescriptor* field,
     444             :                                               Message* message,
     445           0 :                                               io::CodedInputStream* input) {
     446           0 :   const Reflection* message_reflection = message->GetReflection();
     447           0 :   if (field == NULL) {
     448             :     // We store unknown MessageSet extensions as groups.
     449             :     return SkipMessageSetField(
     450           0 :         input, field_number, message_reflection->MutableUnknownFields(message));
     451           0 :   } else if (field->is_repeated() ||
     452           0 :              field->type() != FieldDescriptor::TYPE_MESSAGE) {
     453             :     // This shouldn't happen as we only allow optional message extensions to
     454             :     // MessageSet.
     455           0 :     GOOGLE_LOG(ERROR) << "Extensions of MessageSets must be optional messages.";
     456           0 :     return false;
     457             :   } else {
     458             :     Message* sub_message = message_reflection->MutableMessage(
     459           0 :         message, field, input->GetExtensionFactory());
     460           0 :     return WireFormatLite::ReadMessage(input, sub_message);
     461             :   }
     462             : }
     463             : 
     464          10 : static bool StrictUtf8Check(const FieldDescriptor* field) {
     465          10 :   return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3;
     466             : }
     467             : 
     468           0 : bool WireFormat::ParseAndMergeField(
     469             :     uint32 tag,
     470           0 :     const FieldDescriptor* field,        // May be NULL for unknown
     471             :     Message* message,
     472           0 :     io::CodedInputStream* input) {
     473           0 :   const Reflection* message_reflection = message->GetReflection();
     474             : 
     475             :   enum { UNKNOWN, NORMAL_FORMAT, PACKED_FORMAT } value_format;
     476             : 
     477           0 :   if (field == NULL) {
     478             :     value_format = UNKNOWN;
     479           0 :   } else if (WireFormatLite::GetTagWireType(tag) ==
     480           0 :              WireTypeForFieldType(field->type())) {
     481             :     value_format = NORMAL_FORMAT;
     482           0 :   } else if (field->is_packable() &&
     483             :              WireFormatLite::GetTagWireType(tag) ==
     484             :              WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
     485             :     value_format = PACKED_FORMAT;
     486             :   } else {
     487             :     // We don't recognize this field. Either the field number is unknown
     488             :     // or the wire type doesn't match. Put it in our unknown field set.
     489           0 :     value_format = UNKNOWN;
     490             :   }
     491             : 
     492           0 :   if (value_format == UNKNOWN) {
     493             :     return SkipField(input, tag,
     494           0 :                      message_reflection->MutableUnknownFields(message));
     495           0 :   } else if (value_format == PACKED_FORMAT) {
     496             :     uint32 length;
     497           0 :     if (!input->ReadVarint32(&length)) return false;
     498           0 :     io::CodedInputStream::Limit limit = input->PushLimit(length);
     499             : 
     500           0 :     switch (field->type()) {
     501             : #define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD)                      \
     502             :       case FieldDescriptor::TYPE_##TYPE: {                                     \
     503             :         while (input->BytesUntilLimit() > 0) {                                 \
     504             :           CPPTYPE value;                                                       \
     505             :           if (!WireFormatLite::ReadPrimitive<                                  \
     506             :                 CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value))          \
     507             :             return false;                                                      \
     508             :           message_reflection->Add##CPPTYPE_METHOD(message, field, value);      \
     509             :         }                                                                      \
     510             :         break;                                                                 \
     511             :       }
     512             : 
     513           0 :       HANDLE_PACKED_TYPE( INT32,  int32,  Int32)
     514           0 :       HANDLE_PACKED_TYPE( INT64,  int64,  Int64)
     515           0 :       HANDLE_PACKED_TYPE(SINT32,  int32,  Int32)
     516           0 :       HANDLE_PACKED_TYPE(SINT64,  int64,  Int64)
     517           0 :       HANDLE_PACKED_TYPE(UINT32, uint32, UInt32)
     518           0 :       HANDLE_PACKED_TYPE(UINT64, uint64, UInt64)
     519             : 
     520           0 :       HANDLE_PACKED_TYPE( FIXED32, uint32, UInt32)
     521           0 :       HANDLE_PACKED_TYPE( FIXED64, uint64, UInt64)
     522           0 :       HANDLE_PACKED_TYPE(SFIXED32,  int32,  Int32)
     523           0 :       HANDLE_PACKED_TYPE(SFIXED64,  int64,  Int64)
     524             : 
     525           0 :       HANDLE_PACKED_TYPE(FLOAT , float , Float )
     526           0 :       HANDLE_PACKED_TYPE(DOUBLE, double, Double)
     527             : 
     528           0 :       HANDLE_PACKED_TYPE(BOOL, bool, Bool)
     529             : #undef HANDLE_PACKED_TYPE
     530             : 
     531             :       case FieldDescriptor::TYPE_ENUM: {
     532           0 :         while (input->BytesUntilLimit() > 0) {
     533             :           int value;
     534           0 :           if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
     535             :                   input, &value)) return false;
     536           0 :           if (message->GetDescriptor()->file()->syntax() ==
     537             :               FileDescriptor::SYNTAX_PROTO3) {
     538           0 :             message_reflection->AddEnumValue(message, field, value);
     539             :           } else {
     540             :             const EnumValueDescriptor* enum_value =
     541           0 :                 field->enum_type()->FindValueByNumber(value);
     542           0 :             if (enum_value != NULL) {
     543           0 :               message_reflection->AddEnum(message, field, enum_value);
     544             :             } else {
     545             :               // The enum value is not one of the known values.  Add it to the
     546             :               // UnknownFieldSet.
     547           0 :               int64 sign_extended_value = static_cast<int64>(value);
     548           0 :               message_reflection->MutableUnknownFields(message)
     549             :                   ->AddVarint(
     550             :                       WireFormatLite::GetTagFieldNumber(tag),
     551           0 :                       sign_extended_value);
     552             :             }
     553             :           }
     554             :         }
     555             : 
     556             :         break;
     557             :       }
     558             : 
     559             :       case FieldDescriptor::TYPE_STRING:
     560             :       case FieldDescriptor::TYPE_GROUP:
     561             :       case FieldDescriptor::TYPE_MESSAGE:
     562             :       case FieldDescriptor::TYPE_BYTES:
     563             :         // Can't have packed fields of these types: these should be caught by
     564             :         // the protocol compiler.
     565             :         return false;
     566             :         break;
     567             :     }
     568             : 
     569           0 :     input->PopLimit(limit);
     570             :   } else {
     571             :     // Non-packed value (value_format == NORMAL_FORMAT)
     572           0 :     switch (field->type()) {
     573             : #define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD)                            \
     574             :       case FieldDescriptor::TYPE_##TYPE: {                                    \
     575             :         CPPTYPE value;                                                        \
     576             :         if (!WireFormatLite::ReadPrimitive<                                   \
     577             :                 CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value))         \
     578             :           return false;                                                       \
     579             :         if (field->is_repeated()) {                                           \
     580             :           message_reflection->Add##CPPTYPE_METHOD(message, field, value);     \
     581             :         } else {                                                              \
     582             :           message_reflection->Set##CPPTYPE_METHOD(message, field, value);     \
     583             :         }                                                                     \
     584             :         break;                                                                \
     585             :       }
     586             : 
     587           0 :       HANDLE_TYPE( INT32,  int32,  Int32)
     588           0 :       HANDLE_TYPE( INT64,  int64,  Int64)
     589           0 :       HANDLE_TYPE(SINT32,  int32,  Int32)
     590           0 :       HANDLE_TYPE(SINT64,  int64,  Int64)
     591           0 :       HANDLE_TYPE(UINT32, uint32, UInt32)
     592           0 :       HANDLE_TYPE(UINT64, uint64, UInt64)
     593             : 
     594           0 :       HANDLE_TYPE( FIXED32, uint32, UInt32)
     595           0 :       HANDLE_TYPE( FIXED64, uint64, UInt64)
     596           0 :       HANDLE_TYPE(SFIXED32,  int32,  Int32)
     597           0 :       HANDLE_TYPE(SFIXED64,  int64,  Int64)
     598             : 
     599           0 :       HANDLE_TYPE(FLOAT , float , Float )
     600           0 :       HANDLE_TYPE(DOUBLE, double, Double)
     601             : 
     602           0 :       HANDLE_TYPE(BOOL, bool, Bool)
     603             : #undef HANDLE_TYPE
     604             : 
     605             :       case FieldDescriptor::TYPE_ENUM: {
     606             :         int value;
     607           0 :         if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
     608             :                 input, &value)) return false;
     609           0 :         if (message->GetDescriptor()->file()->syntax() ==
     610             :             FileDescriptor::SYNTAX_PROTO3) {
     611           0 :           if (field->is_repeated()) {
     612           0 :             message_reflection->AddEnumValue(message, field, value);
     613             :           } else {
     614           0 :             message_reflection->SetEnumValue(message, field, value);
     615             :           }
     616             :         } else {
     617             :           const EnumValueDescriptor* enum_value =
     618           0 :               field->enum_type()->FindValueByNumber(value);
     619           0 :           if (enum_value != NULL) {
     620           0 :             if (field->is_repeated()) {
     621           0 :               message_reflection->AddEnum(message, field, enum_value);
     622             :             } else {
     623           0 :               message_reflection->SetEnum(message, field, enum_value);
     624             :             }
     625             :           } else {
     626             :             // The enum value is not one of the known values.  Add it to the
     627             :             // UnknownFieldSet.
     628           0 :             int64 sign_extended_value = static_cast<int64>(value);
     629           0 :             message_reflection->MutableUnknownFields(message)
     630             :                               ->AddVarint(
     631             :                                   WireFormatLite::GetTagFieldNumber(tag),
     632           0 :                                   sign_extended_value);
     633             :           }
     634             :         }
     635             :         break;
     636             :       }
     637             : 
     638             :       // Handle strings separately so that we can optimize the ctype=CORD case.
     639             :       case FieldDescriptor::TYPE_STRING: {
     640           0 :         bool strict_utf8_check = StrictUtf8Check(field);
     641             :         string value;
     642           0 :         if (!WireFormatLite::ReadString(input, &value)) return false;
     643           0 :         if (strict_utf8_check) {
     644           0 :           if (!WireFormatLite::VerifyUtf8String(
     645             :                   value.data(), value.length(), WireFormatLite::PARSE,
     646           0 :                   field->full_name().c_str())) {
     647             :             return false;
     648             :           }
     649             :         } else {
     650             :           VerifyUTF8StringNamedField(value.data(), value.length(), PARSE,
     651             :                                      field->full_name().c_str());
     652             :         }
     653           0 :         if (field->is_repeated()) {
     654           0 :           message_reflection->AddString(message, field, value);
     655             :         } else {
     656           0 :           message_reflection->SetString(message, field, value);
     657             :         }
     658             :         break;
     659             :       }
     660             : 
     661             :       case FieldDescriptor::TYPE_BYTES: {
     662             :         string value;
     663           0 :         if (!WireFormatLite::ReadBytes(input, &value)) return false;
     664           0 :         if (field->is_repeated()) {
     665           0 :           message_reflection->AddString(message, field, value);
     666             :         } else {
     667           0 :           message_reflection->SetString(message, field, value);
     668             :         }
     669             :         break;
     670             :       }
     671             : 
     672             :       case FieldDescriptor::TYPE_GROUP: {
     673             :         Message* sub_message;
     674           0 :         if (field->is_repeated()) {
     675             :           sub_message = message_reflection->AddMessage(
     676           0 :               message, field, input->GetExtensionFactory());
     677             :         } else {
     678             :           sub_message = message_reflection->MutableMessage(
     679           0 :               message, field, input->GetExtensionFactory());
     680             :         }
     681             : 
     682           0 :         if (!WireFormatLite::ReadGroup(WireFormatLite::GetTagFieldNumber(tag),
     683           0 :                                        input, sub_message))
     684             :           return false;
     685             :         break;
     686             :       }
     687             : 
     688             :       case FieldDescriptor::TYPE_MESSAGE: {
     689             :         Message* sub_message;
     690           0 :         if (field->is_repeated()) {
     691             :           sub_message = message_reflection->AddMessage(
     692           0 :               message, field, input->GetExtensionFactory());
     693             :         } else {
     694             :           sub_message = message_reflection->MutableMessage(
     695           0 :               message, field, input->GetExtensionFactory());
     696             :         }
     697             : 
     698           0 :         if (!WireFormatLite::ReadMessage(input, sub_message)) return false;
     699             :         break;
     700             :       }
     701             :     }
     702             :   }
     703             : 
     704             :   return true;
     705             : }
     706             : 
     707           0 : bool WireFormat::ParseAndMergeMessageSetItem(
     708             :     io::CodedInputStream* input,
     709             :     Message* message) {
     710           0 :   const Reflection* message_reflection = message->GetReflection();
     711             : 
     712             :   // This method parses a group which should contain two fields:
     713             :   //   required int32 type_id = 2;
     714             :   //   required data message = 3;
     715             : 
     716           0 :   uint32 last_type_id = 0;
     717             : 
     718             :   // Once we see a type_id, we'll look up the FieldDescriptor for the
     719             :   // extension.
     720           0 :   const FieldDescriptor* field = NULL;
     721             : 
     722             :   // If we see message data before the type_id, we'll append it to this so
     723             :   // we can parse it later.
     724             :   string message_data;
     725             : 
     726             :   while (true) {
     727           0 :     uint32 tag = input->ReadTag();
     728           0 :     if (tag == 0) return false;
     729             : 
     730           0 :     switch (tag) {
     731             :       case WireFormatLite::kMessageSetTypeIdTag: {
     732             :         uint32 type_id;
     733           0 :         if (!input->ReadVarint32(&type_id)) return false;
     734           0 :         last_type_id = type_id;
     735           0 :         field = message_reflection->FindKnownExtensionByNumber(type_id);
     736             : 
     737           0 :         if (!message_data.empty()) {
     738             :           // We saw some message data before the type_id.  Have to parse it
     739             :           // now.
     740             :           io::ArrayInputStream raw_input(message_data.data(),
     741           0 :                                          message_data.size());
     742           0 :           io::CodedInputStream sub_input(&raw_input);
     743           0 :           if (!ParseAndMergeMessageSetField(last_type_id, field, message,
     744           0 :                                             &sub_input)) {
     745           0 :             return false;
     746             :           }
     747           0 :           message_data.clear();
     748             :         }
     749             : 
     750           0 :         break;
     751             :       }
     752             : 
     753             :       case WireFormatLite::kMessageSetMessageTag: {
     754           0 :         if (last_type_id == 0) {
     755             :           // We haven't seen a type_id yet.  Append this data to message_data.
     756             :           string temp;
     757             :           uint32 length;
     758           0 :           if (!input->ReadVarint32(&length)) return false;
     759           0 :           if (!input->ReadString(&temp, length)) return false;
     760           0 :           io::StringOutputStream output_stream(&message_data);
     761           0 :           io::CodedOutputStream coded_output(&output_stream);
     762           0 :           coded_output.WriteVarint32(length);
     763             :           coded_output.WriteString(temp);
     764             :         } else {
     765             :           // Already saw type_id, so we can parse this directly.
     766           0 :           if (!ParseAndMergeMessageSetField(last_type_id, field, message,
     767           0 :                                             input)) {
     768             :             return false;
     769             :           }
     770             :         }
     771             : 
     772             :         break;
     773             :       }
     774             : 
     775             :       case WireFormatLite::kMessageSetItemEndTag: {
     776             :         return true;
     777             :       }
     778             : 
     779             :       default: {
     780           0 :         if (!SkipField(input, tag, NULL)) return false;
     781             :       }
     782             :     }
     783             :   }
     784             : }
     785             : 
     786             : // ===================================================================
     787             : 
     788          14 : void WireFormat::SerializeWithCachedSizes(
     789             :     const Message& message,
     790          56 :     int size, io::CodedOutputStream* output) {
     791          28 :   const Descriptor* descriptor = message.GetDescriptor();
     792          14 :   const Reflection* message_reflection = message.GetReflection();
     793          42 :   int expected_endpoint = output->ByteCount() + size;
     794             : 
     795             :   vector<const FieldDescriptor*> fields;
     796          14 :   message_reflection->ListFields(message, &fields);
     797          52 :   for (int i = 0; i < fields.size(); i++) {
     798          38 :     SerializeFieldWithCachedSizes(fields[i], message, output);
     799             :   }
     800             : 
     801          14 :   if (descriptor->options().message_set_wire_format()) {
     802             :     SerializeUnknownMessageSetItems(
     803           1 :         message_reflection->GetUnknownFields(message), output);
     804             :   } else {
     805             :     SerializeUnknownFields(
     806          13 :         message_reflection->GetUnknownFields(message), output);
     807             :   }
     808             : 
     809          28 :   GOOGLE_CHECK_EQ(output->ByteCount(), expected_endpoint)
     810             :     << ": Protocol message serialized to a size different from what was "
     811             :        "originally expected.  Perhaps it was modified by another thread "
     812          28 :        "during serialization?";
     813          14 : }
     814             : 
     815          19 : void WireFormat::SerializeFieldWithCachedSizes(
     816          58 :     const FieldDescriptor* field,
     817             :     const Message& message,
     818             :     io::CodedOutputStream* output) {
     819          19 :   const Reflection* message_reflection = message.GetReflection();
     820             : 
     821          40 :   if (field->is_extension() &&
     822           3 :       field->containing_type()->options().message_set_wire_format() &&
     823          21 :       field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
     824             :       !field->is_repeated()) {
     825           1 :     SerializeMessageSetItemWithCachedSizes(field, message, output);
     826          20 :     return;
     827             :   }
     828             : 
     829          18 :   int count = 0;
     830             : 
     831          18 :   if (field->is_repeated()) {
     832           0 :     count = message_reflection->FieldSize(message, field);
     833          18 :   } else if (message_reflection->HasField(message, field)) {
     834          18 :     count = 1;
     835             :   }
     836             : 
     837          18 :   const bool is_packed = field->is_packed();
     838          18 :   if (is_packed && count > 0) {
     839             :     WireFormatLite::WriteTag(field->number(),
     840           0 :         WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
     841           0 :     const int data_size = FieldDataOnlyByteSize(field, message);
     842           0 :     output->WriteVarint32(data_size);
     843             :   }
     844             : 
     845          18 :   for (int j = 0; j < count; j++) {
     846          18 :     switch (field->type()) {
     847             : #define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD)      \
     848             :       case FieldDescriptor::TYPE_##TYPE: {                                     \
     849             :         const CPPTYPE value = field->is_repeated() ?                           \
     850             :                               message_reflection->GetRepeated##CPPTYPE_METHOD( \
     851             :                                 message, field, j) :                           \
     852             :                               message_reflection->Get##CPPTYPE_METHOD(         \
     853             :                                 message, field);                               \
     854             :         if (is_packed) {                                                       \
     855             :           WireFormatLite::Write##TYPE_METHOD##NoTag(value, output);            \
     856             :         } else {                                                               \
     857             :           WireFormatLite::Write##TYPE_METHOD(field->number(), value, output);  \
     858             :         }                                                                      \
     859             :         break;                                                                 \
     860             :       }
     861             : 
     862           8 :       HANDLE_PRIMITIVE_TYPE( INT32,  int32,  Int32,  Int32)
     863           0 :       HANDLE_PRIMITIVE_TYPE( INT64,  int64,  Int64,  Int64)
     864           0 :       HANDLE_PRIMITIVE_TYPE(SINT32,  int32, SInt32,  Int32)
     865           0 :       HANDLE_PRIMITIVE_TYPE(SINT64,  int64, SInt64,  Int64)
     866           0 :       HANDLE_PRIMITIVE_TYPE(UINT32, uint32, UInt32, UInt32)
     867           0 :       HANDLE_PRIMITIVE_TYPE(UINT64, uint64, UInt64, UInt64)
     868             : 
     869           0 :       HANDLE_PRIMITIVE_TYPE( FIXED32, uint32,  Fixed32, UInt32)
     870           0 :       HANDLE_PRIMITIVE_TYPE( FIXED64, uint64,  Fixed64, UInt64)
     871           0 :       HANDLE_PRIMITIVE_TYPE(SFIXED32,  int32, SFixed32,  Int32)
     872           0 :       HANDLE_PRIMITIVE_TYPE(SFIXED64,  int64, SFixed64,  Int64)
     873             : 
     874           0 :       HANDLE_PRIMITIVE_TYPE(FLOAT , float , Float , Float )
     875           0 :       HANDLE_PRIMITIVE_TYPE(DOUBLE, double, Double, Double)
     876             : 
     877           0 :       HANDLE_PRIMITIVE_TYPE(BOOL, bool, Bool, Bool)
     878             : #undef HANDLE_PRIMITIVE_TYPE
     879             : 
     880             : #define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD)                       \
     881             :       case FieldDescriptor::TYPE_##TYPE:                                     \
     882             :         WireFormatLite::Write##TYPE_METHOD(                                  \
     883             :               field->number(),                                               \
     884             :               field->is_repeated() ?                                         \
     885             :                 message_reflection->GetRepeated##CPPTYPE_METHOD(             \
     886             :                   message, field, j) :                                       \
     887             :                 message_reflection->Get##CPPTYPE_METHOD(message, field),     \
     888             :               output);                                                       \
     889             :         break;
     890             : 
     891           0 :       HANDLE_TYPE(GROUP  , Group  , Message)
     892           8 :       HANDLE_TYPE(MESSAGE, Message, Message)
     893             : #undef HANDLE_TYPE
     894             : 
     895             :       case FieldDescriptor::TYPE_ENUM: {
     896           0 :         const EnumValueDescriptor* value = field->is_repeated() ?
     897           0 :           message_reflection->GetRepeatedEnum(message, field, j) :
     898           0 :           message_reflection->GetEnum(message, field);
     899           0 :         if (is_packed) {
     900           0 :           WireFormatLite::WriteEnumNoTag(value->number(), output);
     901             :         } else {
     902           0 :           WireFormatLite::WriteEnum(field->number(), value->number(), output);
     903             :         }
     904             :         break;
     905             :       }
     906             : 
     907             :       // Handle strings separately so that we can get string references
     908             :       // instead of copying.
     909             :       case FieldDescriptor::TYPE_STRING: {
     910          10 :         bool strict_utf8_check = StrictUtf8Check(field);
     911             :         string scratch;
     912             :         const string& value = field->is_repeated() ?
     913             :           message_reflection->GetRepeatedStringReference(
     914           0 :             message, field, j, &scratch) :
     915          10 :           message_reflection->GetStringReference(message, field, &scratch);
     916          10 :         if (strict_utf8_check) {
     917             :           WireFormatLite::VerifyUtf8String(value.data(), value.length(),
     918             :                                            WireFormatLite::SERIALIZE,
     919           0 :                                            field->full_name().c_str());
     920             :         } else {
     921             :           VerifyUTF8StringNamedField(value.data(), value.length(), SERIALIZE,
     922             :                                      field->full_name().c_str());
     923             :         }
     924          10 :         WireFormatLite::WriteString(field->number(), value, output);
     925             :         break;
     926             :       }
     927             : 
     928             :       case FieldDescriptor::TYPE_BYTES: {
     929             :         string scratch;
     930             :         const string& value = field->is_repeated() ?
     931             :           message_reflection->GetRepeatedStringReference(
     932           0 :             message, field, j, &scratch) :
     933           0 :           message_reflection->GetStringReference(message, field, &scratch);
     934           0 :         WireFormatLite::WriteBytes(field->number(), value, output);
     935             :         break;
     936             :       }
     937             :     }
     938             :   }
     939             : }
     940             : 
     941           1 : void WireFormat::SerializeMessageSetItemWithCachedSizes(
     942           1 :     const FieldDescriptor* field,
     943             :     const Message& message,
     944             :     io::CodedOutputStream* output) {
     945           1 :   const Reflection* message_reflection = message.GetReflection();
     946             : 
     947             :   // Start group.
     948           1 :   output->WriteVarint32(WireFormatLite::kMessageSetItemStartTag);
     949             : 
     950             :   // Write type ID.
     951           1 :   output->WriteVarint32(WireFormatLite::kMessageSetTypeIdTag);
     952           1 :   output->WriteVarint32(field->number());
     953             : 
     954             :   // Write message.
     955           1 :   output->WriteVarint32(WireFormatLite::kMessageSetMessageTag);
     956             : 
     957           1 :   const Message& sub_message = message_reflection->GetMessage(message, field);
     958           1 :   output->WriteVarint32(sub_message.GetCachedSize());
     959           1 :   sub_message.SerializeWithCachedSizes(output);
     960             : 
     961             :   // End group.
     962           1 :   output->WriteVarint32(WireFormatLite::kMessageSetItemEndTag);
     963           1 : }
     964             : 
     965             : // ===================================================================
     966             : 
     967          14 : int WireFormat::ByteSize(const Message& message) {
     968          28 :   const Descriptor* descriptor = message.GetDescriptor();
     969          14 :   const Reflection* message_reflection = message.GetReflection();
     970             : 
     971          14 :   int our_size = 0;
     972             : 
     973             :   vector<const FieldDescriptor*> fields;
     974          14 :   message_reflection->ListFields(message, &fields);
     975          52 :   for (int i = 0; i < fields.size(); i++) {
     976          38 :     our_size += FieldByteSize(fields[i], message);
     977             :   }
     978             : 
     979          14 :   if (descriptor->options().message_set_wire_format()) {
     980             :     our_size += ComputeUnknownMessageSetItemsSize(
     981           1 :       message_reflection->GetUnknownFields(message));
     982             :   } else {
     983             :     our_size += ComputeUnknownFieldsSize(
     984          13 :       message_reflection->GetUnknownFields(message));
     985             :   }
     986             : 
     987          28 :   return our_size;
     988             : }
     989             : 
     990          19 : int WireFormat::FieldByteSize(
     991          58 :     const FieldDescriptor* field,
     992             :     const Message& message) {
     993          19 :   const Reflection* message_reflection = message.GetReflection();
     994             : 
     995          40 :   if (field->is_extension() &&
     996           3 :       field->containing_type()->options().message_set_wire_format() &&
     997          21 :       field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
     998             :       !field->is_repeated()) {
     999           1 :     return MessageSetItemByteSize(field, message);
    1000             :   }
    1001             : 
    1002          18 :   int count = 0;
    1003          18 :   if (field->is_repeated()) {
    1004           0 :     count = message_reflection->FieldSize(message, field);
    1005          18 :   } else if (message_reflection->HasField(message, field)) {
    1006          18 :     count = 1;
    1007             :   }
    1008             : 
    1009          18 :   const int data_size = FieldDataOnlyByteSize(field, message);
    1010          18 :   int our_size = data_size;
    1011          18 :   if (field->is_packed()) {
    1012           0 :     if (data_size > 0) {
    1013             :       // Packed fields get serialized like a string, not their native type.
    1014             :       // Technically this doesn't really matter; the size only changes if it's
    1015             :       // a GROUP
    1016           0 :       our_size += TagSize(field->number(), FieldDescriptor::TYPE_STRING);
    1017           0 :       our_size += io::CodedOutputStream::VarintSize32(data_size);
    1018             :     }
    1019             :   } else {
    1020          54 :     our_size += count * TagSize(field->number(), field->type());
    1021             :   }
    1022          18 :   return our_size;
    1023             : }
    1024             : 
    1025          18 : int WireFormat::FieldDataOnlyByteSize(
    1026          18 :     const FieldDescriptor* field,
    1027             :     const Message& message) {
    1028          18 :   const Reflection* message_reflection = message.GetReflection();
    1029             : 
    1030          18 :   int count = 0;
    1031          18 :   if (field->is_repeated()) {
    1032           0 :     count = message_reflection->FieldSize(message, field);
    1033          18 :   } else if (message_reflection->HasField(message, field)) {
    1034          18 :     count = 1;
    1035             :   }
    1036             : 
    1037          18 :   int data_size = 0;
    1038          18 :   switch (field->type()) {
    1039             : #define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD)                     \
    1040             :     case FieldDescriptor::TYPE_##TYPE:                                     \
    1041             :       if (field->is_repeated()) {                                          \
    1042             :         for (int j = 0; j < count; j++) {                                  \
    1043             :           data_size += WireFormatLite::TYPE_METHOD##Size(                  \
    1044             :             message_reflection->GetRepeated##CPPTYPE_METHOD(               \
    1045             :               message, field, j));                                         \
    1046             :         }                                                                  \
    1047             :       } else {                                                             \
    1048             :         data_size += WireFormatLite::TYPE_METHOD##Size(                    \
    1049             :           message_reflection->Get##CPPTYPE_METHOD(message, field));        \
    1050             :       }                                                                    \
    1051             :       break;
    1052             : 
    1053             : #define HANDLE_FIXED_TYPE(TYPE, TYPE_METHOD)                               \
    1054             :     case FieldDescriptor::TYPE_##TYPE:                                     \
    1055             :       data_size += count * WireFormatLite::k##TYPE_METHOD##Size;           \
    1056             :       break;
    1057             : 
    1058           8 :     HANDLE_TYPE( INT32,  Int32,  Int32)
    1059           0 :     HANDLE_TYPE( INT64,  Int64,  Int64)
    1060           0 :     HANDLE_TYPE(SINT32, SInt32,  Int32)
    1061           0 :     HANDLE_TYPE(SINT64, SInt64,  Int64)
    1062           0 :     HANDLE_TYPE(UINT32, UInt32, UInt32)
    1063           0 :     HANDLE_TYPE(UINT64, UInt64, UInt64)
    1064             : 
    1065           0 :     HANDLE_FIXED_TYPE( FIXED32,  Fixed32)
    1066           0 :     HANDLE_FIXED_TYPE( FIXED64,  Fixed64)
    1067           0 :     HANDLE_FIXED_TYPE(SFIXED32, SFixed32)
    1068           0 :     HANDLE_FIXED_TYPE(SFIXED64, SFixed64)
    1069             : 
    1070           0 :     HANDLE_FIXED_TYPE(FLOAT , Float )
    1071           0 :     HANDLE_FIXED_TYPE(DOUBLE, Double)
    1072             : 
    1073           0 :     HANDLE_FIXED_TYPE(BOOL, Bool)
    1074             : 
    1075           0 :     HANDLE_TYPE(GROUP  , Group  , Message)
    1076           4 :     HANDLE_TYPE(MESSAGE, Message, Message)
    1077             : #undef HANDLE_TYPE
    1078             : #undef HANDLE_FIXED_TYPE
    1079             : 
    1080             :     case FieldDescriptor::TYPE_ENUM: {
    1081           0 :       if (field->is_repeated()) {
    1082           0 :         for (int j = 0; j < count; j++) {
    1083             :           data_size += WireFormatLite::EnumSize(
    1084           0 :             message_reflection->GetRepeatedEnum(message, field, j)->number());
    1085             :         }
    1086             :       } else {
    1087             :         data_size += WireFormatLite::EnumSize(
    1088           0 :           message_reflection->GetEnum(message, field)->number());
    1089             :       }
    1090             :       break;
    1091             :     }
    1092             : 
    1093             :     // Handle strings separately so that we can get string references
    1094             :     // instead of copying.
    1095             :     case FieldDescriptor::TYPE_STRING:
    1096             :     case FieldDescriptor::TYPE_BYTES: {
    1097          10 :       for (int j = 0; j < count; j++) {
    1098             :         string scratch;
    1099             :         const string& value = field->is_repeated() ?
    1100             :           message_reflection->GetRepeatedStringReference(
    1101           0 :             message, field, j, &scratch) :
    1102          10 :           message_reflection->GetStringReference(message, field, &scratch);
    1103          10 :         data_size += WireFormatLite::StringSize(value);
    1104             :       }
    1105             :       break;
    1106             :     }
    1107             :   }
    1108          18 :   return data_size;
    1109             : }
    1110             : 
    1111           1 : int WireFormat::MessageSetItemByteSize(
    1112           1 :     const FieldDescriptor* field,
    1113             :     const Message& message) {
    1114           1 :   const Reflection* message_reflection = message.GetReflection();
    1115             : 
    1116           1 :   int our_size = WireFormatLite::kMessageSetItemTagsSize;
    1117             : 
    1118             :   // type_id
    1119           2 :   our_size += io::CodedOutputStream::VarintSize32(field->number());
    1120             : 
    1121             :   // message
    1122           1 :   const Message& sub_message = message_reflection->GetMessage(message, field);
    1123           1 :   int message_size = sub_message.ByteSize();
    1124             : 
    1125           2 :   our_size += io::CodedOutputStream::VarintSize32(message_size);
    1126           1 :   our_size += message_size;
    1127             : 
    1128           1 :   return our_size;
    1129             : }
    1130             : 
    1131             : }  // namespace internal
    1132             : }  // namespace protobuf
    1133             : }  // namespace google

Generated by: LCOV version 1.10