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