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