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