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