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