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