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 <google/protobuf/wire_format.h>
36 
37 #include <stack>
38 #include <string>
39 #include <vector>
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.pb.h>
45 #include <google/protobuf/parse_context.h>
46 #include <google/protobuf/io/coded_stream.h>
47 #include <google/protobuf/io/zero_copy_stream.h>
48 #include <google/protobuf/io/zero_copy_stream_impl.h>
49 #include <google/protobuf/descriptor.h>
50 #include <google/protobuf/dynamic_message.h>
51 #include <google/protobuf/map_field.h>
52 #include <google/protobuf/map_field_inl.h>
53 #include <google/protobuf/message.h>
54 #include <google/protobuf/message_lite.h>
55 #include <google/protobuf/unknown_field_set.h>
56 
57 
58 #include <google/protobuf/port_def.inc>
59 
60 const size_t kMapEntryTagByteSize = 2;
61 
62 namespace google {
63 namespace protobuf {
64 namespace internal {
65 
66 // Forward declare static functions
67 static size_t MapValueRefDataOnlyByteSize(const FieldDescriptor* field,
68                                           const MapValueConstRef& value);
69 
70 // ===================================================================
71 
SkipField(io::CodedInputStream * input,uint32_t tag)72 bool UnknownFieldSetFieldSkipper::SkipField(io::CodedInputStream* input,
73                                             uint32_t tag) {
74   return WireFormat::SkipField(input, tag, unknown_fields_);
75 }
76 
SkipMessage(io::CodedInputStream * input)77 bool UnknownFieldSetFieldSkipper::SkipMessage(io::CodedInputStream* input) {
78   return WireFormat::SkipMessage(input, unknown_fields_);
79 }
80 
SkipUnknownEnum(int field_number,int value)81 void UnknownFieldSetFieldSkipper::SkipUnknownEnum(int field_number, int value) {
82   unknown_fields_->AddVarint(field_number, value);
83 }
84 
SkipField(io::CodedInputStream * input,uint32_t tag,UnknownFieldSet * unknown_fields)85 bool WireFormat::SkipField(io::CodedInputStream* input, uint32_t tag,
86                            UnknownFieldSet* unknown_fields) {
87   int number = WireFormatLite::GetTagFieldNumber(tag);
88   // Field number 0 is illegal.
89   if (number == 0) return false;
90 
91   switch (WireFormatLite::GetTagWireType(tag)) {
92     case WireFormatLite::WIRETYPE_VARINT: {
93       uint64_t value;
94       if (!input->ReadVarint64(&value)) return false;
95       if (unknown_fields != NULL) unknown_fields->AddVarint(number, value);
96       return true;
97     }
98     case WireFormatLite::WIRETYPE_FIXED64: {
99       uint64_t value;
100       if (!input->ReadLittleEndian64(&value)) return false;
101       if (unknown_fields != NULL) unknown_fields->AddFixed64(number, value);
102       return true;
103     }
104     case WireFormatLite::WIRETYPE_LENGTH_DELIMITED: {
105       uint32_t length;
106       if (!input->ReadVarint32(&length)) return false;
107       if (unknown_fields == NULL) {
108         if (!input->Skip(length)) return false;
109       } else {
110         if (!input->ReadString(unknown_fields->AddLengthDelimited(number),
111                                length)) {
112           return false;
113         }
114       }
115       return true;
116     }
117     case WireFormatLite::WIRETYPE_START_GROUP: {
118       if (!input->IncrementRecursionDepth()) return false;
119       if (!SkipMessage(input, (unknown_fields == NULL)
120                                   ? NULL
121                                   : unknown_fields->AddGroup(number))) {
122         return false;
123       }
124       input->DecrementRecursionDepth();
125       // Check that the ending tag matched the starting tag.
126       if (!input->LastTagWas(
127               WireFormatLite::MakeTag(WireFormatLite::GetTagFieldNumber(tag),
128                                       WireFormatLite::WIRETYPE_END_GROUP))) {
129         return false;
130       }
131       return true;
132     }
133     case WireFormatLite::WIRETYPE_END_GROUP: {
134       return false;
135     }
136     case WireFormatLite::WIRETYPE_FIXED32: {
137       uint32_t value;
138       if (!input->ReadLittleEndian32(&value)) return false;
139       if (unknown_fields != NULL) unknown_fields->AddFixed32(number, value);
140       return true;
141     }
142     default: {
143       return false;
144     }
145   }
146 }
147 
SkipMessage(io::CodedInputStream * input,UnknownFieldSet * unknown_fields)148 bool WireFormat::SkipMessage(io::CodedInputStream* input,
149                              UnknownFieldSet* unknown_fields) {
150   while (true) {
151     uint32_t tag = input->ReadTag();
152     if (tag == 0) {
153       // End of input.  This is a valid place to end, so return true.
154       return true;
155     }
156 
157     WireFormatLite::WireType wire_type = WireFormatLite::GetTagWireType(tag);
158 
159     if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
160       // Must be the end of the message.
161       return true;
162     }
163 
164     if (!SkipField(input, tag, unknown_fields)) return false;
165   }
166 }
167 
ReadPackedEnumPreserveUnknowns(io::CodedInputStream * input,uint32_t field_number,bool (* is_valid)(int),UnknownFieldSet * unknown_fields,RepeatedField<int> * values)168 bool WireFormat::ReadPackedEnumPreserveUnknowns(io::CodedInputStream* input,
169                                                 uint32_t field_number,
170                                                 bool (*is_valid)(int),
171                                                 UnknownFieldSet* unknown_fields,
172                                                 RepeatedField<int>* values) {
173   uint32_t length;
174   if (!input->ReadVarint32(&length)) return false;
175   io::CodedInputStream::Limit limit = input->PushLimit(length);
176   while (input->BytesUntilLimit() > 0) {
177     int value;
178     if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
179             input, &value)) {
180       return false;
181     }
182     if (is_valid == NULL || is_valid(value)) {
183       values->Add(value);
184     } else {
185       unknown_fields->AddVarint(field_number, value);
186     }
187   }
188   input->PopLimit(limit);
189   return true;
190 }
191 
InternalSerializeUnknownFieldsToArray(const UnknownFieldSet & unknown_fields,uint8_t * target,io::EpsCopyOutputStream * stream)192 uint8_t* WireFormat::InternalSerializeUnknownFieldsToArray(
193     const UnknownFieldSet& unknown_fields, uint8_t* target,
194     io::EpsCopyOutputStream* stream) {
195   for (int i = 0; i < unknown_fields.field_count(); i++) {
196     const UnknownField& field = unknown_fields.field(i);
197 
198     target = stream->EnsureSpace(target);
199     switch (field.type()) {
200       case UnknownField::TYPE_VARINT:
201         target = WireFormatLite::WriteUInt64ToArray(field.number(),
202                                                     field.varint(), target);
203         break;
204       case UnknownField::TYPE_FIXED32:
205         target = WireFormatLite::WriteFixed32ToArray(field.number(),
206                                                      field.fixed32(), target);
207         break;
208       case UnknownField::TYPE_FIXED64:
209         target = WireFormatLite::WriteFixed64ToArray(field.number(),
210                                                      field.fixed64(), target);
211         break;
212       case UnknownField::TYPE_LENGTH_DELIMITED:
213         target = stream->WriteString(field.number(), field.length_delimited(),
214                                      target);
215         break;
216       case UnknownField::TYPE_GROUP:
217         target = WireFormatLite::WriteTagToArray(
218             field.number(), WireFormatLite::WIRETYPE_START_GROUP, target);
219         target = InternalSerializeUnknownFieldsToArray(field.group(), target,
220                                                        stream);
221         target = stream->EnsureSpace(target);
222         target = WireFormatLite::WriteTagToArray(
223             field.number(), WireFormatLite::WIRETYPE_END_GROUP, target);
224         break;
225     }
226   }
227   return target;
228 }
229 
InternalSerializeUnknownMessageSetItemsToArray(const UnknownFieldSet & unknown_fields,uint8_t * target,io::EpsCopyOutputStream * stream)230 uint8_t* WireFormat::InternalSerializeUnknownMessageSetItemsToArray(
231     const UnknownFieldSet& unknown_fields, uint8_t* target,
232     io::EpsCopyOutputStream* stream) {
233   for (int i = 0; i < unknown_fields.field_count(); i++) {
234     const UnknownField& field = unknown_fields.field(i);
235 
236     // The only unknown fields that are allowed to exist in a MessageSet are
237     // messages, which are length-delimited.
238     if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) {
239       target = stream->EnsureSpace(target);
240       // Start group.
241       target = io::CodedOutputStream::WriteTagToArray(
242           WireFormatLite::kMessageSetItemStartTag, target);
243 
244       // Write type ID.
245       target = io::CodedOutputStream::WriteTagToArray(
246           WireFormatLite::kMessageSetTypeIdTag, target);
247       target =
248           io::CodedOutputStream::WriteVarint32ToArray(field.number(), target);
249 
250       // Write message.
251       target = io::CodedOutputStream::WriteTagToArray(
252           WireFormatLite::kMessageSetMessageTag, target);
253 
254       target = field.InternalSerializeLengthDelimitedNoTag(target, stream);
255 
256       target = stream->EnsureSpace(target);
257       // End group.
258       target = io::CodedOutputStream::WriteTagToArray(
259           WireFormatLite::kMessageSetItemEndTag, target);
260     }
261   }
262 
263   return target;
264 }
265 
ComputeUnknownFieldsSize(const UnknownFieldSet & unknown_fields)266 size_t WireFormat::ComputeUnknownFieldsSize(
267     const UnknownFieldSet& unknown_fields) {
268   size_t size = 0;
269   for (int i = 0; i < unknown_fields.field_count(); i++) {
270     const UnknownField& field = unknown_fields.field(i);
271 
272     switch (field.type()) {
273       case UnknownField::TYPE_VARINT:
274         size += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag(
275             field.number(), WireFormatLite::WIRETYPE_VARINT));
276         size += io::CodedOutputStream::VarintSize64(field.varint());
277         break;
278       case UnknownField::TYPE_FIXED32:
279         size += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag(
280             field.number(), WireFormatLite::WIRETYPE_FIXED32));
281         size += sizeof(int32_t);
282         break;
283       case UnknownField::TYPE_FIXED64:
284         size += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag(
285             field.number(), WireFormatLite::WIRETYPE_FIXED64));
286         size += sizeof(int64_t);
287         break;
288       case UnknownField::TYPE_LENGTH_DELIMITED:
289         size += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag(
290             field.number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED));
291         size += io::CodedOutputStream::VarintSize32(
292             field.length_delimited().size());
293         size += field.length_delimited().size();
294         break;
295       case UnknownField::TYPE_GROUP:
296         size += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag(
297             field.number(), WireFormatLite::WIRETYPE_START_GROUP));
298         size += ComputeUnknownFieldsSize(field.group());
299         size += io::CodedOutputStream::VarintSize32(WireFormatLite::MakeTag(
300             field.number(), WireFormatLite::WIRETYPE_END_GROUP));
301         break;
302     }
303   }
304 
305   return size;
306 }
307 
ComputeUnknownMessageSetItemsSize(const UnknownFieldSet & unknown_fields)308 size_t WireFormat::ComputeUnknownMessageSetItemsSize(
309     const UnknownFieldSet& unknown_fields) {
310   size_t size = 0;
311   for (int i = 0; i < unknown_fields.field_count(); i++) {
312     const UnknownField& field = unknown_fields.field(i);
313 
314     // The only unknown fields that are allowed to exist in a MessageSet are
315     // messages, which are length-delimited.
316     if (field.type() == UnknownField::TYPE_LENGTH_DELIMITED) {
317       size += WireFormatLite::kMessageSetItemTagsSize;
318       size += io::CodedOutputStream::VarintSize32(field.number());
319 
320       int field_size = field.GetLengthDelimitedSize();
321       size += io::CodedOutputStream::VarintSize32(field_size);
322       size += field_size;
323     }
324   }
325 
326   return size;
327 }
328 
329 // ===================================================================
330 
ParseAndMergePartial(io::CodedInputStream * input,Message * message)331 bool WireFormat::ParseAndMergePartial(io::CodedInputStream* input,
332                                       Message* message) {
333   const Descriptor* descriptor = message->GetDescriptor();
334   const Reflection* message_reflection = message->GetReflection();
335 
336   while (true) {
337     uint32_t tag = input->ReadTag();
338     if (tag == 0) {
339       // End of input.  This is a valid place to end, so return true.
340       return true;
341     }
342 
343     if (WireFormatLite::GetTagWireType(tag) ==
344         WireFormatLite::WIRETYPE_END_GROUP) {
345       // Must be the end of the message.
346       return true;
347     }
348 
349     const FieldDescriptor* field = NULL;
350 
351     if (descriptor != NULL) {
352       int field_number = WireFormatLite::GetTagFieldNumber(tag);
353       field = descriptor->FindFieldByNumber(field_number);
354 
355       // If that failed, check if the field is an extension.
356       if (field == NULL && descriptor->IsExtensionNumber(field_number)) {
357         if (input->GetExtensionPool() == NULL) {
358           field = message_reflection->FindKnownExtensionByNumber(field_number);
359         } else {
360           field = input->GetExtensionPool()->FindExtensionByNumber(
361               descriptor, field_number);
362         }
363       }
364 
365       // If that failed, but we're a MessageSet, and this is the tag for a
366       // MessageSet item, then parse that.
367       if (field == NULL && descriptor->options().message_set_wire_format() &&
368           tag == WireFormatLite::kMessageSetItemStartTag) {
369         if (!ParseAndMergeMessageSetItem(input, message)) {
370           return false;
371         }
372         continue;  // Skip ParseAndMergeField(); already taken care of.
373       }
374     }
375 
376     if (!ParseAndMergeField(tag, field, message, input)) {
377       return false;
378     }
379   }
380 }
381 
SkipMessageSetField(io::CodedInputStream * input,uint32_t field_number,UnknownFieldSet * unknown_fields)382 bool WireFormat::SkipMessageSetField(io::CodedInputStream* input,
383                                      uint32_t field_number,
384                                      UnknownFieldSet* unknown_fields) {
385   uint32_t length;
386   if (!input->ReadVarint32(&length)) return false;
387   return input->ReadString(unknown_fields->AddLengthDelimited(field_number),
388                            length);
389 }
390 
ParseAndMergeMessageSetField(uint32_t field_number,const FieldDescriptor * field,Message * message,io::CodedInputStream * input)391 bool WireFormat::ParseAndMergeMessageSetField(uint32_t field_number,
392                                               const FieldDescriptor* field,
393                                               Message* message,
394                                               io::CodedInputStream* input) {
395   const Reflection* message_reflection = message->GetReflection();
396   if (field == NULL) {
397     // We store unknown MessageSet extensions as groups.
398     return SkipMessageSetField(
399         input, field_number, message_reflection->MutableUnknownFields(message));
400   } else if (field->is_repeated() ||
401              field->type() != FieldDescriptor::TYPE_MESSAGE) {
402     // This shouldn't happen as we only allow optional message extensions to
403     // MessageSet.
404     GOOGLE_LOG(ERROR) << "Extensions of MessageSets must be optional messages.";
405     return false;
406   } else {
407     Message* sub_message = message_reflection->MutableMessage(
408         message, field, input->GetExtensionFactory());
409     return WireFormatLite::ReadMessage(input, sub_message);
410   }
411 }
412 
StrictUtf8Check(const FieldDescriptor * field)413 static bool StrictUtf8Check(const FieldDescriptor* field) {
414   return field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3;
415 }
416 
ParseAndMergeField(uint32_t tag,const FieldDescriptor * field,Message * message,io::CodedInputStream * input)417 bool WireFormat::ParseAndMergeField(
418     uint32_t tag,
419     const FieldDescriptor* field,  // May be NULL for unknown
420     Message* message, io::CodedInputStream* input) {
421   const Reflection* message_reflection = message->GetReflection();
422 
423   enum { UNKNOWN, NORMAL_FORMAT, PACKED_FORMAT } value_format;
424 
425   if (field == NULL) {
426     value_format = UNKNOWN;
427   } else if (WireFormatLite::GetTagWireType(tag) ==
428              WireTypeForFieldType(field->type())) {
429     value_format = NORMAL_FORMAT;
430   } else if (field->is_packable() &&
431              WireFormatLite::GetTagWireType(tag) ==
432                  WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
433     value_format = PACKED_FORMAT;
434   } else {
435     // We don't recognize this field. Either the field number is unknown
436     // or the wire type doesn't match. Put it in our unknown field set.
437     value_format = UNKNOWN;
438   }
439 
440   if (value_format == UNKNOWN) {
441     return SkipField(input, tag,
442                      message_reflection->MutableUnknownFields(message));
443   } else if (value_format == PACKED_FORMAT) {
444     uint32_t length;
445     if (!input->ReadVarint32(&length)) return false;
446     io::CodedInputStream::Limit limit = input->PushLimit(length);
447 
448     switch (field->type()) {
449 #define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD)                      \
450   case FieldDescriptor::TYPE_##TYPE: {                                         \
451     while (input->BytesUntilLimit() > 0) {                                     \
452       CPPTYPE value;                                                           \
453       if (!WireFormatLite::ReadPrimitive<CPPTYPE,                              \
454                                          WireFormatLite::TYPE_##TYPE>(input,   \
455                                                                       &value)) \
456         return false;                                                          \
457       message_reflection->Add##CPPTYPE_METHOD(message, field, value);          \
458     }                                                                          \
459     break;                                                                     \
460   }
461 
462       HANDLE_PACKED_TYPE(INT32, int32_t, Int32)
463       HANDLE_PACKED_TYPE(INT64, int64_t, Int64)
464       HANDLE_PACKED_TYPE(SINT32, int32_t, Int32)
465       HANDLE_PACKED_TYPE(SINT64, int64_t, Int64)
466       HANDLE_PACKED_TYPE(UINT32, uint32_t, UInt32)
467       HANDLE_PACKED_TYPE(UINT64, uint64_t, UInt64)
468 
469       HANDLE_PACKED_TYPE(FIXED32, uint32_t, UInt32)
470       HANDLE_PACKED_TYPE(FIXED64, uint64_t, UInt64)
471       HANDLE_PACKED_TYPE(SFIXED32, int32_t, Int32)
472       HANDLE_PACKED_TYPE(SFIXED64, int64_t, Int64)
473 
474       HANDLE_PACKED_TYPE(FLOAT, float, Float)
475       HANDLE_PACKED_TYPE(DOUBLE, double, Double)
476 
477       HANDLE_PACKED_TYPE(BOOL, bool, Bool)
478 #undef HANDLE_PACKED_TYPE
479 
480       case FieldDescriptor::TYPE_ENUM: {
481         while (input->BytesUntilLimit() > 0) {
482           int value;
483           if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
484                   input, &value))
485             return false;
486           if (message->GetDescriptor()->file()->syntax() ==
487               FileDescriptor::SYNTAX_PROTO3) {
488             message_reflection->AddEnumValue(message, field, value);
489           } else {
490             const EnumValueDescriptor* enum_value =
491                 field->enum_type()->FindValueByNumber(value);
492             if (enum_value != NULL) {
493               message_reflection->AddEnum(message, field, enum_value);
494             } else {
495               // The enum value is not one of the known values.  Add it to the
496               // UnknownFieldSet.
497               int64_t sign_extended_value = static_cast<int64_t>(value);
498               message_reflection->MutableUnknownFields(message)->AddVarint(
499                   WireFormatLite::GetTagFieldNumber(tag), sign_extended_value);
500             }
501           }
502         }
503 
504         break;
505       }
506 
507       case FieldDescriptor::TYPE_STRING:
508       case FieldDescriptor::TYPE_GROUP:
509       case FieldDescriptor::TYPE_MESSAGE:
510       case FieldDescriptor::TYPE_BYTES:
511         // Can't have packed fields of these types: these should be caught by
512         // the protocol compiler.
513         return false;
514         break;
515     }
516 
517     input->PopLimit(limit);
518   } else {
519     // Non-packed value (value_format == NORMAL_FORMAT)
520     switch (field->type()) {
521 #define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD)                            \
522   case FieldDescriptor::TYPE_##TYPE: {                                        \
523     CPPTYPE value;                                                            \
524     if (!WireFormatLite::ReadPrimitive<CPPTYPE, WireFormatLite::TYPE_##TYPE>( \
525             input, &value))                                                   \
526       return false;                                                           \
527     if (field->is_repeated()) {                                               \
528       message_reflection->Add##CPPTYPE_METHOD(message, field, value);         \
529     } else {                                                                  \
530       message_reflection->Set##CPPTYPE_METHOD(message, field, value);         \
531     }                                                                         \
532     break;                                                                    \
533   }
534 
535       HANDLE_TYPE(INT32, int32_t, Int32)
536       HANDLE_TYPE(INT64, int64_t, Int64)
537       HANDLE_TYPE(SINT32, int32_t, Int32)
538       HANDLE_TYPE(SINT64, int64_t, Int64)
539       HANDLE_TYPE(UINT32, uint32_t, UInt32)
540       HANDLE_TYPE(UINT64, uint64_t, UInt64)
541 
542       HANDLE_TYPE(FIXED32, uint32_t, UInt32)
543       HANDLE_TYPE(FIXED64, uint64_t, UInt64)
544       HANDLE_TYPE(SFIXED32, int32_t, Int32)
545       HANDLE_TYPE(SFIXED64, int64_t, Int64)
546 
547       HANDLE_TYPE(FLOAT, float, Float)
548       HANDLE_TYPE(DOUBLE, double, Double)
549 
550       HANDLE_TYPE(BOOL, bool, Bool)
551 #undef HANDLE_TYPE
552 
553       case FieldDescriptor::TYPE_ENUM: {
554         int value;
555         if (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
556                 input, &value))
557           return false;
558         if (field->is_repeated()) {
559           message_reflection->AddEnumValue(message, field, value);
560         } else {
561           message_reflection->SetEnumValue(message, field, value);
562         }
563         break;
564       }
565 
566       // Handle strings separately so that we can optimize the ctype=CORD case.
567       case FieldDescriptor::TYPE_STRING: {
568         bool strict_utf8_check = StrictUtf8Check(field);
569         std::string value;
570         if (!WireFormatLite::ReadString(input, &value)) return false;
571         if (strict_utf8_check) {
572           if (!WireFormatLite::VerifyUtf8String(value.data(), value.length(),
573                                                 WireFormatLite::PARSE,
574                                                 field->full_name().c_str())) {
575             return false;
576           }
577         } else {
578           VerifyUTF8StringNamedField(value.data(), value.length(), PARSE,
579                                      field->full_name().c_str());
580         }
581         if (field->is_repeated()) {
582           message_reflection->AddString(message, field, value);
583         } else {
584           message_reflection->SetString(message, field, value);
585         }
586         break;
587       }
588 
589       case FieldDescriptor::TYPE_BYTES: {
590         std::string value;
591         if (!WireFormatLite::ReadBytes(input, &value)) return false;
592         if (field->is_repeated()) {
593           message_reflection->AddString(message, field, value);
594         } else {
595           message_reflection->SetString(message, field, value);
596         }
597         break;
598       }
599 
600       case FieldDescriptor::TYPE_GROUP: {
601         Message* sub_message;
602         if (field->is_repeated()) {
603           sub_message = message_reflection->AddMessage(
604               message, field, input->GetExtensionFactory());
605         } else {
606           sub_message = message_reflection->MutableMessage(
607               message, field, input->GetExtensionFactory());
608         }
609 
610         if (!WireFormatLite::ReadGroup(WireFormatLite::GetTagFieldNumber(tag),
611                                        input, sub_message))
612           return false;
613         break;
614       }
615 
616       case FieldDescriptor::TYPE_MESSAGE: {
617         Message* sub_message;
618         if (field->is_repeated()) {
619           sub_message = message_reflection->AddMessage(
620               message, field, input->GetExtensionFactory());
621         } else {
622           sub_message = message_reflection->MutableMessage(
623               message, field, input->GetExtensionFactory());
624         }
625 
626         if (!WireFormatLite::ReadMessage(input, sub_message)) return false;
627         break;
628       }
629     }
630   }
631 
632   return true;
633 }
634 
ParseAndMergeMessageSetItem(io::CodedInputStream * input,Message * message)635 bool WireFormat::ParseAndMergeMessageSetItem(io::CodedInputStream* input,
636                                              Message* message) {
637   struct MSReflective {
638     bool ParseField(int type_id, io::CodedInputStream* input) {
639       const FieldDescriptor* field =
640           message_reflection->FindKnownExtensionByNumber(type_id);
641       return ParseAndMergeMessageSetField(type_id, field, message, input);
642     }
643 
644     bool SkipField(uint32_t tag, io::CodedInputStream* input) {
645       return WireFormat::SkipField(input, tag, NULL);
646     }
647 
648     const Reflection* message_reflection;
649     Message* message;
650   };
651 
652   return ParseMessageSetItemImpl(
653       input, MSReflective{message->GetReflection(), message});
654 }
655 
656 struct WireFormat::MessageSetParser {
_InternalParsegoogle::protobuf::internal::WireFormat::MessageSetParser657   const char* _InternalParse(const char* ptr, internal::ParseContext* ctx) {
658     // Parse a MessageSetItem
659     auto metadata = reflection->MutableInternalMetadata(msg);
660     std::string payload;
661     uint32_t type_id = 0;
662     bool payload_read = false;
663     while (!ctx->Done(&ptr)) {
664       // We use 64 bit tags in order to allow typeid's that span the whole
665       // range of 32 bit numbers.
666       uint32_t tag = static_cast<uint8_t>(*ptr++);
667       if (tag == WireFormatLite::kMessageSetTypeIdTag) {
668         uint64_t tmp;
669         ptr = ParseBigVarint(ptr, &tmp);
670         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
671         type_id = tmp;
672         if (payload_read) {
673           const FieldDescriptor* field;
674           if (ctx->data().pool == nullptr) {
675             field = reflection->FindKnownExtensionByNumber(type_id);
676           } else {
677             field =
678                 ctx->data().pool->FindExtensionByNumber(descriptor, type_id);
679           }
680           if (field == nullptr || field->message_type() == nullptr) {
681             WriteLengthDelimited(
682                 type_id, payload,
683                 metadata->mutable_unknown_fields<UnknownFieldSet>());
684           } else {
685             Message* value =
686                 field->is_repeated()
687                     ? reflection->AddMessage(msg, field, ctx->data().factory)
688                     : reflection->MutableMessage(msg, field,
689                                                  ctx->data().factory);
690             const char* p;
691             // We can't use regular parse from string as we have to track
692             // proper recursion depth and descriptor pools.
693             ParseContext tmp_ctx(ctx->depth(), false, &p, payload);
694             tmp_ctx.data().pool = ctx->data().pool;
695             tmp_ctx.data().factory = ctx->data().factory;
696             GOOGLE_PROTOBUF_PARSER_ASSERT(value->_InternalParse(p, &tmp_ctx) &&
697                                            tmp_ctx.EndedAtLimit());
698           }
699           type_id = 0;
700         }
701         continue;
702       } else if (tag == WireFormatLite::kMessageSetMessageTag) {
703         if (type_id == 0) {
704           int32_t size = ReadSize(&ptr);
705           GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
706           ptr = ctx->ReadString(ptr, size, &payload);
707           GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
708           payload_read = true;
709         } else {
710           // We're now parsing the payload
711           const FieldDescriptor* field = nullptr;
712           if (descriptor->IsExtensionNumber(type_id)) {
713             if (ctx->data().pool == nullptr) {
714               field = reflection->FindKnownExtensionByNumber(type_id);
715             } else {
716               field =
717                   ctx->data().pool->FindExtensionByNumber(descriptor, type_id);
718             }
719           }
720           ptr = WireFormat::_InternalParseAndMergeField(
721               msg, ptr, ctx, static_cast<uint64_t>(type_id) * 8 + 2, reflection,
722               field);
723           type_id = 0;
724         }
725       } else {
726         // An unknown field in MessageSetItem.
727         ptr = ReadTag(ptr - 1, &tag);
728         if (tag == 0 || (tag & 7) == WireFormatLite::WIRETYPE_END_GROUP) {
729           ctx->SetLastTag(tag);
730           return ptr;
731         }
732         // Skip field.
733         ptr = internal::UnknownFieldParse(
734             tag, static_cast<std::string*>(nullptr), ptr, ctx);
735       }
736       GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
737     }
738     return ptr;
739   }
740 
ParseMessageSetgoogle::protobuf::internal::WireFormat::MessageSetParser741   const char* ParseMessageSet(const char* ptr, internal::ParseContext* ctx) {
742     while (!ctx->Done(&ptr)) {
743       uint32_t tag;
744       ptr = ReadTag(ptr, &tag);
745       if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr;
746       if (tag == 0 || (tag & 7) == WireFormatLite::WIRETYPE_END_GROUP) {
747         ctx->SetLastTag(tag);
748         break;
749       }
750       if (tag == WireFormatLite::kMessageSetItemStartTag) {
751         // A message set item starts
752         ptr = ctx->ParseGroup(this, ptr, tag);
753       } else {
754         // Parse other fields as normal extensions.
755         int field_number = WireFormatLite::GetTagFieldNumber(tag);
756         const FieldDescriptor* field = nullptr;
757         if (descriptor->IsExtensionNumber(field_number)) {
758           if (ctx->data().pool == nullptr) {
759             field = reflection->FindKnownExtensionByNumber(field_number);
760           } else {
761             field = ctx->data().pool->FindExtensionByNumber(descriptor,
762                                                             field_number);
763           }
764         }
765         ptr = WireFormat::_InternalParseAndMergeField(msg, ptr, ctx, tag,
766                                                       reflection, field);
767       }
768       if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr;
769     }
770     return ptr;
771   }
772 
773   Message* msg;
774   const Descriptor* descriptor;
775   const Reflection* reflection;
776 };
777 
_InternalParse(Message * msg,const char * ptr,internal::ParseContext * ctx)778 const char* WireFormat::_InternalParse(Message* msg, const char* ptr,
779                                        internal::ParseContext* ctx) {
780   const Descriptor* descriptor = msg->GetDescriptor();
781   const Reflection* reflection = msg->GetReflection();
782   GOOGLE_DCHECK(descriptor);
783   GOOGLE_DCHECK(reflection);
784   if (descriptor->options().message_set_wire_format()) {
785     MessageSetParser message_set{msg, descriptor, reflection};
786     return message_set.ParseMessageSet(ptr, ctx);
787   }
788   while (!ctx->Done(&ptr)) {
789     uint32_t tag;
790     ptr = ReadTag(ptr, &tag);
791     if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr;
792     if (tag == 0 || (tag & 7) == WireFormatLite::WIRETYPE_END_GROUP) {
793       ctx->SetLastTag(tag);
794       break;
795     }
796     const FieldDescriptor* field = nullptr;
797 
798     int field_number = WireFormatLite::GetTagFieldNumber(tag);
799     field = descriptor->FindFieldByNumber(field_number);
800 
801     // If that failed, check if the field is an extension.
802     if (field == nullptr && descriptor->IsExtensionNumber(field_number)) {
803       if (ctx->data().pool == nullptr) {
804         field = reflection->FindKnownExtensionByNumber(field_number);
805       } else {
806         field =
807             ctx->data().pool->FindExtensionByNumber(descriptor, field_number);
808       }
809     }
810 
811     ptr = _InternalParseAndMergeField(msg, ptr, ctx, tag, reflection, field);
812     if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr;
813   }
814   return ptr;
815 }
816 
_InternalParseAndMergeField(Message * msg,const char * ptr,internal::ParseContext * ctx,uint64_t tag,const Reflection * reflection,const FieldDescriptor * field)817 const char* WireFormat::_InternalParseAndMergeField(
818     Message* msg, const char* ptr, internal::ParseContext* ctx, uint64_t tag,
819     const Reflection* reflection, const FieldDescriptor* field) {
820   if (field == nullptr) {
821     // unknown field set parser takes 64bit tags, because message set type ids
822     // span the full 32 bit range making the tag span [0, 2^35) range.
823     return internal::UnknownFieldParse(
824         tag, reflection->MutableUnknownFields(msg), ptr, ctx);
825   }
826   if (WireFormatLite::GetTagWireType(tag) !=
827       WireTypeForFieldType(field->type())) {
828     if (field->is_packable() && WireFormatLite::GetTagWireType(tag) ==
829                                     WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
830       switch (field->type()) {
831 #define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD)                   \
832   case FieldDescriptor::TYPE_##TYPE: {                                      \
833     ptr = internal::Packed##CPPTYPE_METHOD##Parser(                         \
834         reflection->MutableRepeatedFieldInternal<CPPTYPE>(msg, field), ptr, \
835         ctx);                                                               \
836     return ptr;                                                             \
837   }
838 
839         HANDLE_PACKED_TYPE(INT32, int32_t, Int32)
840         HANDLE_PACKED_TYPE(INT64, int64_t, Int64)
841         HANDLE_PACKED_TYPE(SINT32, int32_t, SInt32)
842         HANDLE_PACKED_TYPE(SINT64, int64_t, SInt64)
843         HANDLE_PACKED_TYPE(UINT32, uint32_t, UInt32)
844         HANDLE_PACKED_TYPE(UINT64, uint64_t, UInt64)
845 
846         HANDLE_PACKED_TYPE(FIXED32, uint32_t, Fixed32)
847         HANDLE_PACKED_TYPE(FIXED64, uint64_t, Fixed64)
848         HANDLE_PACKED_TYPE(SFIXED32, int32_t, SFixed32)
849         HANDLE_PACKED_TYPE(SFIXED64, int64_t, SFixed64)
850 
851         HANDLE_PACKED_TYPE(FLOAT, float, Float)
852         HANDLE_PACKED_TYPE(DOUBLE, double, Double)
853 
854         HANDLE_PACKED_TYPE(BOOL, bool, Bool)
855 #undef HANDLE_PACKED_TYPE
856 
857         case FieldDescriptor::TYPE_ENUM: {
858           auto rep_enum =
859               reflection->MutableRepeatedFieldInternal<int>(msg, field);
860           bool open_enum = false;
861           if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 ||
862               open_enum) {
863             ptr = internal::PackedEnumParser(rep_enum, ptr, ctx);
864           } else {
865             return ctx->ReadPackedVarint(
866                 ptr, [rep_enum, field, reflection, msg](uint64_t val) {
867                   if (field->enum_type()->FindValueByNumber(val) != nullptr) {
868                     rep_enum->Add(val);
869                   } else {
870                     WriteVarint(field->number(), val,
871                                 reflection->MutableUnknownFields(msg));
872                   }
873                 });
874           }
875           return ptr;
876         }
877 
878         case FieldDescriptor::TYPE_STRING:
879         case FieldDescriptor::TYPE_GROUP:
880         case FieldDescriptor::TYPE_MESSAGE:
881         case FieldDescriptor::TYPE_BYTES:
882           GOOGLE_LOG(FATAL) << "Can't reach";
883           return nullptr;
884       }
885     } else {
886       // mismatched wiretype;
887       return internal::UnknownFieldParse(
888           tag, reflection->MutableUnknownFields(msg), ptr, ctx);
889     }
890   }
891 
892   // Non-packed value
893   bool utf8_check = false;
894   bool strict_utf8_check = false;
895   switch (field->type()) {
896 #define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD)        \
897   case FieldDescriptor::TYPE_##TYPE: {                    \
898     CPPTYPE value;                                        \
899     ptr = VarintParse(ptr, &value);                       \
900     if (ptr == nullptr) return nullptr;                   \
901     if (field->is_repeated()) {                           \
902       reflection->Add##CPPTYPE_METHOD(msg, field, value); \
903     } else {                                              \
904       reflection->Set##CPPTYPE_METHOD(msg, field, value); \
905     }                                                     \
906     return ptr;                                           \
907   }
908 
909     HANDLE_TYPE(BOOL, uint64_t, Bool)
910     HANDLE_TYPE(INT32, uint32_t, Int32)
911     HANDLE_TYPE(INT64, uint64_t, Int64)
912     HANDLE_TYPE(UINT32, uint32_t, UInt32)
913     HANDLE_TYPE(UINT64, uint64_t, UInt64)
914 
915     case FieldDescriptor::TYPE_SINT32: {
916       int32_t value = ReadVarintZigZag32(&ptr);
917       if (ptr == nullptr) return nullptr;
918       if (field->is_repeated()) {
919         reflection->AddInt32(msg, field, value);
920       } else {
921         reflection->SetInt32(msg, field, value);
922       }
923       return ptr;
924     }
925     case FieldDescriptor::TYPE_SINT64: {
926       int64_t value = ReadVarintZigZag64(&ptr);
927       if (ptr == nullptr) return nullptr;
928       if (field->is_repeated()) {
929         reflection->AddInt64(msg, field, value);
930       } else {
931         reflection->SetInt64(msg, field, value);
932       }
933       return ptr;
934     }
935 #undef HANDLE_TYPE
936 #define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD)        \
937   case FieldDescriptor::TYPE_##TYPE: {                    \
938     CPPTYPE value;                                        \
939     value = UnalignedLoad<CPPTYPE>(ptr);                  \
940     ptr += sizeof(CPPTYPE);                               \
941     if (field->is_repeated()) {                           \
942       reflection->Add##CPPTYPE_METHOD(msg, field, value); \
943     } else {                                              \
944       reflection->Set##CPPTYPE_METHOD(msg, field, value); \
945     }                                                     \
946     return ptr;                                           \
947   }
948 
949       HANDLE_TYPE(FIXED32, uint32_t, UInt32)
950       HANDLE_TYPE(FIXED64, uint64_t, UInt64)
951       HANDLE_TYPE(SFIXED32, int32_t, Int32)
952       HANDLE_TYPE(SFIXED64, int64_t, Int64)
953 
954       HANDLE_TYPE(FLOAT, float, Float)
955       HANDLE_TYPE(DOUBLE, double, Double)
956 
957 #undef HANDLE_TYPE
958 
959     case FieldDescriptor::TYPE_ENUM: {
960       uint32_t value;
961       ptr = VarintParse(ptr, &value);
962       if (ptr == nullptr) return nullptr;
963       if (field->is_repeated()) {
964         reflection->AddEnumValue(msg, field, value);
965       } else {
966         reflection->SetEnumValue(msg, field, value);
967       }
968       return ptr;
969     }
970 
971     // Handle strings separately so that we can optimize the ctype=CORD case.
972     case FieldDescriptor::TYPE_STRING:
973       utf8_check = true;
974       strict_utf8_check = StrictUtf8Check(field);
975       PROTOBUF_FALLTHROUGH_INTENDED;
976     case FieldDescriptor::TYPE_BYTES: {
977       int size = ReadSize(&ptr);
978       if (ptr == nullptr) return nullptr;
979       std::string value;
980       ptr = ctx->ReadString(ptr, size, &value);
981       if (ptr == nullptr) return nullptr;
982       if (utf8_check) {
983         if (strict_utf8_check) {
984           if (!WireFormatLite::VerifyUtf8String(value.data(), value.length(),
985                                                 WireFormatLite::PARSE,
986                                                 field->full_name().c_str())) {
987             return nullptr;
988           }
989         } else {
990           VerifyUTF8StringNamedField(value.data(), value.length(), PARSE,
991                                      field->full_name().c_str());
992         }
993       }
994       if (field->is_repeated()) {
995         reflection->AddString(msg, field, value);
996       } else {
997         reflection->SetString(msg, field, value);
998       }
999       return ptr;
1000     }
1001 
1002     case FieldDescriptor::TYPE_GROUP: {
1003       Message* sub_message;
1004       if (field->is_repeated()) {
1005         sub_message = reflection->AddMessage(msg, field, ctx->data().factory);
1006       } else {
1007         sub_message =
1008             reflection->MutableMessage(msg, field, ctx->data().factory);
1009       }
1010 
1011       return ctx->ParseGroup(sub_message, ptr, tag);
1012     }
1013 
1014     case FieldDescriptor::TYPE_MESSAGE: {
1015       Message* sub_message;
1016       if (field->is_repeated()) {
1017         sub_message = reflection->AddMessage(msg, field, ctx->data().factory);
1018       } else {
1019         sub_message =
1020             reflection->MutableMessage(msg, field, ctx->data().factory);
1021       }
1022       return ctx->ParseMessage(sub_message, ptr);
1023     }
1024   }
1025 
1026   // GCC 8 complains about control reaching end of non-void function here.
1027   // Let's keep it happy by returning a nullptr.
1028   return nullptr;
1029 }
1030 
1031 // ===================================================================
1032 
_InternalSerialize(const Message & message,uint8_t * target,io::EpsCopyOutputStream * stream)1033 uint8_t* WireFormat::_InternalSerialize(const Message& message, uint8_t* target,
1034                                         io::EpsCopyOutputStream* stream) {
1035   const Descriptor* descriptor = message.GetDescriptor();
1036   const Reflection* message_reflection = message.GetReflection();
1037 
1038   std::vector<const FieldDescriptor*> fields;
1039 
1040   // Fields of map entry should always be serialized.
1041   if (descriptor->options().map_entry()) {
1042     for (int i = 0; i < descriptor->field_count(); i++) {
1043       fields.push_back(descriptor->field(i));
1044     }
1045   } else {
1046     message_reflection->ListFields(message, &fields);
1047   }
1048 
1049   for (auto field : fields) {
1050     target = InternalSerializeField(field, message, target, stream);
1051   }
1052 
1053   if (descriptor->options().message_set_wire_format()) {
1054     return InternalSerializeUnknownMessageSetItemsToArray(
1055         message_reflection->GetUnknownFields(message), target, stream);
1056   } else {
1057     return InternalSerializeUnknownFieldsToArray(
1058         message_reflection->GetUnknownFields(message), target, stream);
1059   }
1060 }
1061 
SerializeMapKeyWithCachedSizes(const FieldDescriptor * field,const MapKey & value,uint8_t * target,io::EpsCopyOutputStream * stream)1062 uint8_t* SerializeMapKeyWithCachedSizes(const FieldDescriptor* field,
1063                                         const MapKey& value, uint8_t* target,
1064                                         io::EpsCopyOutputStream* stream) {
1065   target = stream->EnsureSpace(target);
1066   switch (field->type()) {
1067     case FieldDescriptor::TYPE_DOUBLE:
1068     case FieldDescriptor::TYPE_FLOAT:
1069     case FieldDescriptor::TYPE_GROUP:
1070     case FieldDescriptor::TYPE_MESSAGE:
1071     case FieldDescriptor::TYPE_BYTES:
1072     case FieldDescriptor::TYPE_ENUM:
1073       GOOGLE_LOG(FATAL) << "Unsupported";
1074       break;
1075 #define CASE_TYPE(FieldType, CamelFieldType, CamelCppType)   \
1076   case FieldDescriptor::TYPE_##FieldType:                    \
1077     target = WireFormatLite::Write##CamelFieldType##ToArray( \
1078         1, value.Get##CamelCppType##Value(), target);        \
1079     break;
1080       CASE_TYPE(INT64, Int64, Int64)
1081       CASE_TYPE(UINT64, UInt64, UInt64)
1082       CASE_TYPE(INT32, Int32, Int32)
1083       CASE_TYPE(FIXED64, Fixed64, UInt64)
1084       CASE_TYPE(FIXED32, Fixed32, UInt32)
1085       CASE_TYPE(BOOL, Bool, Bool)
1086       CASE_TYPE(UINT32, UInt32, UInt32)
1087       CASE_TYPE(SFIXED32, SFixed32, Int32)
1088       CASE_TYPE(SFIXED64, SFixed64, Int64)
1089       CASE_TYPE(SINT32, SInt32, Int32)
1090       CASE_TYPE(SINT64, SInt64, Int64)
1091 #undef CASE_TYPE
1092     case FieldDescriptor::TYPE_STRING:
1093       target = stream->WriteString(1, value.GetStringValue(), target);
1094       break;
1095   }
1096   return target;
1097 }
1098 
SerializeMapValueRefWithCachedSizes(const FieldDescriptor * field,const MapValueConstRef & value,uint8_t * target,io::EpsCopyOutputStream * stream)1099 static uint8_t* SerializeMapValueRefWithCachedSizes(
1100     const FieldDescriptor* field, const MapValueConstRef& value,
1101     uint8_t* target, io::EpsCopyOutputStream* stream) {
1102   target = stream->EnsureSpace(target);
1103   switch (field->type()) {
1104 #define CASE_TYPE(FieldType, CamelFieldType, CamelCppType)   \
1105   case FieldDescriptor::TYPE_##FieldType:                    \
1106     target = WireFormatLite::Write##CamelFieldType##ToArray( \
1107         2, value.Get##CamelCppType##Value(), target);        \
1108     break;
1109     CASE_TYPE(INT64, Int64, Int64)
1110     CASE_TYPE(UINT64, UInt64, UInt64)
1111     CASE_TYPE(INT32, Int32, Int32)
1112     CASE_TYPE(FIXED64, Fixed64, UInt64)
1113     CASE_TYPE(FIXED32, Fixed32, UInt32)
1114     CASE_TYPE(BOOL, Bool, Bool)
1115     CASE_TYPE(UINT32, UInt32, UInt32)
1116     CASE_TYPE(SFIXED32, SFixed32, Int32)
1117     CASE_TYPE(SFIXED64, SFixed64, Int64)
1118     CASE_TYPE(SINT32, SInt32, Int32)
1119     CASE_TYPE(SINT64, SInt64, Int64)
1120     CASE_TYPE(ENUM, Enum, Enum)
1121     CASE_TYPE(DOUBLE, Double, Double)
1122     CASE_TYPE(FLOAT, Float, Float)
1123 #undef CASE_TYPE
1124     case FieldDescriptor::TYPE_STRING:
1125     case FieldDescriptor::TYPE_BYTES:
1126       target = stream->WriteString(2, value.GetStringValue(), target);
1127       break;
1128     case FieldDescriptor::TYPE_MESSAGE:
1129       target = WireFormatLite::InternalWriteMessage(2, value.GetMessageValue(),
1130                                                     target, stream);
1131       break;
1132     case FieldDescriptor::TYPE_GROUP:
1133       target = WireFormatLite::InternalWriteGroup(2, value.GetMessageValue(),
1134                                                   target, stream);
1135       break;
1136   }
1137   return target;
1138 }
1139 
1140 class MapKeySorter {
1141  public:
SortKey(const Message & message,const Reflection * reflection,const FieldDescriptor * field)1142   static std::vector<MapKey> SortKey(const Message& message,
1143                                      const Reflection* reflection,
1144                                      const FieldDescriptor* field) {
1145     std::vector<MapKey> sorted_key_list;
1146     for (MapIterator it =
1147              reflection->MapBegin(const_cast<Message*>(&message), field);
1148          it != reflection->MapEnd(const_cast<Message*>(&message), field);
1149          ++it) {
1150       sorted_key_list.push_back(it.GetKey());
1151     }
1152     MapKeyComparator comparator;
1153     std::sort(sorted_key_list.begin(), sorted_key_list.end(), comparator);
1154     return sorted_key_list;
1155   }
1156 
1157  private:
1158   class MapKeyComparator {
1159    public:
operator ()(const MapKey & a,const MapKey & b) const1160     bool operator()(const MapKey& a, const MapKey& b) const {
1161       GOOGLE_DCHECK(a.type() == b.type());
1162       switch (a.type()) {
1163 #define CASE_TYPE(CppType, CamelCppType)                                \
1164   case FieldDescriptor::CPPTYPE_##CppType: {                            \
1165     return a.Get##CamelCppType##Value() < b.Get##CamelCppType##Value(); \
1166   }
1167         CASE_TYPE(STRING, String)
1168         CASE_TYPE(INT64, Int64)
1169         CASE_TYPE(INT32, Int32)
1170         CASE_TYPE(UINT64, UInt64)
1171         CASE_TYPE(UINT32, UInt32)
1172         CASE_TYPE(BOOL, Bool)
1173 #undef CASE_TYPE
1174 
1175         default:
1176           GOOGLE_LOG(DFATAL) << "Invalid key for map field.";
1177           return true;
1178       }
1179     }
1180   };
1181 };
1182 
InternalSerializeMapEntry(const FieldDescriptor * field,const MapKey & key,const MapValueConstRef & value,uint8_t * target,io::EpsCopyOutputStream * stream)1183 static uint8_t* InternalSerializeMapEntry(const FieldDescriptor* field,
1184                                           const MapKey& key,
1185                                           const MapValueConstRef& value,
1186                                           uint8_t* target,
1187                                           io::EpsCopyOutputStream* stream) {
1188   const FieldDescriptor* key_field = field->message_type()->field(0);
1189   const FieldDescriptor* value_field = field->message_type()->field(1);
1190 
1191   size_t size = kMapEntryTagByteSize;
1192   size += MapKeyDataOnlyByteSize(key_field, key);
1193   size += MapValueRefDataOnlyByteSize(value_field, value);
1194   target = stream->EnsureSpace(target);
1195   target = WireFormatLite::WriteTagToArray(
1196       field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED, target);
1197   target = io::CodedOutputStream::WriteVarint32ToArray(size, target);
1198   target = SerializeMapKeyWithCachedSizes(key_field, key, target, stream);
1199   target =
1200       SerializeMapValueRefWithCachedSizes(value_field, value, target, stream);
1201   return target;
1202 }
1203 
InternalSerializeField(const FieldDescriptor * field,const Message & message,uint8_t * target,io::EpsCopyOutputStream * stream)1204 uint8_t* WireFormat::InternalSerializeField(const FieldDescriptor* field,
1205                                             const Message& message,
1206                                             uint8_t* target,
1207                                             io::EpsCopyOutputStream* stream) {
1208   const Reflection* message_reflection = message.GetReflection();
1209 
1210   if (field->is_extension() &&
1211       field->containing_type()->options().message_set_wire_format() &&
1212       field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
1213       !field->is_repeated()) {
1214     return InternalSerializeMessageSetItem(field, message, target, stream);
1215   }
1216 
1217   // For map fields, we can use either repeated field reflection or map
1218   // reflection.  Our choice has some subtle effects.  If we use repeated field
1219   // reflection here, then the repeated field representation becomes
1220   // authoritative for this field: any existing references that came from map
1221   // reflection remain valid for reading, but mutations to them are lost and
1222   // will be overwritten next time we call map reflection!
1223   //
1224   // So far this mainly affects Python, which keeps long-term references to map
1225   // values around, and always uses map reflection.  See: b/35918691
1226   //
1227   // Here we choose to use map reflection API as long as the internal
1228   // map is valid. In this way, the serialization doesn't change map field's
1229   // internal state and existing references that came from map reflection remain
1230   // valid for both reading and writing.
1231   if (field->is_map()) {
1232     const MapFieldBase* map_field =
1233         message_reflection->GetMapData(message, field);
1234     if (map_field->IsMapValid()) {
1235       if (stream->IsSerializationDeterministic()) {
1236         std::vector<MapKey> sorted_key_list =
1237             MapKeySorter::SortKey(message, message_reflection, field);
1238         for (std::vector<MapKey>::iterator it = sorted_key_list.begin();
1239              it != sorted_key_list.end(); ++it) {
1240           MapValueConstRef map_value;
1241           message_reflection->LookupMapValue(message, field, *it, &map_value);
1242           target =
1243               InternalSerializeMapEntry(field, *it, map_value, target, stream);
1244         }
1245       } else {
1246         for (MapIterator it = message_reflection->MapBegin(
1247                  const_cast<Message*>(&message), field);
1248              it !=
1249              message_reflection->MapEnd(const_cast<Message*>(&message), field);
1250              ++it) {
1251           target = InternalSerializeMapEntry(field, it.GetKey(),
1252                                              it.GetValueRef(), target, stream);
1253         }
1254       }
1255 
1256       return target;
1257     }
1258   }
1259   int count = 0;
1260 
1261   if (field->is_repeated()) {
1262     count = message_reflection->FieldSize(message, field);
1263   } else if (field->containing_type()->options().map_entry()) {
1264     // Map entry fields always need to be serialized.
1265     count = 1;
1266   } else if (message_reflection->HasField(message, field)) {
1267     count = 1;
1268   }
1269 
1270   // map_entries is for maps that'll be deterministically serialized.
1271   std::vector<const Message*> map_entries;
1272   if (count > 1 && field->is_map() && stream->IsSerializationDeterministic()) {
1273     map_entries =
1274         DynamicMapSorter::Sort(message, count, message_reflection, field);
1275   }
1276 
1277   if (field->is_packed()) {
1278     if (count == 0) return target;
1279     target = stream->EnsureSpace(target);
1280     switch (field->type()) {
1281 #define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD)      \
1282   case FieldDescriptor::TYPE_##TYPE: {                                         \
1283     auto r =                                                                   \
1284         message_reflection->GetRepeatedFieldInternal<CPPTYPE>(message, field); \
1285     target = stream->Write##TYPE_METHOD##Packed(                               \
1286         field->number(), r, FieldDataOnlyByteSize(field, message), target);    \
1287     break;                                                                     \
1288   }
1289 
1290       HANDLE_PRIMITIVE_TYPE(INT32, int32_t, Int32, Int32)
1291       HANDLE_PRIMITIVE_TYPE(INT64, int64_t, Int64, Int64)
1292       HANDLE_PRIMITIVE_TYPE(SINT32, int32_t, SInt32, Int32)
1293       HANDLE_PRIMITIVE_TYPE(SINT64, int64_t, SInt64, Int64)
1294       HANDLE_PRIMITIVE_TYPE(UINT32, uint32_t, UInt32, UInt32)
1295       HANDLE_PRIMITIVE_TYPE(UINT64, uint64_t, UInt64, UInt64)
1296       HANDLE_PRIMITIVE_TYPE(ENUM, int, Enum, Enum)
1297 
1298 #undef HANDLE_PRIMITIVE_TYPE
1299 #define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD)      \
1300   case FieldDescriptor::TYPE_##TYPE: {                                         \
1301     auto r =                                                                   \
1302         message_reflection->GetRepeatedFieldInternal<CPPTYPE>(message, field); \
1303     target = stream->WriteFixedPacked(field->number(), r, target);             \
1304     break;                                                                     \
1305   }
1306 
1307       HANDLE_PRIMITIVE_TYPE(FIXED32, uint32_t, Fixed32, UInt32)
1308       HANDLE_PRIMITIVE_TYPE(FIXED64, uint64_t, Fixed64, UInt64)
1309       HANDLE_PRIMITIVE_TYPE(SFIXED32, int32_t, SFixed32, Int32)
1310       HANDLE_PRIMITIVE_TYPE(SFIXED64, int64_t, SFixed64, Int64)
1311 
1312       HANDLE_PRIMITIVE_TYPE(FLOAT, float, Float, Float)
1313       HANDLE_PRIMITIVE_TYPE(DOUBLE, double, Double, Double)
1314 
1315       HANDLE_PRIMITIVE_TYPE(BOOL, bool, Bool, Bool)
1316 #undef HANDLE_PRIMITIVE_TYPE
1317       default:
1318         GOOGLE_LOG(FATAL) << "Invalid descriptor";
1319     }
1320     return target;
1321   }
1322 
1323   for (int j = 0; j < count; j++) {
1324     target = stream->EnsureSpace(target);
1325     switch (field->type()) {
1326 #define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD)     \
1327   case FieldDescriptor::TYPE_##TYPE: {                                        \
1328     const CPPTYPE value =                                                     \
1329         field->is_repeated()                                                  \
1330             ? message_reflection->GetRepeated##CPPTYPE_METHOD(message, field, \
1331                                                               j)              \
1332             : message_reflection->Get##CPPTYPE_METHOD(message, field);        \
1333     target = WireFormatLite::Write##TYPE_METHOD##ToArray(field->number(),     \
1334                                                          value, target);      \
1335     break;                                                                    \
1336   }
1337 
1338       HANDLE_PRIMITIVE_TYPE(INT32, int32_t, Int32, Int32)
1339       HANDLE_PRIMITIVE_TYPE(INT64, int64_t, Int64, Int64)
1340       HANDLE_PRIMITIVE_TYPE(SINT32, int32_t, SInt32, Int32)
1341       HANDLE_PRIMITIVE_TYPE(SINT64, int64_t, SInt64, Int64)
1342       HANDLE_PRIMITIVE_TYPE(UINT32, uint32_t, UInt32, UInt32)
1343       HANDLE_PRIMITIVE_TYPE(UINT64, uint64_t, UInt64, UInt64)
1344 
1345       HANDLE_PRIMITIVE_TYPE(FIXED32, uint32_t, Fixed32, UInt32)
1346       HANDLE_PRIMITIVE_TYPE(FIXED64, uint64_t, Fixed64, UInt64)
1347       HANDLE_PRIMITIVE_TYPE(SFIXED32, int32_t, SFixed32, Int32)
1348       HANDLE_PRIMITIVE_TYPE(SFIXED64, int64_t, SFixed64, Int64)
1349 
1350       HANDLE_PRIMITIVE_TYPE(FLOAT, float, Float, Float)
1351       HANDLE_PRIMITIVE_TYPE(DOUBLE, double, Double, Double)
1352 
1353       HANDLE_PRIMITIVE_TYPE(BOOL, bool, Bool, Bool)
1354 #undef HANDLE_PRIMITIVE_TYPE
1355 
1356 #define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD)                         \
1357   case FieldDescriptor::TYPE_##TYPE:                                           \
1358     target = WireFormatLite::InternalWrite##TYPE_METHOD(                       \
1359         field->number(),                                                       \
1360         field->is_repeated()                                                   \
1361             ? (map_entries.empty()                                             \
1362                    ? message_reflection->GetRepeated##CPPTYPE_METHOD(message,  \
1363                                                                      field, j) \
1364                    : *map_entries[j])                                          \
1365             : message_reflection->Get##CPPTYPE_METHOD(message, field),         \
1366         target, stream);                                                       \
1367     break;
1368 
1369       HANDLE_TYPE(GROUP, Group, Message)
1370       HANDLE_TYPE(MESSAGE, Message, Message)
1371 #undef HANDLE_TYPE
1372 
1373       case FieldDescriptor::TYPE_ENUM: {
1374         const EnumValueDescriptor* value =
1375             field->is_repeated()
1376                 ? message_reflection->GetRepeatedEnum(message, field, j)
1377                 : message_reflection->GetEnum(message, field);
1378         target = WireFormatLite::WriteEnumToArray(field->number(),
1379                                                   value->number(), target);
1380         break;
1381       }
1382 
1383       // Handle strings separately so that we can get string references
1384       // instead of copying.
1385       case FieldDescriptor::TYPE_STRING: {
1386         bool strict_utf8_check = StrictUtf8Check(field);
1387         std::string scratch;
1388         const std::string& value =
1389             field->is_repeated()
1390                 ? message_reflection->GetRepeatedStringReference(message, field,
1391                                                                  j, &scratch)
1392                 : message_reflection->GetStringReference(message, field,
1393                                                          &scratch);
1394         if (strict_utf8_check) {
1395           WireFormatLite::VerifyUtf8String(value.data(), value.length(),
1396                                            WireFormatLite::SERIALIZE,
1397                                            field->full_name().c_str());
1398         } else {
1399           VerifyUTF8StringNamedField(value.data(), value.length(), SERIALIZE,
1400                                      field->full_name().c_str());
1401         }
1402         target = stream->WriteString(field->number(), value, target);
1403         break;
1404       }
1405 
1406       case FieldDescriptor::TYPE_BYTES: {
1407         std::string scratch;
1408         const std::string& value =
1409             field->is_repeated()
1410                 ? message_reflection->GetRepeatedStringReference(message, field,
1411                                                                  j, &scratch)
1412                 : message_reflection->GetStringReference(message, field,
1413                                                          &scratch);
1414         target = stream->WriteString(field->number(), value, target);
1415         break;
1416       }
1417     }
1418   }
1419   return target;
1420 }
1421 
InternalSerializeMessageSetItem(const FieldDescriptor * field,const Message & message,uint8_t * target,io::EpsCopyOutputStream * stream)1422 uint8_t* WireFormat::InternalSerializeMessageSetItem(
1423     const FieldDescriptor* field, const Message& message, uint8_t* target,
1424     io::EpsCopyOutputStream* stream) {
1425   const Reflection* message_reflection = message.GetReflection();
1426 
1427   target = stream->EnsureSpace(target);
1428   // Start group.
1429   target = io::CodedOutputStream::WriteTagToArray(
1430       WireFormatLite::kMessageSetItemStartTag, target);
1431   // Write type ID.
1432   target = WireFormatLite::WriteUInt32ToArray(
1433       WireFormatLite::kMessageSetTypeIdNumber, field->number(), target);
1434   // Write message.
1435   target = WireFormatLite::InternalWriteMessage(
1436       WireFormatLite::kMessageSetMessageNumber,
1437       message_reflection->GetMessage(message, field), target, stream);
1438   // End group.
1439   target = stream->EnsureSpace(target);
1440   target = io::CodedOutputStream::WriteTagToArray(
1441       WireFormatLite::kMessageSetItemEndTag, target);
1442   return target;
1443 }
1444 
1445 // ===================================================================
1446 
ByteSize(const Message & message)1447 size_t WireFormat::ByteSize(const Message& message) {
1448   const Descriptor* descriptor = message.GetDescriptor();
1449   const Reflection* message_reflection = message.GetReflection();
1450 
1451   size_t our_size = 0;
1452 
1453   std::vector<const FieldDescriptor*> fields;
1454 
1455   // Fields of map entry should always be serialized.
1456   if (descriptor->options().map_entry()) {
1457     for (int i = 0; i < descriptor->field_count(); i++) {
1458       fields.push_back(descriptor->field(i));
1459     }
1460   } else {
1461     message_reflection->ListFields(message, &fields);
1462   }
1463 
1464   for (const FieldDescriptor* field : fields) {
1465     our_size += FieldByteSize(field, message);
1466   }
1467 
1468   if (descriptor->options().message_set_wire_format()) {
1469     our_size += ComputeUnknownMessageSetItemsSize(
1470         message_reflection->GetUnknownFields(message));
1471   } else {
1472     our_size +=
1473         ComputeUnknownFieldsSize(message_reflection->GetUnknownFields(message));
1474   }
1475 
1476   return our_size;
1477 }
1478 
FieldByteSize(const FieldDescriptor * field,const Message & message)1479 size_t WireFormat::FieldByteSize(const FieldDescriptor* field,
1480                                  const Message& message) {
1481   const Reflection* message_reflection = message.GetReflection();
1482 
1483   if (field->is_extension() &&
1484       field->containing_type()->options().message_set_wire_format() &&
1485       field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
1486       !field->is_repeated()) {
1487     return MessageSetItemByteSize(field, message);
1488   }
1489 
1490   size_t count = 0;
1491   if (field->is_repeated()) {
1492     if (field->is_map()) {
1493       const MapFieldBase* map_field =
1494           message_reflection->GetMapData(message, field);
1495       if (map_field->IsMapValid()) {
1496         count = FromIntSize(map_field->size());
1497       } else {
1498         count = FromIntSize(message_reflection->FieldSize(message, field));
1499       }
1500     } else {
1501       count = FromIntSize(message_reflection->FieldSize(message, field));
1502     }
1503   } else if (field->containing_type()->options().map_entry()) {
1504     // Map entry fields always need to be serialized.
1505     count = 1;
1506   } else if (message_reflection->HasField(message, field)) {
1507     count = 1;
1508   }
1509 
1510   const size_t data_size = FieldDataOnlyByteSize(field, message);
1511   size_t our_size = data_size;
1512   if (field->is_packed()) {
1513     if (data_size > 0) {
1514       // Packed fields get serialized like a string, not their native type.
1515       // Technically this doesn't really matter; the size only changes if it's
1516       // a GROUP
1517       our_size += TagSize(field->number(), FieldDescriptor::TYPE_STRING);
1518       our_size += io::CodedOutputStream::VarintSize32(data_size);
1519     }
1520   } else {
1521     our_size += count * TagSize(field->number(), field->type());
1522   }
1523   return our_size;
1524 }
1525 
MapKeyDataOnlyByteSize(const FieldDescriptor * field,const MapKey & value)1526 size_t MapKeyDataOnlyByteSize(const FieldDescriptor* field,
1527                               const MapKey& value) {
1528   GOOGLE_DCHECK_EQ(FieldDescriptor::TypeToCppType(field->type()), value.type());
1529   switch (field->type()) {
1530     case FieldDescriptor::TYPE_DOUBLE:
1531     case FieldDescriptor::TYPE_FLOAT:
1532     case FieldDescriptor::TYPE_GROUP:
1533     case FieldDescriptor::TYPE_MESSAGE:
1534     case FieldDescriptor::TYPE_BYTES:
1535     case FieldDescriptor::TYPE_ENUM:
1536       GOOGLE_LOG(FATAL) << "Unsupported";
1537       return 0;
1538 #define CASE_TYPE(FieldType, CamelFieldType, CamelCppType) \
1539   case FieldDescriptor::TYPE_##FieldType:                  \
1540     return WireFormatLite::CamelFieldType##Size(           \
1541         value.Get##CamelCppType##Value());
1542 
1543 #define FIXED_CASE_TYPE(FieldType, CamelFieldType) \
1544   case FieldDescriptor::TYPE_##FieldType:          \
1545     return WireFormatLite::k##CamelFieldType##Size;
1546 
1547       CASE_TYPE(INT32, Int32, Int32);
1548       CASE_TYPE(INT64, Int64, Int64);
1549       CASE_TYPE(UINT32, UInt32, UInt32);
1550       CASE_TYPE(UINT64, UInt64, UInt64);
1551       CASE_TYPE(SINT32, SInt32, Int32);
1552       CASE_TYPE(SINT64, SInt64, Int64);
1553       CASE_TYPE(STRING, String, String);
1554       FIXED_CASE_TYPE(FIXED32, Fixed32);
1555       FIXED_CASE_TYPE(FIXED64, Fixed64);
1556       FIXED_CASE_TYPE(SFIXED32, SFixed32);
1557       FIXED_CASE_TYPE(SFIXED64, SFixed64);
1558       FIXED_CASE_TYPE(BOOL, Bool);
1559 
1560 #undef CASE_TYPE
1561 #undef FIXED_CASE_TYPE
1562   }
1563   GOOGLE_LOG(FATAL) << "Cannot get here";
1564   return 0;
1565 }
1566 
MapValueRefDataOnlyByteSize(const FieldDescriptor * field,const MapValueConstRef & value)1567 static size_t MapValueRefDataOnlyByteSize(const FieldDescriptor* field,
1568                                           const MapValueConstRef& value) {
1569   switch (field->type()) {
1570     case FieldDescriptor::TYPE_GROUP:
1571       GOOGLE_LOG(FATAL) << "Unsupported";
1572       return 0;
1573 #define CASE_TYPE(FieldType, CamelFieldType, CamelCppType) \
1574   case FieldDescriptor::TYPE_##FieldType:                  \
1575     return WireFormatLite::CamelFieldType##Size(           \
1576         value.Get##CamelCppType##Value());
1577 
1578 #define FIXED_CASE_TYPE(FieldType, CamelFieldType) \
1579   case FieldDescriptor::TYPE_##FieldType:          \
1580     return WireFormatLite::k##CamelFieldType##Size;
1581 
1582       CASE_TYPE(INT32, Int32, Int32);
1583       CASE_TYPE(INT64, Int64, Int64);
1584       CASE_TYPE(UINT32, UInt32, UInt32);
1585       CASE_TYPE(UINT64, UInt64, UInt64);
1586       CASE_TYPE(SINT32, SInt32, Int32);
1587       CASE_TYPE(SINT64, SInt64, Int64);
1588       CASE_TYPE(STRING, String, String);
1589       CASE_TYPE(BYTES, Bytes, String);
1590       CASE_TYPE(ENUM, Enum, Enum);
1591       CASE_TYPE(MESSAGE, Message, Message);
1592       FIXED_CASE_TYPE(FIXED32, Fixed32);
1593       FIXED_CASE_TYPE(FIXED64, Fixed64);
1594       FIXED_CASE_TYPE(SFIXED32, SFixed32);
1595       FIXED_CASE_TYPE(SFIXED64, SFixed64);
1596       FIXED_CASE_TYPE(DOUBLE, Double);
1597       FIXED_CASE_TYPE(FLOAT, Float);
1598       FIXED_CASE_TYPE(BOOL, Bool);
1599 
1600 #undef CASE_TYPE
1601 #undef FIXED_CASE_TYPE
1602   }
1603   GOOGLE_LOG(FATAL) << "Cannot get here";
1604   return 0;
1605 }
1606 
FieldDataOnlyByteSize(const FieldDescriptor * field,const Message & message)1607 size_t WireFormat::FieldDataOnlyByteSize(const FieldDescriptor* field,
1608                                          const Message& message) {
1609   const Reflection* message_reflection = message.GetReflection();
1610 
1611   size_t data_size = 0;
1612 
1613   if (field->is_map()) {
1614     const MapFieldBase* map_field =
1615         message_reflection->GetMapData(message, field);
1616     if (map_field->IsMapValid()) {
1617       MapIterator iter(const_cast<Message*>(&message), field);
1618       MapIterator end(const_cast<Message*>(&message), field);
1619       const FieldDescriptor* key_field = field->message_type()->field(0);
1620       const FieldDescriptor* value_field = field->message_type()->field(1);
1621       for (map_field->MapBegin(&iter), map_field->MapEnd(&end); iter != end;
1622            ++iter) {
1623         size_t size = kMapEntryTagByteSize;
1624         size += MapKeyDataOnlyByteSize(key_field, iter.GetKey());
1625         size += MapValueRefDataOnlyByteSize(value_field, iter.GetValueRef());
1626         data_size += WireFormatLite::LengthDelimitedSize(size);
1627       }
1628       return data_size;
1629     }
1630   }
1631 
1632   size_t count = 0;
1633   if (field->is_repeated()) {
1634     count =
1635         internal::FromIntSize(message_reflection->FieldSize(message, field));
1636   } else if (field->containing_type()->options().map_entry()) {
1637     // Map entry fields always need to be serialized.
1638     count = 1;
1639   } else if (message_reflection->HasField(message, field)) {
1640     count = 1;
1641   }
1642 
1643   switch (field->type()) {
1644 #define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD)                      \
1645   case FieldDescriptor::TYPE_##TYPE:                                        \
1646     if (field->is_repeated()) {                                             \
1647       for (size_t j = 0; j < count; j++) {                                  \
1648         data_size += WireFormatLite::TYPE_METHOD##Size(                     \
1649             message_reflection->GetRepeated##CPPTYPE_METHOD(message, field, \
1650                                                             j));            \
1651       }                                                                     \
1652     } else {                                                                \
1653       data_size += WireFormatLite::TYPE_METHOD##Size(                       \
1654           message_reflection->Get##CPPTYPE_METHOD(message, field));         \
1655     }                                                                       \
1656     break;
1657 
1658 #define HANDLE_FIXED_TYPE(TYPE, TYPE_METHOD)                   \
1659   case FieldDescriptor::TYPE_##TYPE:                           \
1660     data_size += count * WireFormatLite::k##TYPE_METHOD##Size; \
1661     break;
1662 
1663     HANDLE_TYPE(INT32, Int32, Int32)
1664     HANDLE_TYPE(INT64, Int64, Int64)
1665     HANDLE_TYPE(SINT32, SInt32, Int32)
1666     HANDLE_TYPE(SINT64, SInt64, Int64)
1667     HANDLE_TYPE(UINT32, UInt32, UInt32)
1668     HANDLE_TYPE(UINT64, UInt64, UInt64)
1669 
1670     HANDLE_FIXED_TYPE(FIXED32, Fixed32)
1671     HANDLE_FIXED_TYPE(FIXED64, Fixed64)
1672     HANDLE_FIXED_TYPE(SFIXED32, SFixed32)
1673     HANDLE_FIXED_TYPE(SFIXED64, SFixed64)
1674 
1675     HANDLE_FIXED_TYPE(FLOAT, Float)
1676     HANDLE_FIXED_TYPE(DOUBLE, Double)
1677 
1678     HANDLE_FIXED_TYPE(BOOL, Bool)
1679 
1680     HANDLE_TYPE(GROUP, Group, Message)
1681     HANDLE_TYPE(MESSAGE, Message, Message)
1682 #undef HANDLE_TYPE
1683 #undef HANDLE_FIXED_TYPE
1684 
1685     case FieldDescriptor::TYPE_ENUM: {
1686       if (field->is_repeated()) {
1687         for (size_t j = 0; j < count; j++) {
1688           data_size += WireFormatLite::EnumSize(
1689               message_reflection->GetRepeatedEnum(message, field, j)->number());
1690         }
1691       } else {
1692         data_size += WireFormatLite::EnumSize(
1693             message_reflection->GetEnum(message, field)->number());
1694       }
1695       break;
1696     }
1697 
1698     // Handle strings separately so that we can get string references
1699     // instead of copying.
1700     case FieldDescriptor::TYPE_STRING:
1701     case FieldDescriptor::TYPE_BYTES: {
1702       for (size_t j = 0; j < count; j++) {
1703         std::string scratch;
1704         const std::string& value =
1705             field->is_repeated()
1706                 ? message_reflection->GetRepeatedStringReference(message, field,
1707                                                                  j, &scratch)
1708                 : message_reflection->GetStringReference(message, field,
1709                                                          &scratch);
1710         data_size += WireFormatLite::StringSize(value);
1711       }
1712       break;
1713     }
1714   }
1715   return data_size;
1716 }
1717 
MessageSetItemByteSize(const FieldDescriptor * field,const Message & message)1718 size_t WireFormat::MessageSetItemByteSize(const FieldDescriptor* field,
1719                                           const Message& message) {
1720   const Reflection* message_reflection = message.GetReflection();
1721 
1722   size_t our_size = WireFormatLite::kMessageSetItemTagsSize;
1723 
1724   // type_id
1725   our_size += io::CodedOutputStream::VarintSize32(field->number());
1726 
1727   // message
1728   const Message& sub_message = message_reflection->GetMessage(message, field);
1729   size_t message_size = sub_message.ByteSizeLong();
1730 
1731   our_size += io::CodedOutputStream::VarintSize32(message_size);
1732   our_size += message_size;
1733 
1734   return our_size;
1735 }
1736 
1737 // Compute the size of the UnknownFieldSet on the wire.
ComputeUnknownFieldsSize(const InternalMetadata & metadata,size_t total_size,CachedSize * cached_size)1738 size_t ComputeUnknownFieldsSize(const InternalMetadata& metadata,
1739                                 size_t total_size, CachedSize* cached_size) {
1740   total_size += WireFormat::ComputeUnknownFieldsSize(
1741       metadata.unknown_fields<UnknownFieldSet>(
1742           UnknownFieldSet::default_instance));
1743   cached_size->Set(ToCachedSize(total_size));
1744   return total_size;
1745 }
1746 
1747 }  // namespace internal
1748 }  // namespace protobuf
1749 }  // namespace google
1750 
1751 #include <google/protobuf/port_undef.inc>
1752