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