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 #ifndef GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_LITE_H__
32 #define GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_LITE_H__
33 
34 #include <google/protobuf/io/zero_copy_stream_impl_lite.h>
35 #include <google/protobuf/extension_set.h>
36 #include <google/protobuf/generated_message_table_driven.h>
37 #include <google/protobuf/implicit_weak_message.h>
38 #include <google/protobuf/repeated_field.h>
39 #include <google/protobuf/wire_format_lite.h>
40 #include <type_traits>
41 
42 
43 #include <google/protobuf/port_def.inc>
44 
45 namespace google {
46 namespace protobuf {
47 namespace internal {
48 
49 
50 enum StringType {
51   StringType_STRING = 0,
52 };
53 
54 // Logically a superset of StringType, consisting of all field types that
55 // require special initialization.
56 enum ProcessingType {
57   ProcessingType_STRING = 0,
58   ProcessingType_CORD = 1,
59   ProcessingType_STRING_PIECE = 2,
60   ProcessingType_MESSAGE = 3,
61 };
62 
63 enum Cardinality {
64   Cardinality_SINGULAR = 0,
65   Cardinality_REPEATED = 1,
66   Cardinality_ONEOF = 3
67 };
68 
69 template <typename Type>
Raw(MessageLite * msg,int64 offset)70 inline Type* Raw(MessageLite* msg, int64 offset) {
71   return reinterpret_cast<Type*>(reinterpret_cast<uint8*>(msg) + offset);
72 }
73 
74 template <typename Type>
Raw(const MessageLite * msg,int64 offset)75 inline const Type* Raw(const MessageLite* msg, int64 offset) {
76   return reinterpret_cast<const Type*>(reinterpret_cast<const uint8*>(msg) +
77                                        offset);
78 }
79 
GetExtensionSet(MessageLite * msg,int64 extension_offset)80 inline ExtensionSet* GetExtensionSet(MessageLite* msg, int64 extension_offset) {
81   if (extension_offset == -1) {
82     return NULL;
83   }
84 
85   return Raw<ExtensionSet>(msg, extension_offset);
86 }
87 
88 template <typename Type>
AddField(MessageLite * msg,int64 offset)89 inline Type* AddField(MessageLite* msg, int64 offset) {
90   static_assert(std::is_trivial<Type>::value, "Do not assign");
91 
92   RepeatedField<Type>* repeated = Raw<RepeatedField<Type>>(msg, offset);
93   return repeated->Add();
94 }
95 
96 template <>
97 inline std::string* AddField<std::string>(MessageLite* msg, int64 offset) {
98   RepeatedPtrField<std::string>* repeated =
99       Raw<RepeatedPtrField<std::string>>(msg, offset);
100   return repeated->Add();
101 }
102 
103 
104 template <typename Type>
AddField(MessageLite * msg,int64 offset,Type value)105 inline void AddField(MessageLite* msg, int64 offset, Type value) {
106   static_assert(std::is_trivial<Type>::value, "Do not assign");
107   *AddField<Type>(msg, offset) = value;
108 }
109 
SetBit(uint32 * has_bits,uint32 has_bit_index)110 inline void SetBit(uint32* has_bits, uint32 has_bit_index) {
111   GOOGLE_DCHECK(has_bits != nullptr);
112 
113   uint32 mask = static_cast<uint32>(1u) << (has_bit_index % 32);
114   has_bits[has_bit_index / 32u] |= mask;
115 }
116 
117 template <typename Type>
MutableField(MessageLite * msg,uint32 * has_bits,uint32 has_bit_index,int64 offset)118 inline Type* MutableField(MessageLite* msg, uint32* has_bits,
119                           uint32 has_bit_index, int64 offset) {
120   SetBit(has_bits, has_bit_index);
121   return Raw<Type>(msg, offset);
122 }
123 
124 template <typename Type>
SetField(MessageLite * msg,uint32 * has_bits,uint32 has_bit_index,int64 offset,Type value)125 inline void SetField(MessageLite* msg, uint32* has_bits, uint32 has_bit_index,
126                      int64 offset, Type value) {
127   static_assert(std::is_trivial<Type>::value, "Do not assign");
128   *MutableField<Type>(msg, has_bits, has_bit_index, offset) = value;
129 }
130 
131 template <typename Type>
SetOneofField(MessageLite * msg,uint32 * oneof_case,uint32 oneof_case_index,int64 offset,int field_number,Type value)132 inline void SetOneofField(MessageLite* msg, uint32* oneof_case,
133                           uint32 oneof_case_index, int64 offset,
134                           int field_number, Type value) {
135   oneof_case[oneof_case_index] = field_number;
136   *Raw<Type>(msg, offset) = value;
137 }
138 
139 // Clears a oneof field. The field argument should correspond to the particular
140 // field that is currently set in the oneof.
ClearOneofField(const ParseTableField & field,Arena * arena,MessageLite * msg)141 inline void ClearOneofField(const ParseTableField& field, Arena* arena,
142                             MessageLite* msg) {
143   switch (field.processing_type & kTypeMask) {
144     case WireFormatLite::TYPE_MESSAGE:
145       if (arena == NULL) {
146         delete *Raw<MessageLite*>(msg, field.offset);
147       }
148       break;
149 
150     case WireFormatLite::TYPE_STRING:
151     case WireFormatLite::TYPE_BYTES:
152       Raw<ArenaStringPtr>(msg, field.offset)
153           ->Destroy(ArenaStringPtr::EmptyDefault{}, arena);
154       break;
155 
156     default:
157       // No cleanup needed.
158       break;
159   }
160 }
161 
162 // Clears and reinitializes a oneof field as necessary, in preparation for
163 // parsing a new value with type field_type and field number field_number.
164 //
165 // Note: the oneof_case argument should point directly to the _oneof_case_
166 // element corresponding to this particular oneof, not to the beginning of the
167 // _oneof_case_ array.
168 template <ProcessingType field_type>
ResetOneofField(const ParseTable & table,int field_number,Arena * arena,MessageLite * msg,uint32 * oneof_case,int64 offset,const void * default_ptr)169 inline void ResetOneofField(const ParseTable& table, int field_number,
170                             Arena* arena, MessageLite* msg, uint32* oneof_case,
171                             int64 offset, const void* default_ptr) {
172   if (static_cast<int64>(*oneof_case) == field_number) {
173     // The oneof is already set to the right type, so there is no need to clear
174     // it.
175     return;
176   }
177 
178   if (*oneof_case != 0) {
179     ClearOneofField(table.fields[*oneof_case], arena, msg);
180   }
181   *oneof_case = field_number;
182 
183   switch (field_type) {
184     case ProcessingType_STRING:
185       Raw<ArenaStringPtr>(msg, offset)
186           ->UnsafeSetDefault(static_cast<const std::string*>(default_ptr));
187       break;
188     case ProcessingType_MESSAGE:
189       MessageLite** submessage = Raw<MessageLite*>(msg, offset);
190       const MessageLite* prototype =
191           table.aux[field_number].messages.default_message();
192       *submessage = prototype->New(arena);
193       break;
194   }
195 }
196 
197 template <typename UnknownFieldHandler, Cardinality cardinality,
198           bool is_string_type, StringType ctype>
HandleString(io::CodedInputStream * input,MessageLite * msg,Arena * arena,uint32 * has_bits,uint32 has_bit_index,int64 offset,const void * default_ptr,const char * field_name)199 static inline bool HandleString(io::CodedInputStream* input, MessageLite* msg,
200                                 Arena* arena, uint32* has_bits,
201                                 uint32 has_bit_index, int64 offset,
202                                 const void* default_ptr,
203                                 const char* field_name) {
204   StringPiece utf8_string_data;
205 #ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
206   constexpr bool kValidateUtf8 = is_string_type;
207 #else
208   constexpr bool kValidateUtf8 = false;
209 #endif  // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
210 
211   switch (ctype) {
212     case StringType_STRING: {
213       switch (cardinality) {
214         case Cardinality_SINGULAR: {
215           ArenaStringPtr* field = MutableField<ArenaStringPtr>(
216               msg, has_bits, has_bit_index, offset);
217           std::string* value = field->MutableNoCopy(
218               static_cast<const std::string*>(default_ptr), arena);
219           if (PROTOBUF_PREDICT_FALSE(
220                   !WireFormatLite::ReadString(input, value))) {
221             return false;
222           }
223           utf8_string_data = field->Get();
224         } break;
225         case Cardinality_REPEATED: {
226           std::string* value = AddField<std::string>(msg, offset);
227           if (PROTOBUF_PREDICT_FALSE(
228                   !WireFormatLite::ReadString(input, value))) {
229             return false;
230           }
231           utf8_string_data = *value;
232         } break;
233         case Cardinality_ONEOF: {
234           ArenaStringPtr* field = Raw<ArenaStringPtr>(msg, offset);
235           std::string* value = field->MutableNoCopy(
236               static_cast<const std::string*>(default_ptr), arena);
237           if (PROTOBUF_PREDICT_FALSE(
238                   !WireFormatLite::ReadString(input, value))) {
239             return false;
240           }
241           utf8_string_data = field->Get();
242         } break;
243         default:
244           PROTOBUF_ASSUME(false);
245       }
246       break;
247     }
248     default:
249       PROTOBUF_ASSUME(false);
250   }
251 
252   if (kValidateUtf8) {
253     // TODO(b/118759213): fail if proto3
254     WireFormatLite::VerifyUtf8String(utf8_string_data.data(),
255                                      utf8_string_data.length(),
256                                      WireFormatLite::PARSE, field_name);
257   }
258   return true;
259 }
260 
261 template <typename UnknownFieldHandler, Cardinality cardinality>
HandleEnum(const ParseTable & table,io::CodedInputStream * input,MessageLite * msg,uint32 * presence,uint32 presence_index,int64 offset,uint32 tag,int field_number)262 inline bool HandleEnum(const ParseTable& table, io::CodedInputStream* input,
263                        MessageLite* msg, uint32* presence,
264                        uint32 presence_index, int64 offset, uint32 tag,
265                        int field_number) {
266   int value;
267   if (PROTOBUF_PREDICT_FALSE(
268           (!WireFormatLite::ReadPrimitive<int, WireFormatLite::TYPE_ENUM>(
269               input, &value)))) {
270     return false;
271   }
272 
273   AuxiliaryParseTableField::EnumValidator validator =
274       table.aux[field_number].enums.validator;
275   if (validator == nullptr || validator(value)) {
276     switch (cardinality) {
277       case Cardinality_SINGULAR:
278         SetField(msg, presence, presence_index, offset, value);
279         break;
280       case Cardinality_REPEATED:
281         AddField(msg, offset, value);
282         break;
283       case Cardinality_ONEOF:
284         ClearOneofField(table.fields[presence[presence_index]], msg->GetArena(),
285                         msg);
286         SetOneofField(msg, presence, presence_index, offset, field_number,
287                       value);
288         break;
289       default:
290         PROTOBUF_ASSUME(false);
291     }
292   } else {
293     UnknownFieldHandler::Varint(msg, table, tag, value);
294   }
295 
296   return true;
297 }
298 
299 // RepeatedMessageTypeHandler allows us to operate on RepeatedPtrField fields
300 // without instantiating the specific template.
301 class RepeatedMessageTypeHandler {
302  public:
303   typedef MessageLite Type;
304   typedef MessageLite WeakType;
GetArena(Type * t)305   static Arena* GetArena(Type* t) { return t->GetArena(); }
GetMaybeArenaPointer(Type * t)306   static void* GetMaybeArenaPointer(Type* t) {
307     return t->GetMaybeArenaPointer();
308   }
309   static inline Type* NewFromPrototype(const Type* prototype,
310                                        Arena* arena = NULL) {
311     return prototype->New(arena);
312   }
313   static void Delete(Type* t, Arena* arena = NULL) {
314     if (arena == NULL) {
315       delete t;
316     }
317   }
318 };
319 
320 class MergePartialFromCodedStreamHelper {
321  public:
Add(RepeatedPtrFieldBase * field,const MessageLite * prototype)322   static MessageLite* Add(RepeatedPtrFieldBase* field,
323                           const MessageLite* prototype) {
324     return field->Add<RepeatedMessageTypeHandler>(
325         const_cast<MessageLite*>(prototype));
326   }
327 };
328 
329 template <typename UnknownFieldHandler, uint32 kMaxTag>
MergePartialFromCodedStreamInlined(MessageLite * msg,const ParseTable & table,io::CodedInputStream * input)330 bool MergePartialFromCodedStreamInlined(MessageLite* msg,
331                                         const ParseTable& table,
332                                         io::CodedInputStream* input) {
333   // We require that has_bits are present, as to avoid having to check for them
334   // for every field.
335   //
336   // TODO(ckennelly):  Make this a compile-time parameter with templates.
337   GOOGLE_DCHECK_GE(table.has_bits_offset, 0);
338   uint32* has_bits = Raw<uint32>(msg, table.has_bits_offset);
339   GOOGLE_DCHECK(has_bits != NULL);
340 
341   while (true) {
342     uint32 tag = input->ReadTagWithCutoffNoLastTag(kMaxTag).first;
343     const WireFormatLite::WireType wire_type =
344         WireFormatLite::GetTagWireType(tag);
345     const int field_number = WireFormatLite::GetTagFieldNumber(tag);
346 
347     if (PROTOBUF_PREDICT_FALSE(field_number > table.max_field_number)) {
348       // check for possible extensions
349       if (UnknownFieldHandler::ParseExtension(msg, table, input, tag)) {
350         // successfully parsed
351         continue;
352       }
353 
354       if (PROTOBUF_PREDICT_FALSE(
355               !UnknownFieldHandler::Skip(msg, table, input, tag))) {
356         return false;
357       }
358 
359       continue;
360     }
361 
362     // We implicitly verify that data points to a valid field as we check the
363     // wire types.  Entries in table.fields[i] that do not correspond to valid
364     // field numbers have their normal_wiretype and packed_wiretype fields set
365     // with the kInvalidMask value.  As wire_type cannot take on that value, we
366     // will never match.
367     const ParseTableField* data = table.fields + field_number;
368 
369     // TODO(ckennelly): Avoid sign extension
370     const int64 presence_index = data->presence_index;
371     const int64 offset = data->offset;
372     const unsigned char processing_type = data->processing_type;
373 
374     if (data->normal_wiretype == static_cast<unsigned char>(wire_type)) {
375       switch (processing_type) {
376 #define HANDLE_TYPE(TYPE, CPPTYPE)                                             \
377   case (WireFormatLite::TYPE_##TYPE): {                                        \
378     CPPTYPE value;                                                             \
379     if (PROTOBUF_PREDICT_FALSE(                                                \
380             (!WireFormatLite::ReadPrimitive<                                   \
381                 CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)))) {      \
382       return false;                                                            \
383     }                                                                          \
384     SetField(msg, has_bits, presence_index, offset, value);                    \
385     break;                                                                     \
386   }                                                                            \
387   case (WireFormatLite::TYPE_##TYPE) | kRepeatedMask: {                        \
388     RepeatedField<CPPTYPE>* values = Raw<RepeatedField<CPPTYPE>>(msg, offset); \
389     if (PROTOBUF_PREDICT_FALSE((!WireFormatLite::ReadRepeatedPrimitive<        \
390                                 CPPTYPE, WireFormatLite::TYPE_##TYPE>(         \
391             data->tag_size, tag, input, values)))) {                           \
392       return false;                                                            \
393     }                                                                          \
394     break;                                                                     \
395   }                                                                            \
396   case (WireFormatLite::TYPE_##TYPE) | kOneofMask: {                           \
397     uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset);            \
398     CPPTYPE value;                                                             \
399     if (PROTOBUF_PREDICT_FALSE(                                                \
400             (!WireFormatLite::ReadPrimitive<                                   \
401                 CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)))) {      \
402       return false;                                                            \
403     }                                                                          \
404     ClearOneofField(table.fields[oneof_case[presence_index]], msg->GetArena(), \
405                     msg);                                                      \
406     SetOneofField(msg, oneof_case, presence_index, offset, field_number,       \
407                   value);                                                      \
408     break;                                                                     \
409   }
410 
411         HANDLE_TYPE(INT32, int32)
412         HANDLE_TYPE(INT64, int64)
413         HANDLE_TYPE(SINT32, int32)
414         HANDLE_TYPE(SINT64, int64)
415         HANDLE_TYPE(UINT32, uint32)
416         HANDLE_TYPE(UINT64, uint64)
417 
418         HANDLE_TYPE(FIXED32, uint32)
419         HANDLE_TYPE(FIXED64, uint64)
420         HANDLE_TYPE(SFIXED32, int32)
421         HANDLE_TYPE(SFIXED64, int64)
422 
423         HANDLE_TYPE(FLOAT, float)
424         HANDLE_TYPE(DOUBLE, double)
425 
426         HANDLE_TYPE(BOOL, bool)
427 #undef HANDLE_TYPE
428         case WireFormatLite::TYPE_BYTES:
429 #ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
430         case WireFormatLite::TYPE_STRING:
431 #endif  // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
432         {
433           Arena* const arena = msg->GetArena();
434           const void* default_ptr = table.aux[field_number].strings.default_ptr;
435 
436           if (PROTOBUF_PREDICT_FALSE(
437                   (!HandleString<UnknownFieldHandler, Cardinality_SINGULAR,
438                                  false, StringType_STRING>(
439                       input, msg, arena, has_bits, presence_index, offset,
440                       default_ptr, nullptr)))) {
441             return false;
442           }
443           break;
444         }
445         case WireFormatLite::TYPE_BYTES | kOneofMask:
446 #ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
447         case WireFormatLite::TYPE_STRING | kOneofMask:
448 #endif  // !GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
449         {
450           Arena* const arena = msg->GetArena();
451           uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset);
452           const void* default_ptr = table.aux[field_number].strings.default_ptr;
453 
454           ResetOneofField<ProcessingType_STRING>(
455               table, field_number, arena, msg, oneof_case + presence_index,
456               offset, default_ptr);
457 
458           if (PROTOBUF_PREDICT_FALSE(
459                   (!HandleString<UnknownFieldHandler, Cardinality_ONEOF, false,
460                                  StringType_STRING>(input, msg, arena, has_bits,
461                                                     presence_index, offset,
462                                                     default_ptr, nullptr)))) {
463             return false;
464           }
465           break;
466         }
467         case (WireFormatLite::TYPE_BYTES) | kRepeatedMask:
468 #ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
469         case (WireFormatLite::TYPE_STRING) | kRepeatedMask:
470 #endif  // !GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
471         {
472           Arena* const arena = msg->GetArena();
473           const void* default_ptr = table.aux[field_number].strings.default_ptr;
474 
475           if (PROTOBUF_PREDICT_FALSE(
476                   (!HandleString<UnknownFieldHandler, Cardinality_REPEATED,
477                                  false, StringType_STRING>(
478                       input, msg, arena, has_bits, presence_index, offset,
479                       default_ptr, nullptr)))) {
480             return false;
481           }
482           break;
483         }
484 #ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
485         case (WireFormatLite::TYPE_STRING): {
486           Arena* const arena = msg->GetArena();
487           const void* default_ptr = table.aux[field_number].strings.default_ptr;
488           const char* field_name = table.aux[field_number].strings.field_name;
489 
490           if (PROTOBUF_PREDICT_FALSE(
491                   (!HandleString<UnknownFieldHandler, Cardinality_SINGULAR,
492                                  true, StringType_STRING>(
493                       input, msg, arena, has_bits, presence_index, offset,
494                       default_ptr, field_name)))) {
495             return false;
496           }
497           break;
498         }
499         case (WireFormatLite::TYPE_STRING) | kRepeatedMask: {
500           Arena* const arena = msg->GetArena();
501           const void* default_ptr = table.aux[field_number].strings.default_ptr;
502           const char* field_name = table.aux[field_number].strings.field_name;
503 
504           if (PROTOBUF_PREDICT_FALSE(
505                   (!HandleString<UnknownFieldHandler, Cardinality_REPEATED,
506                                  true, StringType_STRING>(
507                       input, msg, arena, has_bits, presence_index, offset,
508                       default_ptr, field_name)))) {
509             return false;
510           }
511           break;
512         }
513         case (WireFormatLite::TYPE_STRING) | kOneofMask: {
514           Arena* const arena = msg->GetArena();
515           uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset);
516           const void* default_ptr = table.aux[field_number].strings.default_ptr;
517           const char* field_name = table.aux[field_number].strings.field_name;
518 
519           ResetOneofField<ProcessingType_STRING>(
520               table, field_number, arena, msg, oneof_case + presence_index,
521               offset, default_ptr);
522 
523           if (PROTOBUF_PREDICT_FALSE(
524                   (!HandleString<UnknownFieldHandler, Cardinality_ONEOF, true,
525                                  StringType_STRING>(
526                       input, msg, arena, has_bits, presence_index, offset,
527                       default_ptr, field_name)))) {
528             return false;
529           }
530           break;
531         }
532 #endif  // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
533         case WireFormatLite::TYPE_ENUM: {
534           if (PROTOBUF_PREDICT_FALSE(
535                   (!HandleEnum<UnknownFieldHandler, Cardinality_SINGULAR>(
536                       table, input, msg, has_bits, presence_index, offset, tag,
537                       field_number)))) {
538             return false;
539           }
540           break;
541         }
542         case WireFormatLite::TYPE_ENUM | kRepeatedMask: {
543           if (PROTOBUF_PREDICT_FALSE(
544                   (!HandleEnum<UnknownFieldHandler, Cardinality_REPEATED>(
545                       table, input, msg, has_bits, presence_index, offset, tag,
546                       field_number)))) {
547             return false;
548           }
549           break;
550         }
551         case WireFormatLite::TYPE_ENUM | kOneofMask: {
552           uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset);
553           if (PROTOBUF_PREDICT_FALSE(
554                   (!HandleEnum<UnknownFieldHandler, Cardinality_ONEOF>(
555                       table, input, msg, oneof_case, presence_index, offset,
556                       tag, field_number)))) {
557             return false;
558           }
559           break;
560         }
561         case WireFormatLite::TYPE_GROUP: {
562           MessageLite** submsg_holder =
563               MutableField<MessageLite*>(msg, has_bits, presence_index, offset);
564           MessageLite* submsg = *submsg_holder;
565 
566           if (submsg == NULL) {
567             Arena* const arena = msg->GetArena();
568             const MessageLite* prototype =
569                 table.aux[field_number].messages.default_message();
570             submsg = prototype->New(arena);
571             *submsg_holder = submsg;
572           }
573 
574           if (PROTOBUF_PREDICT_FALSE(
575                   !WireFormatLite::ReadGroup(field_number, input, submsg))) {
576             return false;
577           }
578 
579           break;
580         }
581         case WireFormatLite::TYPE_GROUP | kRepeatedMask: {
582           RepeatedPtrFieldBase* field = Raw<RepeatedPtrFieldBase>(msg, offset);
583           const MessageLite* prototype =
584               table.aux[field_number].messages.default_message();
585           GOOGLE_DCHECK(prototype != NULL);
586 
587           MessageLite* submsg =
588               MergePartialFromCodedStreamHelper::Add(field, prototype);
589 
590           if (PROTOBUF_PREDICT_FALSE(
591                   !WireFormatLite::ReadGroup(field_number, input, submsg))) {
592             return false;
593           }
594 
595           break;
596         }
597         case WireFormatLite::TYPE_MESSAGE: {
598           MessageLite** submsg_holder =
599               MutableField<MessageLite*>(msg, has_bits, presence_index, offset);
600           MessageLite* submsg = *submsg_holder;
601 
602           if (submsg == NULL) {
603             Arena* const arena = msg->GetArena();
604             const MessageLite* prototype =
605                 table.aux[field_number].messages.default_message();
606             if (prototype == NULL) {
607               prototype = ImplicitWeakMessage::default_instance();
608             }
609             submsg = prototype->New(arena);
610             *submsg_holder = submsg;
611           }
612 
613           if (PROTOBUF_PREDICT_FALSE(
614                   !WireFormatLite::ReadMessage(input, submsg))) {
615             return false;
616           }
617 
618           break;
619         }
620         // TODO(ckennelly):  Adapt ReadMessageNoVirtualNoRecursionDepth and
621         // manage input->IncrementRecursionDepth() here.
622         case WireFormatLite::TYPE_MESSAGE | kRepeatedMask: {
623           RepeatedPtrFieldBase* field = Raw<RepeatedPtrFieldBase>(msg, offset);
624           const MessageLite* prototype =
625               table.aux[field_number].messages.default_message();
626           if (prototype == NULL) {
627             prototype = ImplicitWeakMessage::default_instance();
628           }
629 
630           MessageLite* submsg =
631               MergePartialFromCodedStreamHelper::Add(field, prototype);
632 
633           if (PROTOBUF_PREDICT_FALSE(
634                   !WireFormatLite::ReadMessage(input, submsg))) {
635             return false;
636           }
637 
638           break;
639         }
640         case WireFormatLite::TYPE_MESSAGE | kOneofMask: {
641           Arena* const arena = msg->GetArena();
642           uint32* oneof_case = Raw<uint32>(msg, table.oneof_case_offset);
643           MessageLite** submsg_holder = Raw<MessageLite*>(msg, offset);
644           ResetOneofField<ProcessingType_MESSAGE>(
645               table, field_number, arena, msg, oneof_case + presence_index,
646               offset, NULL);
647           MessageLite* submsg = *submsg_holder;
648 
649           if (PROTOBUF_PREDICT_FALSE(
650                   !WireFormatLite::ReadMessage(input, submsg))) {
651             return false;
652           }
653 
654           break;
655         }
656         case TYPE_MAP: {
657           if (PROTOBUF_PREDICT_FALSE(!(*table.aux[field_number].maps.parse_map)(
658                   input, Raw<void>(msg, offset)))) {
659             return false;
660           }
661           break;
662         }
663         case 0: {
664           // Done.
665           input->SetLastTag(tag);
666           return true;
667         }
668         default:
669           PROTOBUF_ASSUME(false);
670       }
671     } else if (data->packed_wiretype == static_cast<unsigned char>(wire_type)) {
672       // Non-packable fields have their packed_wiretype masked with
673       // kNotPackedMask, which is impossible to match here.
674       GOOGLE_DCHECK(processing_type & kRepeatedMask);
675       GOOGLE_DCHECK_NE(processing_type, kRepeatedMask);
676       GOOGLE_DCHECK_EQ(0, processing_type & kOneofMask);
677 
678 
679       // Mask out kRepeatedMask bit, allowing the jump table to be smaller.
680       switch (static_cast<WireFormatLite::FieldType>(processing_type ^
681                                                      kRepeatedMask)) {
682 #define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD)                      \
683   case WireFormatLite::TYPE_##TYPE: {                                          \
684     RepeatedField<CPPTYPE>* values = Raw<RepeatedField<CPPTYPE>>(msg, offset); \
685     if (PROTOBUF_PREDICT_FALSE(                                                \
686             (!WireFormatLite::ReadPackedPrimitive<                             \
687                 CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, values)))) {      \
688       return false;                                                            \
689     }                                                                          \
690     break;                                                                     \
691   }
692 
693         HANDLE_PACKED_TYPE(INT32, int32, Int32)
694         HANDLE_PACKED_TYPE(INT64, int64, Int64)
695         HANDLE_PACKED_TYPE(SINT32, int32, Int32)
696         HANDLE_PACKED_TYPE(SINT64, int64, Int64)
697         HANDLE_PACKED_TYPE(UINT32, uint32, UInt32)
698         HANDLE_PACKED_TYPE(UINT64, uint64, UInt64)
699 
700         HANDLE_PACKED_TYPE(FIXED32, uint32, UInt32)
701         HANDLE_PACKED_TYPE(FIXED64, uint64, UInt64)
702         HANDLE_PACKED_TYPE(SFIXED32, int32, Int32)
703         HANDLE_PACKED_TYPE(SFIXED64, int64, Int64)
704 
705         HANDLE_PACKED_TYPE(FLOAT, float, Float)
706         HANDLE_PACKED_TYPE(DOUBLE, double, Double)
707 
708         HANDLE_PACKED_TYPE(BOOL, bool, Bool)
709 #undef HANDLE_PACKED_TYPE
710         case WireFormatLite::TYPE_ENUM: {
711           // To avoid unnecessarily calling MutableUnknownFields (which mutates
712           // InternalMetadata) when all inputs in the repeated series
713           // are valid, we implement our own parser rather than call
714           // WireFormat::ReadPackedEnumPreserveUnknowns.
715           uint32 length;
716           if (PROTOBUF_PREDICT_FALSE(!input->ReadVarint32(&length))) {
717             return false;
718           }
719 
720           AuxiliaryParseTableField::EnumValidator validator =
721               table.aux[field_number].enums.validator;
722           RepeatedField<int>* values = Raw<RepeatedField<int>>(msg, offset);
723 
724           io::CodedInputStream::Limit limit = input->PushLimit(length);
725           while (input->BytesUntilLimit() > 0) {
726             int value;
727             if (PROTOBUF_PREDICT_FALSE(
728                     (!WireFormatLite::ReadPrimitive<
729                         int, WireFormatLite::TYPE_ENUM>(input, &value)))) {
730               return false;
731             }
732 
733             if (validator == nullptr || validator(value)) {
734               values->Add(value);
735             } else {
736               // TODO(ckennelly): Consider caching here.
737               UnknownFieldHandler::Varint(msg, table, tag, value);
738             }
739           }
740           input->PopLimit(limit);
741 
742           break;
743         }
744         case WireFormatLite::TYPE_STRING:
745         case WireFormatLite::TYPE_GROUP:
746         case WireFormatLite::TYPE_MESSAGE:
747         case WireFormatLite::TYPE_BYTES:
748           GOOGLE_DCHECK(false);
749           return false;
750         default:
751           PROTOBUF_ASSUME(false);
752       }
753     } else {
754       if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
755         // Must be the end of the message.
756         input->SetLastTag(tag);
757         return true;
758       }
759 
760       // check for possible extensions
761       if (UnknownFieldHandler::ParseExtension(msg, table, input, tag)) {
762         // successfully parsed
763         continue;
764       }
765 
766       // process unknown field.
767       if (PROTOBUF_PREDICT_FALSE(
768               !UnknownFieldHandler::Skip(msg, table, input, tag))) {
769         return false;
770       }
771     }
772   }
773 }  // NOLINT(readability/fn_size)
774 
775 template <typename UnknownFieldHandler>
MergePartialFromCodedStreamImpl(MessageLite * msg,const ParseTable & table,io::CodedInputStream * input)776 bool MergePartialFromCodedStreamImpl(MessageLite* msg, const ParseTable& table,
777                                      io::CodedInputStream* input) {
778   // The main beneficial cutoff values are 1 and 2 byte tags.
779   // Instantiate calls with the appropriate upper tag range
780   if (table.max_field_number <= (0x7F >> 3)) {
781     return MergePartialFromCodedStreamInlined<UnknownFieldHandler, 0x7F>(
782         msg, table, input);
783   } else if (table.max_field_number <= (0x3FFF >> 3)) {
784     return MergePartialFromCodedStreamInlined<UnknownFieldHandler, 0x3FFF>(
785         msg, table, input);
786   } else {
787     return MergePartialFromCodedStreamInlined<
788         UnknownFieldHandler, std::numeric_limits<uint32>::max()>(msg, table,
789                                                                  input);
790   }
791 }
792 
793 }  // namespace internal
794 }  // namespace protobuf
795 }  // namespace google
796 
797 #include <google/protobuf/port_undef.inc>
798 
799 #endif  // GOOGLE_PROTOBUF_GENERATED_MESSAGE_TABLE_DRIVEN_LITE_H__
800