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