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