• 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 MapValueRef& 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     std::string payload;
663     uint32 type_id = 0;
664     bool payload_read = false;
665     while (!ctx->Done(&ptr)) {
666       // We use 64 bit tags in order to allow typeid's that span the whole
667       // range of 32 bit numbers.
668       uint32 tag = static_cast<uint8>(*ptr++);
669       if (tag == WireFormatLite::kMessageSetTypeIdTag) {
670         uint64 tmp;
671         ptr = ParseBigVarint(ptr, &tmp);
672         GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
673         type_id = tmp;
674         if (payload_read) {
675           const FieldDescriptor* field;
676           if (ctx->data().pool == nullptr) {
677             field = reflection->FindKnownExtensionByNumber(type_id);
678           } else {
679             field =
680                 ctx->data().pool->FindExtensionByNumber(descriptor, type_id);
681           }
682           if (field == nullptr || field->message_type() == nullptr) {
683             WriteLengthDelimited(
684                 type_id, payload,
685                 metadata->mutable_unknown_fields<UnknownFieldSet>());
686           } else {
687             Message* value =
688                 field->is_repeated()
689                     ? reflection->AddMessage(msg, field, ctx->data().factory)
690                     : reflection->MutableMessage(msg, field,
691                                                  ctx->data().factory);
692             const char* p;
693             // We can't use regular parse from string as we have to track
694             // proper recursion depth and descriptor pools.
695             ParseContext tmp_ctx(ctx->depth(), false, &p, payload);
696             tmp_ctx.data().pool = ctx->data().pool;
697             tmp_ctx.data().factory = ctx->data().factory;
698             GOOGLE_PROTOBUF_PARSER_ASSERT(value->_InternalParse(p, &tmp_ctx) &&
699                                            tmp_ctx.EndedAtLimit());
700           }
701           type_id = 0;
702         }
703         continue;
704       } else if (tag == WireFormatLite::kMessageSetMessageTag) {
705         if (type_id == 0) {
706           int32 size = ReadSize(&ptr);
707           GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
708           ptr = ctx->ReadString(ptr, size, &payload);
709           GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
710           payload_read = true;
711         } else {
712           // We're now parsing the payload
713           const FieldDescriptor* field = nullptr;
714           if (descriptor->IsExtensionNumber(type_id)) {
715             if (ctx->data().pool == nullptr) {
716               field = reflection->FindKnownExtensionByNumber(type_id);
717             } else {
718               field =
719                   ctx->data().pool->FindExtensionByNumber(descriptor, type_id);
720             }
721           }
722           ptr = WireFormat::_InternalParseAndMergeField(
723               msg, ptr, ctx, static_cast<uint64>(type_id) * 8 + 2, reflection,
724               field);
725           type_id = 0;
726         }
727       } else {
728         // An unknown field in MessageSetItem.
729         ptr = ReadTag(ptr - 1, &tag);
730         if (tag == 0 || (tag & 7) == WireFormatLite::WIRETYPE_END_GROUP) {
731           ctx->SetLastTag(tag);
732           return ptr;
733         }
734         // Skip field.
735         ptr = internal::UnknownFieldParse(
736             tag, static_cast<std::string*>(nullptr), ptr, ctx);
737       }
738       GOOGLE_PROTOBUF_PARSER_ASSERT(ptr);
739     }
740     return ptr;
741   }
742 
ParseMessageSetgoogle::protobuf::internal::WireFormat::MessageSetParser743   const char* ParseMessageSet(const char* ptr, internal::ParseContext* ctx) {
744     while (!ctx->Done(&ptr)) {
745       uint32 tag;
746       ptr = ReadTag(ptr, &tag);
747       if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr;
748       if (tag == 0 || (tag & 7) == WireFormatLite::WIRETYPE_END_GROUP) {
749         ctx->SetLastTag(tag);
750         break;
751       }
752       if (tag == WireFormatLite::kMessageSetItemStartTag) {
753         // A message set item starts
754         ptr = ctx->ParseGroup(this, ptr, tag);
755       } else {
756         // Parse other fields as normal extensions.
757         int field_number = WireFormatLite::GetTagFieldNumber(tag);
758         const FieldDescriptor* field = nullptr;
759         if (descriptor->IsExtensionNumber(field_number)) {
760           if (ctx->data().pool == nullptr) {
761             field = reflection->FindKnownExtensionByNumber(field_number);
762           } else {
763             field = ctx->data().pool->FindExtensionByNumber(descriptor,
764                                                             field_number);
765           }
766         }
767         ptr = WireFormat::_InternalParseAndMergeField(msg, ptr, ctx, tag,
768                                                       reflection, field);
769       }
770       if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr;
771     }
772     return ptr;
773   }
774 
775   Message* msg;
776   const Descriptor* descriptor;
777   const Reflection* reflection;
778 };
779 
_InternalParse(Message * msg,const char * ptr,internal::ParseContext * ctx)780 const char* WireFormat::_InternalParse(Message* msg, const char* ptr,
781                                        internal::ParseContext* ctx) {
782   const Descriptor* descriptor = msg->GetDescriptor();
783   const Reflection* reflection = msg->GetReflection();
784   GOOGLE_DCHECK(descriptor);
785   GOOGLE_DCHECK(reflection);
786   if (descriptor->options().message_set_wire_format()) {
787     MessageSetParser message_set{msg, descriptor, reflection};
788     return message_set.ParseMessageSet(ptr, ctx);
789   }
790   while (!ctx->Done(&ptr)) {
791     uint32 tag;
792     ptr = ReadTag(ptr, &tag);
793     if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr;
794     if (tag == 0 || (tag & 7) == WireFormatLite::WIRETYPE_END_GROUP) {
795       ctx->SetLastTag(tag);
796       break;
797     }
798     const FieldDescriptor* field = nullptr;
799 
800     int field_number = WireFormatLite::GetTagFieldNumber(tag);
801     field = descriptor->FindFieldByNumber(field_number);
802 
803     // If that failed, check if the field is an extension.
804     if (field == nullptr && descriptor->IsExtensionNumber(field_number)) {
805       if (ctx->data().pool == nullptr) {
806         field = reflection->FindKnownExtensionByNumber(field_number);
807       } else {
808         field =
809             ctx->data().pool->FindExtensionByNumber(descriptor, field_number);
810       }
811     }
812 
813     ptr = _InternalParseAndMergeField(msg, ptr, ctx, tag, reflection, field);
814     if (PROTOBUF_PREDICT_FALSE(ptr == nullptr)) return nullptr;
815   }
816   return ptr;
817 }
818 
_InternalParseAndMergeField(Message * msg,const char * ptr,internal::ParseContext * ctx,uint64 tag,const Reflection * reflection,const FieldDescriptor * field)819 const char* WireFormat::_InternalParseAndMergeField(
820     Message* msg, const char* ptr, internal::ParseContext* ctx, uint64 tag,
821     const Reflection* reflection, const FieldDescriptor* field) {
822   if (field == nullptr) {
823     // unknown field set parser takes 64bit tags, because message set type ids
824     // span the full 32 bit range making the tag span [0, 2^35) range.
825     return internal::UnknownFieldParse(
826         tag, reflection->MutableUnknownFields(msg), ptr, ctx);
827   }
828   if (WireFormatLite::GetTagWireType(tag) !=
829       WireTypeForFieldType(field->type())) {
830     if (field->is_packable() && WireFormatLite::GetTagWireType(tag) ==
831                                     WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
832       switch (field->type()) {
833 #define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD)                   \
834   case FieldDescriptor::TYPE_##TYPE: {                                      \
835     ptr = internal::Packed##CPPTYPE_METHOD##Parser(                         \
836         reflection->MutableRepeatedFieldInternal<CPPTYPE>(msg, field), ptr, \
837         ctx);                                                               \
838     return ptr;                                                             \
839   }
840 
841         HANDLE_PACKED_TYPE(INT32, int32, Int32)
842         HANDLE_PACKED_TYPE(INT64, int64, Int64)
843         HANDLE_PACKED_TYPE(SINT32, int32, SInt32)
844         HANDLE_PACKED_TYPE(SINT64, int64, SInt64)
845         HANDLE_PACKED_TYPE(UINT32, uint32, UInt32)
846         HANDLE_PACKED_TYPE(UINT64, uint64, UInt64)
847 
848         HANDLE_PACKED_TYPE(FIXED32, uint32, Fixed32)
849         HANDLE_PACKED_TYPE(FIXED64, uint64, Fixed64)
850         HANDLE_PACKED_TYPE(SFIXED32, int32, SFixed32)
851         HANDLE_PACKED_TYPE(SFIXED64, int64, SFixed64)
852 
853         HANDLE_PACKED_TYPE(FLOAT, float, Float)
854         HANDLE_PACKED_TYPE(DOUBLE, double, Double)
855 
856         HANDLE_PACKED_TYPE(BOOL, bool, Bool)
857 #undef HANDLE_PACKED_TYPE
858 
859         case FieldDescriptor::TYPE_ENUM: {
860           auto rep_enum =
861               reflection->MutableRepeatedFieldInternal<int>(msg, field);
862           bool open_enum = false;
863           if (field->file()->syntax() == FileDescriptor::SYNTAX_PROTO3 ||
864               open_enum) {
865             ptr = internal::PackedEnumParser(rep_enum, ptr, ctx);
866           } else {
867             return ctx->ReadPackedVarint(
868                 ptr, [rep_enum, field, reflection, msg](uint64 val) {
869                   if (field->enum_type()->FindValueByNumber(val) != nullptr) {
870                     rep_enum->Add(val);
871                   } else {
872                     WriteVarint(field->number(), val,
873                                 reflection->MutableUnknownFields(msg));
874                   }
875                 });
876           }
877           return ptr;
878         }
879 
880         case FieldDescriptor::TYPE_STRING:
881         case FieldDescriptor::TYPE_GROUP:
882         case FieldDescriptor::TYPE_MESSAGE:
883         case FieldDescriptor::TYPE_BYTES:
884           GOOGLE_LOG(FATAL) << "Can't reach";
885           return nullptr;
886       }
887     } else {
888       // mismatched wiretype;
889       return internal::UnknownFieldParse(
890           tag, reflection->MutableUnknownFields(msg), ptr, ctx);
891     }
892   }
893 
894   // Non-packed value
895   bool utf8_check = false;
896   bool strict_utf8_check = false;
897   switch (field->type()) {
898 #define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD)        \
899   case FieldDescriptor::TYPE_##TYPE: {                    \
900     CPPTYPE value;                                        \
901     ptr = VarintParse(ptr, &value);                       \
902     if (ptr == nullptr) return nullptr;                   \
903     if (field->is_repeated()) {                           \
904       reflection->Add##CPPTYPE_METHOD(msg, field, value); \
905     } else {                                              \
906       reflection->Set##CPPTYPE_METHOD(msg, field, value); \
907     }                                                     \
908     return ptr;                                           \
909   }
910 
911     HANDLE_TYPE(BOOL, uint64, Bool)
912     HANDLE_TYPE(INT32, uint32, Int32)
913     HANDLE_TYPE(INT64, uint64, Int64)
914     HANDLE_TYPE(UINT32, uint32, UInt32)
915     HANDLE_TYPE(UINT64, uint64, UInt64)
916 
917     case FieldDescriptor::TYPE_SINT32: {
918       int32 value = ReadVarintZigZag32(&ptr);
919       if (ptr == nullptr) return nullptr;
920       if (field->is_repeated()) {
921         reflection->AddInt32(msg, field, value);
922       } else {
923         reflection->SetInt32(msg, field, value);
924       }
925       return ptr;
926     }
927     case FieldDescriptor::TYPE_SINT64: {
928       int64 value = ReadVarintZigZag64(&ptr);
929       if (ptr == nullptr) return nullptr;
930       if (field->is_repeated()) {
931         reflection->AddInt64(msg, field, value);
932       } else {
933         reflection->SetInt64(msg, field, value);
934       }
935       return ptr;
936     }
937 #undef HANDLE_TYPE
938 #define HANDLE_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD)        \
939   case FieldDescriptor::TYPE_##TYPE: {                    \
940     CPPTYPE value;                                        \
941     value = UnalignedLoad<CPPTYPE>(ptr);                  \
942     ptr += sizeof(CPPTYPE);                               \
943     if (field->is_repeated()) {                           \
944       reflection->Add##CPPTYPE_METHOD(msg, field, value); \
945     } else {                                              \
946       reflection->Set##CPPTYPE_METHOD(msg, field, value); \
947     }                                                     \
948     return ptr;                                           \
949   }
950 
951       HANDLE_TYPE(FIXED32, uint32, UInt32)
952       HANDLE_TYPE(FIXED64, uint64, UInt64)
953       HANDLE_TYPE(SFIXED32, int32, Int32)
954       HANDLE_TYPE(SFIXED64, int64, Int64)
955 
956       HANDLE_TYPE(FLOAT, float, Float)
957       HANDLE_TYPE(DOUBLE, double, Double)
958 
959 #undef HANDLE_TYPE
960 
961     case FieldDescriptor::TYPE_ENUM: {
962       uint32 value;
963       ptr = VarintParse(ptr, &value);
964       if (ptr == nullptr) return nullptr;
965       if (field->is_repeated()) {
966         reflection->AddEnumValue(msg, field, value);
967       } else {
968         reflection->SetEnumValue(msg, field, value);
969       }
970       return ptr;
971     }
972 
973     // Handle strings separately so that we can optimize the ctype=CORD case.
974     case FieldDescriptor::TYPE_STRING:
975       utf8_check = true;
976       strict_utf8_check = StrictUtf8Check(field);
977       PROTOBUF_FALLTHROUGH_INTENDED;
978     case FieldDescriptor::TYPE_BYTES: {
979       int size = ReadSize(&ptr);
980       if (ptr == nullptr) return nullptr;
981       std::string value;
982       ptr = ctx->ReadString(ptr, size, &value);
983       if (ptr == nullptr) return nullptr;
984       if (utf8_check) {
985         if (strict_utf8_check) {
986           if (!WireFormatLite::VerifyUtf8String(value.data(), value.length(),
987                                                 WireFormatLite::PARSE,
988                                                 field->full_name().c_str())) {
989             return nullptr;
990           }
991         } else {
992           VerifyUTF8StringNamedField(value.data(), value.length(), PARSE,
993                                      field->full_name().c_str());
994         }
995       }
996       if (field->is_repeated()) {
997         reflection->AddString(msg, field, value);
998       } else {
999         reflection->SetString(msg, field, value);
1000       }
1001       return ptr;
1002     }
1003 
1004     case FieldDescriptor::TYPE_GROUP: {
1005       Message* sub_message;
1006       if (field->is_repeated()) {
1007         sub_message = reflection->AddMessage(msg, field, ctx->data().factory);
1008       } else {
1009         sub_message =
1010             reflection->MutableMessage(msg, field, ctx->data().factory);
1011       }
1012 
1013       return ctx->ParseGroup(sub_message, ptr, tag);
1014     }
1015 
1016     case FieldDescriptor::TYPE_MESSAGE: {
1017       Message* sub_message;
1018       if (field->is_repeated()) {
1019         sub_message = reflection->AddMessage(msg, field, ctx->data().factory);
1020       } else {
1021         sub_message =
1022             reflection->MutableMessage(msg, field, ctx->data().factory);
1023       }
1024       return ctx->ParseMessage(sub_message, ptr);
1025     }
1026   }
1027 
1028   // GCC 8 complains about control reaching end of non-void function here.
1029   // Let's keep it happy by returning a nullptr.
1030   return nullptr;
1031 }
1032 
1033 // ===================================================================
1034 
_InternalSerialize(const Message & message,uint8 * target,io::EpsCopyOutputStream * stream)1035 uint8* WireFormat::_InternalSerialize(const Message& message, uint8* target,
1036                                       io::EpsCopyOutputStream* stream) {
1037   const Descriptor* descriptor = message.GetDescriptor();
1038   const Reflection* message_reflection = message.GetReflection();
1039 
1040   std::vector<const FieldDescriptor*> fields;
1041 
1042   // Fields of map entry should always be serialized.
1043   if (descriptor->options().map_entry()) {
1044     for (int i = 0; i < descriptor->field_count(); i++) {
1045       fields.push_back(descriptor->field(i));
1046     }
1047   } else {
1048     message_reflection->ListFields(message, &fields);
1049   }
1050 
1051   for (auto field : fields) {
1052     target = InternalSerializeField(field, message, target, stream);
1053   }
1054 
1055   if (descriptor->options().message_set_wire_format()) {
1056     return InternalSerializeUnknownMessageSetItemsToArray(
1057         message_reflection->GetUnknownFields(message), target, stream);
1058   } else {
1059     return InternalSerializeUnknownFieldsToArray(
1060         message_reflection->GetUnknownFields(message), target, stream);
1061   }
1062 }
1063 
SerializeMapKeyWithCachedSizes(const FieldDescriptor * field,const MapKey & value,uint8 * target,io::EpsCopyOutputStream * stream)1064 static uint8* SerializeMapKeyWithCachedSizes(const FieldDescriptor* field,
1065                                              const MapKey& value, uint8* target,
1066                                              io::EpsCopyOutputStream* stream) {
1067   target = stream->EnsureSpace(target);
1068   switch (field->type()) {
1069     case FieldDescriptor::TYPE_DOUBLE:
1070     case FieldDescriptor::TYPE_FLOAT:
1071     case FieldDescriptor::TYPE_GROUP:
1072     case FieldDescriptor::TYPE_MESSAGE:
1073     case FieldDescriptor::TYPE_BYTES:
1074     case FieldDescriptor::TYPE_ENUM:
1075       GOOGLE_LOG(FATAL) << "Unsupported";
1076       break;
1077 #define CASE_TYPE(FieldType, CamelFieldType, CamelCppType)   \
1078   case FieldDescriptor::TYPE_##FieldType:                    \
1079     target = WireFormatLite::Write##CamelFieldType##ToArray( \
1080         1, value.Get##CamelCppType##Value(), target);        \
1081     break;
1082       CASE_TYPE(INT64, Int64, Int64)
1083       CASE_TYPE(UINT64, UInt64, UInt64)
1084       CASE_TYPE(INT32, Int32, Int32)
1085       CASE_TYPE(FIXED64, Fixed64, UInt64)
1086       CASE_TYPE(FIXED32, Fixed32, UInt32)
1087       CASE_TYPE(BOOL, Bool, Bool)
1088       CASE_TYPE(UINT32, UInt32, UInt32)
1089       CASE_TYPE(SFIXED32, SFixed32, Int32)
1090       CASE_TYPE(SFIXED64, SFixed64, Int64)
1091       CASE_TYPE(SINT32, SInt32, Int32)
1092       CASE_TYPE(SINT64, SInt64, Int64)
1093 #undef CASE_TYPE
1094     case FieldDescriptor::TYPE_STRING:
1095       target = stream->WriteString(1, value.GetStringValue(), target);
1096       break;
1097   }
1098   return target;
1099 }
1100 
SerializeMapValueRefWithCachedSizes(const FieldDescriptor * field,const MapValueRef & value,uint8 * target,io::EpsCopyOutputStream * stream)1101 static uint8* SerializeMapValueRefWithCachedSizes(
1102     const FieldDescriptor* field, const MapValueRef& value, uint8* target,
1103     io::EpsCopyOutputStream* stream) {
1104   target = stream->EnsureSpace(target);
1105   switch (field->type()) {
1106 #define CASE_TYPE(FieldType, CamelFieldType, CamelCppType)   \
1107   case FieldDescriptor::TYPE_##FieldType:                    \
1108     target = WireFormatLite::Write##CamelFieldType##ToArray( \
1109         2, value.Get##CamelCppType##Value(), target);        \
1110     break;
1111     CASE_TYPE(INT64, Int64, Int64)
1112     CASE_TYPE(UINT64, UInt64, UInt64)
1113     CASE_TYPE(INT32, Int32, Int32)
1114     CASE_TYPE(FIXED64, Fixed64, UInt64)
1115     CASE_TYPE(FIXED32, Fixed32, UInt32)
1116     CASE_TYPE(BOOL, Bool, Bool)
1117     CASE_TYPE(UINT32, UInt32, UInt32)
1118     CASE_TYPE(SFIXED32, SFixed32, Int32)
1119     CASE_TYPE(SFIXED64, SFixed64, Int64)
1120     CASE_TYPE(SINT32, SInt32, Int32)
1121     CASE_TYPE(SINT64, SInt64, Int64)
1122     CASE_TYPE(ENUM, Enum, Enum)
1123     CASE_TYPE(DOUBLE, Double, Double)
1124     CASE_TYPE(FLOAT, Float, Float)
1125 #undef CASE_TYPE
1126     case FieldDescriptor::TYPE_STRING:
1127     case FieldDescriptor::TYPE_BYTES:
1128       target = stream->WriteString(2, value.GetStringValue(), target);
1129       break;
1130     case FieldDescriptor::TYPE_MESSAGE:
1131       target = WireFormatLite::InternalWriteMessage(2, value.GetMessageValue(),
1132                                                     target, stream);
1133       break;
1134     case FieldDescriptor::TYPE_GROUP:
1135       target = WireFormatLite::InternalWriteGroup(2, value.GetMessageValue(),
1136                                                   target, stream);
1137       break;
1138   }
1139   return target;
1140 }
1141 
1142 class MapKeySorter {
1143  public:
SortKey(const Message & message,const Reflection * reflection,const FieldDescriptor * field)1144   static std::vector<MapKey> SortKey(const Message& message,
1145                                      const Reflection* reflection,
1146                                      const FieldDescriptor* field) {
1147     std::vector<MapKey> sorted_key_list;
1148     for (MapIterator it =
1149              reflection->MapBegin(const_cast<Message*>(&message), field);
1150          it != reflection->MapEnd(const_cast<Message*>(&message), field);
1151          ++it) {
1152       sorted_key_list.push_back(it.GetKey());
1153     }
1154     MapKeyComparator comparator;
1155     std::sort(sorted_key_list.begin(), sorted_key_list.end(), comparator);
1156     return sorted_key_list;
1157   }
1158 
1159  private:
1160   class MapKeyComparator {
1161    public:
operator ()(const MapKey & a,const MapKey & b) const1162     bool operator()(const MapKey& a, const MapKey& b) const {
1163       GOOGLE_DCHECK(a.type() == b.type());
1164       switch (a.type()) {
1165 #define CASE_TYPE(CppType, CamelCppType)                                \
1166   case FieldDescriptor::CPPTYPE_##CppType: {                            \
1167     return a.Get##CamelCppType##Value() < b.Get##CamelCppType##Value(); \
1168   }
1169         CASE_TYPE(STRING, String)
1170         CASE_TYPE(INT64, Int64)
1171         CASE_TYPE(INT32, Int32)
1172         CASE_TYPE(UINT64, UInt64)
1173         CASE_TYPE(UINT32, UInt32)
1174         CASE_TYPE(BOOL, Bool)
1175 #undef CASE_TYPE
1176 
1177         default:
1178           GOOGLE_LOG(DFATAL) << "Invalid key for map field.";
1179           return true;
1180       }
1181     }
1182   };
1183 };
1184 
InternalSerializeMapEntry(const FieldDescriptor * field,const MapKey & key,const MapValueRef & value,uint8 * target,io::EpsCopyOutputStream * stream)1185 static uint8* InternalSerializeMapEntry(const FieldDescriptor* field,
1186                                         const MapKey& key,
1187                                         const MapValueRef& value, uint8* target,
1188                                         io::EpsCopyOutputStream* stream) {
1189   const FieldDescriptor* key_field = field->message_type()->field(0);
1190   const FieldDescriptor* value_field = field->message_type()->field(1);
1191 
1192   size_t size = kMapEntryTagByteSize;
1193   size += MapKeyDataOnlyByteSize(key_field, key);
1194   size += MapValueRefDataOnlyByteSize(value_field, value);
1195   target = stream->EnsureSpace(target);
1196   target = WireFormatLite::WriteTagToArray(
1197       field->number(), WireFormatLite::WIRETYPE_LENGTH_DELIMITED, target);
1198   target = io::CodedOutputStream::WriteVarint32ToArray(size, target);
1199   target = SerializeMapKeyWithCachedSizes(key_field, key, target, stream);
1200   target =
1201       SerializeMapValueRefWithCachedSizes(value_field, value, target, stream);
1202   return target;
1203 }
1204 
InternalSerializeField(const FieldDescriptor * field,const Message & message,uint8 * target,io::EpsCopyOutputStream * stream)1205 uint8* WireFormat::InternalSerializeField(const FieldDescriptor* field,
1206                                           const Message& message, uint8* 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           MapValueRef map_value;
1241           message_reflection->InsertOrLookupMapValue(
1242               const_cast<Message*>(&message), field, *it, &map_value);
1243           target =
1244               InternalSerializeMapEntry(field, *it, map_value, target, stream);
1245         }
1246       } else {
1247         for (MapIterator it = message_reflection->MapBegin(
1248                  const_cast<Message*>(&message), field);
1249              it !=
1250              message_reflection->MapEnd(const_cast<Message*>(&message), field);
1251              ++it) {
1252           target = InternalSerializeMapEntry(field, it.GetKey(),
1253                                              it.GetValueRef(), target, stream);
1254         }
1255       }
1256 
1257       return target;
1258     }
1259   }
1260   int count = 0;
1261 
1262   if (field->is_repeated()) {
1263     count = message_reflection->FieldSize(message, field);
1264   } else if (field->containing_type()->options().map_entry()) {
1265     // Map entry fields always need to be serialized.
1266     count = 1;
1267   } else if (message_reflection->HasField(message, field)) {
1268     count = 1;
1269   }
1270 
1271   // map_entries is for maps that'll be deterministically serialized.
1272   std::vector<const Message*> map_entries;
1273   if (count > 1 && field->is_map() && stream->IsSerializationDeterministic()) {
1274     map_entries =
1275         DynamicMapSorter::Sort(message, count, message_reflection, field);
1276   }
1277 
1278   if (field->is_packed()) {
1279     if (count == 0) return target;
1280     target = stream->EnsureSpace(target);
1281     switch (field->type()) {
1282 #define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD)      \
1283   case FieldDescriptor::TYPE_##TYPE: {                                         \
1284     auto r =                                                                   \
1285         message_reflection->GetRepeatedFieldInternal<CPPTYPE>(message, field); \
1286     target = stream->Write##TYPE_METHOD##Packed(                               \
1287         field->number(), r, FieldDataOnlyByteSize(field, message), target);    \
1288     break;                                                                     \
1289   }
1290 
1291       HANDLE_PRIMITIVE_TYPE(INT32, int32, Int32, Int32)
1292       HANDLE_PRIMITIVE_TYPE(INT64, int64, Int64, Int64)
1293       HANDLE_PRIMITIVE_TYPE(SINT32, int32, SInt32, Int32)
1294       HANDLE_PRIMITIVE_TYPE(SINT64, int64, SInt64, Int64)
1295       HANDLE_PRIMITIVE_TYPE(UINT32, uint32, UInt32, UInt32)
1296       HANDLE_PRIMITIVE_TYPE(UINT64, uint64, UInt64, UInt64)
1297       HANDLE_PRIMITIVE_TYPE(ENUM, int, Enum, Enum)
1298 
1299 #undef HANDLE_PRIMITIVE_TYPE
1300 #define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD)      \
1301   case FieldDescriptor::TYPE_##TYPE: {                                         \
1302     auto r =                                                                   \
1303         message_reflection->GetRepeatedFieldInternal<CPPTYPE>(message, field); \
1304     target = stream->WriteFixedPacked(field->number(), r, target);             \
1305     break;                                                                     \
1306   }
1307 
1308       HANDLE_PRIMITIVE_TYPE(FIXED32, uint32, Fixed32, UInt32)
1309       HANDLE_PRIMITIVE_TYPE(FIXED64, uint64, Fixed64, UInt64)
1310       HANDLE_PRIMITIVE_TYPE(SFIXED32, int32, SFixed32, Int32)
1311       HANDLE_PRIMITIVE_TYPE(SFIXED64, int64, SFixed64, Int64)
1312 
1313       HANDLE_PRIMITIVE_TYPE(FLOAT, float, Float, Float)
1314       HANDLE_PRIMITIVE_TYPE(DOUBLE, double, Double, Double)
1315 
1316       HANDLE_PRIMITIVE_TYPE(BOOL, bool, Bool, Bool)
1317 #undef HANDLE_PRIMITIVE_TYPE
1318       default:
1319         GOOGLE_LOG(FATAL) << "Invalid descriptor";
1320     }
1321     return target;
1322   }
1323 
1324   for (int j = 0; j < count; j++) {
1325     target = stream->EnsureSpace(target);
1326     switch (field->type()) {
1327 #define HANDLE_PRIMITIVE_TYPE(TYPE, CPPTYPE, TYPE_METHOD, CPPTYPE_METHOD)     \
1328   case FieldDescriptor::TYPE_##TYPE: {                                        \
1329     const CPPTYPE value =                                                     \
1330         field->is_repeated()                                                  \
1331             ? message_reflection->GetRepeated##CPPTYPE_METHOD(message, field, \
1332                                                               j)              \
1333             : message_reflection->Get##CPPTYPE_METHOD(message, field);        \
1334     target = WireFormatLite::Write##TYPE_METHOD##ToArray(field->number(),     \
1335                                                          value, target);      \
1336     break;                                                                    \
1337   }
1338 
1339       HANDLE_PRIMITIVE_TYPE(INT32, int32, Int32, Int32)
1340       HANDLE_PRIMITIVE_TYPE(INT64, int64, Int64, Int64)
1341       HANDLE_PRIMITIVE_TYPE(SINT32, int32, SInt32, Int32)
1342       HANDLE_PRIMITIVE_TYPE(SINT64, int64, SInt64, Int64)
1343       HANDLE_PRIMITIVE_TYPE(UINT32, uint32, UInt32, UInt32)
1344       HANDLE_PRIMITIVE_TYPE(UINT64, uint64, UInt64, UInt64)
1345 
1346       HANDLE_PRIMITIVE_TYPE(FIXED32, uint32, Fixed32, UInt32)
1347       HANDLE_PRIMITIVE_TYPE(FIXED64, uint64, Fixed64, UInt64)
1348       HANDLE_PRIMITIVE_TYPE(SFIXED32, int32, SFixed32, Int32)
1349       HANDLE_PRIMITIVE_TYPE(SFIXED64, int64, SFixed64, Int64)
1350 
1351       HANDLE_PRIMITIVE_TYPE(FLOAT, float, Float, Float)
1352       HANDLE_PRIMITIVE_TYPE(DOUBLE, double, Double, Double)
1353 
1354       HANDLE_PRIMITIVE_TYPE(BOOL, bool, Bool, Bool)
1355 #undef HANDLE_PRIMITIVE_TYPE
1356 
1357 #define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD)                         \
1358   case FieldDescriptor::TYPE_##TYPE:                                           \
1359     target = WireFormatLite::InternalWrite##TYPE_METHOD(                       \
1360         field->number(),                                                       \
1361         field->is_repeated()                                                   \
1362             ? (map_entries.empty()                                             \
1363                    ? message_reflection->GetRepeated##CPPTYPE_METHOD(message,  \
1364                                                                      field, j) \
1365                    : *map_entries[j])                                          \
1366             : message_reflection->Get##CPPTYPE_METHOD(message, field),         \
1367         target, stream);                                                       \
1368     break;
1369 
1370       HANDLE_TYPE(GROUP, Group, Message)
1371       HANDLE_TYPE(MESSAGE, Message, Message)
1372 #undef HANDLE_TYPE
1373 
1374       case FieldDescriptor::TYPE_ENUM: {
1375         const EnumValueDescriptor* value =
1376             field->is_repeated()
1377                 ? message_reflection->GetRepeatedEnum(message, field, j)
1378                 : message_reflection->GetEnum(message, field);
1379         target = WireFormatLite::WriteEnumToArray(field->number(),
1380                                                   value->number(), target);
1381         break;
1382       }
1383 
1384       // Handle strings separately so that we can get string references
1385       // instead of copying.
1386       case FieldDescriptor::TYPE_STRING: {
1387         bool strict_utf8_check = StrictUtf8Check(field);
1388         std::string scratch;
1389         const std::string& value =
1390             field->is_repeated()
1391                 ? message_reflection->GetRepeatedStringReference(message, field,
1392                                                                  j, &scratch)
1393                 : message_reflection->GetStringReference(message, field,
1394                                                          &scratch);
1395         if (strict_utf8_check) {
1396           WireFormatLite::VerifyUtf8String(value.data(), value.length(),
1397                                            WireFormatLite::SERIALIZE,
1398                                            field->full_name().c_str());
1399         } else {
1400           VerifyUTF8StringNamedField(value.data(), value.length(), SERIALIZE,
1401                                      field->full_name().c_str());
1402         }
1403         target = stream->WriteString(field->number(), value, target);
1404         break;
1405       }
1406 
1407       case FieldDescriptor::TYPE_BYTES: {
1408         std::string scratch;
1409         const std::string& value =
1410             field->is_repeated()
1411                 ? message_reflection->GetRepeatedStringReference(message, field,
1412                                                                  j, &scratch)
1413                 : message_reflection->GetStringReference(message, field,
1414                                                          &scratch);
1415         target = stream->WriteString(field->number(), value, target);
1416         break;
1417       }
1418     }
1419   }
1420   return target;
1421 }
1422 
InternalSerializeMessageSetItem(const FieldDescriptor * field,const Message & message,uint8 * target,io::EpsCopyOutputStream * stream)1423 uint8* WireFormat::InternalSerializeMessageSetItem(
1424     const FieldDescriptor* field, const Message& message, uint8* target,
1425     io::EpsCopyOutputStream* stream) {
1426   const Reflection* message_reflection = message.GetReflection();
1427 
1428   target = stream->EnsureSpace(target);
1429   // Start group.
1430   target = io::CodedOutputStream::WriteTagToArray(
1431       WireFormatLite::kMessageSetItemStartTag, target);
1432   // Write type ID.
1433   target = WireFormatLite::WriteUInt32ToArray(
1434       WireFormatLite::kMessageSetTypeIdNumber, field->number(), target);
1435   // Write message.
1436   target = WireFormatLite::InternalWriteMessage(
1437       WireFormatLite::kMessageSetMessageNumber,
1438       message_reflection->GetMessage(message, field), target, stream);
1439   // End group.
1440   target = stream->EnsureSpace(target);
1441   target = io::CodedOutputStream::WriteTagToArray(
1442       WireFormatLite::kMessageSetItemEndTag, target);
1443   return target;
1444 }
1445 
1446 // ===================================================================
1447 
ByteSize(const Message & message)1448 size_t WireFormat::ByteSize(const Message& message) {
1449   const Descriptor* descriptor = message.GetDescriptor();
1450   const Reflection* message_reflection = message.GetReflection();
1451 
1452   size_t our_size = 0;
1453 
1454   std::vector<const FieldDescriptor*> fields;
1455 
1456   // Fields of map entry should always be serialized.
1457   if (descriptor->options().map_entry()) {
1458     for (int i = 0; i < descriptor->field_count(); i++) {
1459       fields.push_back(descriptor->field(i));
1460     }
1461   } else {
1462     message_reflection->ListFields(message, &fields);
1463   }
1464 
1465   for (int i = 0; i < fields.size(); i++) {
1466     our_size += FieldByteSize(fields[i], message);
1467   }
1468 
1469   if (descriptor->options().message_set_wire_format()) {
1470     our_size += ComputeUnknownMessageSetItemsSize(
1471         message_reflection->GetUnknownFields(message));
1472   } else {
1473     our_size +=
1474         ComputeUnknownFieldsSize(message_reflection->GetUnknownFields(message));
1475   }
1476 
1477   return our_size;
1478 }
1479 
FieldByteSize(const FieldDescriptor * field,const Message & message)1480 size_t WireFormat::FieldByteSize(const FieldDescriptor* field,
1481                                  const Message& message) {
1482   const Reflection* message_reflection = message.GetReflection();
1483 
1484   if (field->is_extension() &&
1485       field->containing_type()->options().message_set_wire_format() &&
1486       field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE &&
1487       !field->is_repeated()) {
1488     return MessageSetItemByteSize(field, message);
1489   }
1490 
1491   size_t count = 0;
1492   if (field->is_repeated()) {
1493     if (field->is_map()) {
1494       const MapFieldBase* map_field =
1495           message_reflection->GetMapData(message, field);
1496       if (map_field->IsMapValid()) {
1497         count = FromIntSize(map_field->size());
1498       } else {
1499         count = FromIntSize(message_reflection->FieldSize(message, field));
1500       }
1501     } else {
1502       count = FromIntSize(message_reflection->FieldSize(message, field));
1503     }
1504   } else if (field->containing_type()->options().map_entry()) {
1505     // Map entry fields always need to be serialized.
1506     count = 1;
1507   } else if (message_reflection->HasField(message, field)) {
1508     count = 1;
1509   }
1510 
1511   const size_t data_size = FieldDataOnlyByteSize(field, message);
1512   size_t our_size = data_size;
1513   if (field->is_packed()) {
1514     if (data_size > 0) {
1515       // Packed fields get serialized like a string, not their native type.
1516       // Technically this doesn't really matter; the size only changes if it's
1517       // a GROUP
1518       our_size += TagSize(field->number(), FieldDescriptor::TYPE_STRING);
1519       our_size += io::CodedOutputStream::VarintSize32(data_size);
1520     }
1521   } else {
1522     our_size += count * TagSize(field->number(), field->type());
1523   }
1524   return our_size;
1525 }
1526 
MapKeyDataOnlyByteSize(const FieldDescriptor * field,const MapKey & value)1527 static size_t MapKeyDataOnlyByteSize(const FieldDescriptor* field,
1528                                      const MapKey& value) {
1529   GOOGLE_DCHECK_EQ(FieldDescriptor::TypeToCppType(field->type()), value.type());
1530   switch (field->type()) {
1531     case FieldDescriptor::TYPE_DOUBLE:
1532     case FieldDescriptor::TYPE_FLOAT:
1533     case FieldDescriptor::TYPE_GROUP:
1534     case FieldDescriptor::TYPE_MESSAGE:
1535     case FieldDescriptor::TYPE_BYTES:
1536     case FieldDescriptor::TYPE_ENUM:
1537       GOOGLE_LOG(FATAL) << "Unsupported";
1538       return 0;
1539 #define CASE_TYPE(FieldType, CamelFieldType, CamelCppType) \
1540   case FieldDescriptor::TYPE_##FieldType:                  \
1541     return WireFormatLite::CamelFieldType##Size(           \
1542         value.Get##CamelCppType##Value());
1543 
1544 #define FIXED_CASE_TYPE(FieldType, CamelFieldType) \
1545   case FieldDescriptor::TYPE_##FieldType:          \
1546     return WireFormatLite::k##CamelFieldType##Size;
1547 
1548       CASE_TYPE(INT32, Int32, Int32);
1549       CASE_TYPE(INT64, Int64, Int64);
1550       CASE_TYPE(UINT32, UInt32, UInt32);
1551       CASE_TYPE(UINT64, UInt64, UInt64);
1552       CASE_TYPE(SINT32, SInt32, Int32);
1553       CASE_TYPE(SINT64, SInt64, Int64);
1554       CASE_TYPE(STRING, String, String);
1555       FIXED_CASE_TYPE(FIXED32, Fixed32);
1556       FIXED_CASE_TYPE(FIXED64, Fixed64);
1557       FIXED_CASE_TYPE(SFIXED32, SFixed32);
1558       FIXED_CASE_TYPE(SFIXED64, SFixed64);
1559       FIXED_CASE_TYPE(BOOL, Bool);
1560 
1561 #undef CASE_TYPE
1562 #undef FIXED_CASE_TYPE
1563   }
1564   GOOGLE_LOG(FATAL) << "Cannot get here";
1565   return 0;
1566 }
1567 
MapValueRefDataOnlyByteSize(const FieldDescriptor * field,const MapValueRef & value)1568 static size_t MapValueRefDataOnlyByteSize(const FieldDescriptor* field,
1569                                           const MapValueRef& value) {
1570   switch (field->type()) {
1571     case FieldDescriptor::TYPE_GROUP:
1572       GOOGLE_LOG(FATAL) << "Unsupported";
1573       return 0;
1574 #define CASE_TYPE(FieldType, CamelFieldType, CamelCppType) \
1575   case FieldDescriptor::TYPE_##FieldType:                  \
1576     return WireFormatLite::CamelFieldType##Size(           \
1577         value.Get##CamelCppType##Value());
1578 
1579 #define FIXED_CASE_TYPE(FieldType, CamelFieldType) \
1580   case FieldDescriptor::TYPE_##FieldType:          \
1581     return WireFormatLite::k##CamelFieldType##Size;
1582 
1583       CASE_TYPE(INT32, Int32, Int32);
1584       CASE_TYPE(INT64, Int64, Int64);
1585       CASE_TYPE(UINT32, UInt32, UInt32);
1586       CASE_TYPE(UINT64, UInt64, UInt64);
1587       CASE_TYPE(SINT32, SInt32, Int32);
1588       CASE_TYPE(SINT64, SInt64, Int64);
1589       CASE_TYPE(STRING, String, String);
1590       CASE_TYPE(BYTES, Bytes, String);
1591       CASE_TYPE(ENUM, Enum, Enum);
1592       CASE_TYPE(MESSAGE, Message, Message);
1593       FIXED_CASE_TYPE(FIXED32, Fixed32);
1594       FIXED_CASE_TYPE(FIXED64, Fixed64);
1595       FIXED_CASE_TYPE(SFIXED32, SFixed32);
1596       FIXED_CASE_TYPE(SFIXED64, SFixed64);
1597       FIXED_CASE_TYPE(DOUBLE, Double);
1598       FIXED_CASE_TYPE(FLOAT, Float);
1599       FIXED_CASE_TYPE(BOOL, Bool);
1600 
1601 #undef CASE_TYPE
1602 #undef FIXED_CASE_TYPE
1603   }
1604   GOOGLE_LOG(FATAL) << "Cannot get here";
1605   return 0;
1606 }
1607 
FieldDataOnlyByteSize(const FieldDescriptor * field,const Message & message)1608 size_t WireFormat::FieldDataOnlyByteSize(const FieldDescriptor* field,
1609                                          const Message& message) {
1610   const Reflection* message_reflection = message.GetReflection();
1611 
1612   size_t data_size = 0;
1613 
1614   if (field->is_map()) {
1615     const MapFieldBase* map_field =
1616         message_reflection->GetMapData(message, field);
1617     if (map_field->IsMapValid()) {
1618       MapIterator iter(const_cast<Message*>(&message), field);
1619       MapIterator end(const_cast<Message*>(&message), field);
1620       const FieldDescriptor* key_field = field->message_type()->field(0);
1621       const FieldDescriptor* value_field = field->message_type()->field(1);
1622       for (map_field->MapBegin(&iter), map_field->MapEnd(&end); iter != end;
1623            ++iter) {
1624         size_t size = kMapEntryTagByteSize;
1625         size += MapKeyDataOnlyByteSize(key_field, iter.GetKey());
1626         size += MapValueRefDataOnlyByteSize(value_field, iter.GetValueRef());
1627         data_size += WireFormatLite::LengthDelimitedSize(size);
1628       }
1629       return data_size;
1630     }
1631   }
1632 
1633   size_t count = 0;
1634   if (field->is_repeated()) {
1635     count =
1636         internal::FromIntSize(message_reflection->FieldSize(message, field));
1637   } else if (field->containing_type()->options().map_entry()) {
1638     // Map entry fields always need to be serialized.
1639     count = 1;
1640   } else if (message_reflection->HasField(message, field)) {
1641     count = 1;
1642   }
1643 
1644   switch (field->type()) {
1645 #define HANDLE_TYPE(TYPE, TYPE_METHOD, CPPTYPE_METHOD)                      \
1646   case FieldDescriptor::TYPE_##TYPE:                                        \
1647     if (field->is_repeated()) {                                             \
1648       for (int j = 0; j < count; j++) {                                     \
1649         data_size += WireFormatLite::TYPE_METHOD##Size(                     \
1650             message_reflection->GetRepeated##CPPTYPE_METHOD(message, field, \
1651                                                             j));            \
1652       }                                                                     \
1653     } else {                                                                \
1654       data_size += WireFormatLite::TYPE_METHOD##Size(                       \
1655           message_reflection->Get##CPPTYPE_METHOD(message, field));         \
1656     }                                                                       \
1657     break;
1658 
1659 #define HANDLE_FIXED_TYPE(TYPE, TYPE_METHOD)                   \
1660   case FieldDescriptor::TYPE_##TYPE:                           \
1661     data_size += count * WireFormatLite::k##TYPE_METHOD##Size; \
1662     break;
1663 
1664     HANDLE_TYPE(INT32, Int32, Int32)
1665     HANDLE_TYPE(INT64, Int64, Int64)
1666     HANDLE_TYPE(SINT32, SInt32, Int32)
1667     HANDLE_TYPE(SINT64, SInt64, Int64)
1668     HANDLE_TYPE(UINT32, UInt32, UInt32)
1669     HANDLE_TYPE(UINT64, UInt64, UInt64)
1670 
1671     HANDLE_FIXED_TYPE(FIXED32, Fixed32)
1672     HANDLE_FIXED_TYPE(FIXED64, Fixed64)
1673     HANDLE_FIXED_TYPE(SFIXED32, SFixed32)
1674     HANDLE_FIXED_TYPE(SFIXED64, SFixed64)
1675 
1676     HANDLE_FIXED_TYPE(FLOAT, Float)
1677     HANDLE_FIXED_TYPE(DOUBLE, Double)
1678 
1679     HANDLE_FIXED_TYPE(BOOL, Bool)
1680 
1681     HANDLE_TYPE(GROUP, Group, Message)
1682     HANDLE_TYPE(MESSAGE, Message, Message)
1683 #undef HANDLE_TYPE
1684 #undef HANDLE_FIXED_TYPE
1685 
1686     case FieldDescriptor::TYPE_ENUM: {
1687       if (field->is_repeated()) {
1688         for (int j = 0; j < count; j++) {
1689           data_size += WireFormatLite::EnumSize(
1690               message_reflection->GetRepeatedEnum(message, field, j)->number());
1691         }
1692       } else {
1693         data_size += WireFormatLite::EnumSize(
1694             message_reflection->GetEnum(message, field)->number());
1695       }
1696       break;
1697     }
1698 
1699     // Handle strings separately so that we can get string references
1700     // instead of copying.
1701     case FieldDescriptor::TYPE_STRING:
1702     case FieldDescriptor::TYPE_BYTES: {
1703       for (int j = 0; j < count; j++) {
1704         std::string scratch;
1705         const std::string& value =
1706             field->is_repeated()
1707                 ? message_reflection->GetRepeatedStringReference(message, field,
1708                                                                  j, &scratch)
1709                 : message_reflection->GetStringReference(message, field,
1710                                                          &scratch);
1711         data_size += WireFormatLite::StringSize(value);
1712       }
1713       break;
1714     }
1715   }
1716   return data_size;
1717 }
1718 
MessageSetItemByteSize(const FieldDescriptor * field,const Message & message)1719 size_t WireFormat::MessageSetItemByteSize(const FieldDescriptor* field,
1720                                           const Message& message) {
1721   const Reflection* message_reflection = message.GetReflection();
1722 
1723   size_t our_size = WireFormatLite::kMessageSetItemTagsSize;
1724 
1725   // type_id
1726   our_size += io::CodedOutputStream::VarintSize32(field->number());
1727 
1728   // message
1729   const Message& sub_message = message_reflection->GetMessage(message, field);
1730   size_t message_size = sub_message.ByteSizeLong();
1731 
1732   our_size += io::CodedOutputStream::VarintSize32(message_size);
1733   our_size += message_size;
1734 
1735   return our_size;
1736 }
1737 
1738 // Compute the size of the UnknownFieldSet on the wire.
ComputeUnknownFieldsSize(const InternalMetadata & metadata,size_t total_size,CachedSize * cached_size)1739 size_t ComputeUnknownFieldsSize(const InternalMetadata& metadata,
1740                                 size_t total_size, CachedSize* cached_size) {
1741   total_size += WireFormat::ComputeUnknownFieldsSize(
1742       metadata.unknown_fields<UnknownFieldSet>(
1743           UnknownFieldSet::default_instance));
1744   cached_size->Set(ToCachedSize(total_size));
1745   return total_size;
1746 }
1747 
1748 }  // namespace internal
1749 }  // namespace protobuf
1750 }  // namespace google
1751