in cdk/extra/protobuf/protobuf-3.19.6/src/google/protobuf/generated_message_table_driven_lite.h [367:848]
bool MergePartialFromCodedStreamInlined(MessageLite* msg,
const ParseTable& table,
io::CodedInputStream* input) {
// We require that has_bits are present, as to avoid having to check for them
// for every field.
//
// TODO(ckennelly): Make this a compile-time parameter with templates.
GOOGLE_DCHECK_GE(table.has_bits_offset, 0);
uint32_t* has_bits = Raw<uint32_t>(msg, table.has_bits_offset);
GOOGLE_DCHECK(has_bits != nullptr);
while (true) {
uint32_t tag = input->ReadTagWithCutoffNoLastTag(kMaxTag).first;
const WireFormatLite::WireType wire_type =
WireFormatLite::GetTagWireType(tag);
const int field_number = WireFormatLite::GetTagFieldNumber(tag);
if (PROTOBUF_PREDICT_FALSE(field_number > table.max_field_number)) {
// check for possible extensions
if (UnknownFieldHandler::ParseExtension(msg, table, input, tag)) {
// successfully parsed
continue;
}
if (PROTOBUF_PREDICT_FALSE(
!UnknownFieldHandler::Skip(msg, table, input, tag))) {
return false;
}
continue;
}
// We implicitly verify that data points to a valid field as we check the
// wire types. Entries in table.fields[i] that do not correspond to valid
// field numbers have their normal_wiretype and packed_wiretype fields set
// with the kInvalidMask value. As wire_type cannot take on that value, we
// will never match.
const ParseTableField* data = table.fields + field_number;
// TODO(ckennelly): Avoid sign extension
const int64_t presence_index = data->presence_index;
const int64_t offset = data->offset;
const unsigned char processing_type = data->processing_type;
if (data->normal_wiretype == static_cast<unsigned char>(wire_type)) {
switch (processing_type) {
#define HANDLE_TYPE(TYPE, CPPTYPE) \
case (WireFormatLite::TYPE_##TYPE): { \
CPPTYPE value; \
if (PROTOBUF_PREDICT_FALSE( \
(!WireFormatLite::ReadPrimitive< \
CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)))) { \
return false; \
} \
SetField(msg, has_bits, presence_index, offset, value); \
break; \
} \
case (WireFormatLite::TYPE_##TYPE) | kRepeatedMask: { \
RepeatedField<CPPTYPE>* values = Raw<RepeatedField<CPPTYPE>>(msg, offset); \
if (PROTOBUF_PREDICT_FALSE((!WireFormatLite::ReadRepeatedPrimitive< \
CPPTYPE, WireFormatLite::TYPE_##TYPE>( \
data->tag_size, tag, input, values)))) { \
return false; \
} \
break; \
} \
case (WireFormatLite::TYPE_##TYPE) | kOneofMask: { \
uint32_t* oneof_case = Raw<uint32_t>(msg, table.oneof_case_offset); \
CPPTYPE value; \
if (PROTOBUF_PREDICT_FALSE( \
(!WireFormatLite::ReadPrimitive< \
CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, &value)))) { \
return false; \
} \
ClearOneofField(table.fields[oneof_case[presence_index]], msg->GetArena(), \
msg); \
SetOneofField(msg, oneof_case, presence_index, offset, field_number, \
value); \
break; \
}
HANDLE_TYPE(INT32, int32_t)
HANDLE_TYPE(INT64, int64_t)
HANDLE_TYPE(SINT32, int32_t)
HANDLE_TYPE(SINT64, int64_t)
HANDLE_TYPE(UINT32, uint32_t)
HANDLE_TYPE(UINT64, uint64_t)
HANDLE_TYPE(FIXED32, uint32_t)
HANDLE_TYPE(FIXED64, uint64_t)
HANDLE_TYPE(SFIXED32, int32_t)
HANDLE_TYPE(SFIXED64, int64_t)
HANDLE_TYPE(FLOAT, float)
HANDLE_TYPE(DOUBLE, double)
HANDLE_TYPE(BOOL, bool)
#undef HANDLE_TYPE
case WireFormatLite::TYPE_BYTES:
#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
case WireFormatLite::TYPE_STRING:
#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
{
Arena* const arena = msg->GetArena();
const void* default_ptr = table.aux[field_number].strings.default_ptr;
if (PROTOBUF_PREDICT_FALSE(
(!HandleString<UnknownFieldHandler, Cardinality_SINGULAR,
false, StringType_STRING>(
input, msg, arena, has_bits, presence_index, offset,
default_ptr, nullptr)))) {
return false;
}
break;
}
case TYPE_BYTES_INLINED:
#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
case TYPE_STRING_INLINED:
#endif // !GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
{
Arena* const arena = msg->GetArena();
const void* default_ptr = table.aux[field_number].strings.default_ptr;
if (PROTOBUF_PREDICT_FALSE(
(!HandleString<UnknownFieldHandler, Cardinality_SINGULAR,
false, StringType_INLINED>(
input, msg, arena, has_bits, presence_index, offset,
default_ptr, nullptr)))) {
return false;
}
break;
}
case WireFormatLite::TYPE_BYTES | kOneofMask:
#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
case WireFormatLite::TYPE_STRING | kOneofMask:
#endif // !GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
{
Arena* const arena = msg->GetArena();
uint32_t* oneof_case = Raw<uint32_t>(msg, table.oneof_case_offset);
const void* default_ptr = table.aux[field_number].strings.default_ptr;
ResetOneofField<ProcessingType_STRING>(
table, field_number, arena, msg, oneof_case + presence_index,
offset, default_ptr);
if (PROTOBUF_PREDICT_FALSE(
(!HandleString<UnknownFieldHandler, Cardinality_ONEOF, false,
StringType_STRING>(input, msg, arena, has_bits,
presence_index, offset,
default_ptr, nullptr)))) {
return false;
}
break;
}
case (WireFormatLite::TYPE_BYTES) | kRepeatedMask:
case TYPE_BYTES_INLINED | kRepeatedMask:
#ifndef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
case (WireFormatLite::TYPE_STRING) | kRepeatedMask:
case TYPE_STRING_INLINED | kRepeatedMask:
#endif // !GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
{
Arena* const arena = msg->GetArena();
const void* default_ptr = table.aux[field_number].strings.default_ptr;
if (PROTOBUF_PREDICT_FALSE(
(!HandleString<UnknownFieldHandler, Cardinality_REPEATED,
false, StringType_STRING>(
input, msg, arena, has_bits, presence_index, offset,
default_ptr, nullptr)))) {
return false;
}
break;
}
#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
case (WireFormatLite::TYPE_STRING): {
Arena* const arena = msg->GetArena();
const void* default_ptr = table.aux[field_number].strings.default_ptr;
const char* field_name = table.aux[field_number].strings.field_name;
if (PROTOBUF_PREDICT_FALSE(
(!HandleString<UnknownFieldHandler, Cardinality_SINGULAR,
true, StringType_STRING>(
input, msg, arena, has_bits, presence_index, offset,
default_ptr, field_name)))) {
return false;
}
break;
}
case TYPE_STRING_INLINED | kRepeatedMask:
case (WireFormatLite::TYPE_STRING) | kRepeatedMask: {
Arena* const arena = msg->GetArena();
const void* default_ptr = table.aux[field_number].strings.default_ptr;
const char* field_name = table.aux[field_number].strings.field_name;
if (PROTOBUF_PREDICT_FALSE(
(!HandleString<UnknownFieldHandler, Cardinality_REPEATED,
true, StringType_STRING>(
input, msg, arena, has_bits, presence_index, offset,
default_ptr, field_name)))) {
return false;
}
break;
}
case (WireFormatLite::TYPE_STRING) | kOneofMask: {
Arena* const arena = msg->GetArena();
uint32_t* oneof_case = Raw<uint32_t>(msg, table.oneof_case_offset);
const void* default_ptr = table.aux[field_number].strings.default_ptr;
const char* field_name = table.aux[field_number].strings.field_name;
ResetOneofField<ProcessingType_STRING>(
table, field_number, arena, msg, oneof_case + presence_index,
offset, default_ptr);
if (PROTOBUF_PREDICT_FALSE(
(!HandleString<UnknownFieldHandler, Cardinality_ONEOF, true,
StringType_STRING>(
input, msg, arena, has_bits, presence_index, offset,
default_ptr, field_name)))) {
return false;
}
break;
}
#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
case WireFormatLite::TYPE_ENUM: {
if (PROTOBUF_PREDICT_FALSE(
(!HandleEnum<UnknownFieldHandler, Cardinality_SINGULAR>(
table, input, msg, has_bits, presence_index, offset, tag,
field_number)))) {
return false;
}
break;
}
case WireFormatLite::TYPE_ENUM | kRepeatedMask: {
if (PROTOBUF_PREDICT_FALSE(
(!HandleEnum<UnknownFieldHandler, Cardinality_REPEATED>(
table, input, msg, has_bits, presence_index, offset, tag,
field_number)))) {
return false;
}
break;
}
case WireFormatLite::TYPE_ENUM | kOneofMask: {
uint32_t* oneof_case = Raw<uint32_t>(msg, table.oneof_case_offset);
if (PROTOBUF_PREDICT_FALSE(
(!HandleEnum<UnknownFieldHandler, Cardinality_ONEOF>(
table, input, msg, oneof_case, presence_index, offset,
tag, field_number)))) {
return false;
}
break;
}
case WireFormatLite::TYPE_GROUP: {
MessageLite** submsg_holder =
MutableField<MessageLite*>(msg, has_bits, presence_index, offset);
MessageLite* submsg = *submsg_holder;
if (submsg == nullptr) {
Arena* const arena = msg->GetArena();
const MessageLite* prototype =
table.aux[field_number].messages.default_message();
submsg = prototype->New(arena);
*submsg_holder = submsg;
}
if (PROTOBUF_PREDICT_FALSE(
!WireFormatLite::ReadGroup(field_number, input, submsg))) {
return false;
}
break;
}
case WireFormatLite::TYPE_GROUP | kRepeatedMask: {
RepeatedPtrFieldBase* field = Raw<RepeatedPtrFieldBase>(msg, offset);
const MessageLite* prototype =
table.aux[field_number].messages.default_message();
GOOGLE_DCHECK(prototype != nullptr);
MessageLite* submsg =
MergePartialFromCodedStreamHelper::Add(field, prototype);
if (PROTOBUF_PREDICT_FALSE(
!WireFormatLite::ReadGroup(field_number, input, submsg))) {
return false;
}
break;
}
case WireFormatLite::TYPE_MESSAGE: {
MessageLite** submsg_holder =
MutableField<MessageLite*>(msg, has_bits, presence_index, offset);
MessageLite* submsg = *submsg_holder;
if (submsg == nullptr) {
Arena* const arena = msg->GetArena();
const MessageLite* prototype =
table.aux[field_number].messages.default_message();
if (prototype == nullptr) {
prototype = ImplicitWeakMessage::default_instance();
}
submsg = prototype->New(arena);
*submsg_holder = submsg;
}
if (PROTOBUF_PREDICT_FALSE(
!WireFormatLite::ReadMessage(input, submsg))) {
return false;
}
break;
}
// TODO(ckennelly): Adapt ReadMessageNoVirtualNoRecursionDepth and
// manage input->IncrementRecursionDepth() here.
case WireFormatLite::TYPE_MESSAGE | kRepeatedMask: {
RepeatedPtrFieldBase* field = Raw<RepeatedPtrFieldBase>(msg, offset);
const MessageLite* prototype =
table.aux[field_number].messages.default_message();
if (prototype == nullptr) {
prototype = ImplicitWeakMessage::default_instance();
}
MessageLite* submsg =
MergePartialFromCodedStreamHelper::Add(field, prototype);
if (PROTOBUF_PREDICT_FALSE(
!WireFormatLite::ReadMessage(input, submsg))) {
return false;
}
break;
}
case WireFormatLite::TYPE_MESSAGE | kOneofMask: {
Arena* const arena = msg->GetArena();
uint32_t* oneof_case = Raw<uint32_t>(msg, table.oneof_case_offset);
MessageLite** submsg_holder = Raw<MessageLite*>(msg, offset);
ResetOneofField<ProcessingType_MESSAGE>(
table, field_number, arena, msg, oneof_case + presence_index,
offset, nullptr);
MessageLite* submsg = *submsg_holder;
if (PROTOBUF_PREDICT_FALSE(
!WireFormatLite::ReadMessage(input, submsg))) {
return false;
}
break;
}
#ifdef GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
case TYPE_STRING_INLINED: {
Arena* const arena = msg->GetArena();
const void* default_ptr = table.aux[field_number].strings.default_ptr;
const char* field_name = table.aux[field_number].strings.field_name;
if (PROTOBUF_PREDICT_FALSE(
(!HandleString<UnknownFieldHandler, Cardinality_SINGULAR,
true, StringType_INLINED>(
input, msg, arena, has_bits, presence_index, offset,
default_ptr, field_name)))) {
return false;
}
break;
}
#endif // GOOGLE_PROTOBUF_UTF8_VALIDATION_ENABLED
case TYPE_MAP: {
if (PROTOBUF_PREDICT_FALSE(!(*table.aux[field_number].maps.parse_map)(
input, Raw<void>(msg, offset)))) {
return false;
}
break;
}
case 0: {
// Done.
input->SetLastTag(tag);
return true;
}
default:
PROTOBUF_ASSUME(false);
}
} else if (data->packed_wiretype == static_cast<unsigned char>(wire_type)) {
// Non-packable fields have their packed_wiretype masked with
// kNotPackedMask, which is impossible to match here.
GOOGLE_DCHECK(processing_type & kRepeatedMask);
GOOGLE_DCHECK_NE(processing_type, kRepeatedMask);
GOOGLE_DCHECK_EQ(0, processing_type & kOneofMask);
GOOGLE_DCHECK_NE(TYPE_BYTES_INLINED | kRepeatedMask, processing_type);
GOOGLE_DCHECK_NE(TYPE_STRING_INLINED | kRepeatedMask, processing_type);
// Mask out kRepeatedMask bit, allowing the jump table to be smaller.
switch (static_cast<WireFormatLite::FieldType>(processing_type ^
kRepeatedMask)) {
#define HANDLE_PACKED_TYPE(TYPE, CPPTYPE, CPPTYPE_METHOD) \
case WireFormatLite::TYPE_##TYPE: { \
RepeatedField<CPPTYPE>* values = Raw<RepeatedField<CPPTYPE>>(msg, offset); \
if (PROTOBUF_PREDICT_FALSE( \
(!WireFormatLite::ReadPackedPrimitive< \
CPPTYPE, WireFormatLite::TYPE_##TYPE>(input, values)))) { \
return false; \
} \
break; \
}
HANDLE_PACKED_TYPE(INT32, int32_t, Int32)
HANDLE_PACKED_TYPE(INT64, int64_t, Int64)
HANDLE_PACKED_TYPE(SINT32, int32_t, Int32)
HANDLE_PACKED_TYPE(SINT64, int64_t, Int64)
HANDLE_PACKED_TYPE(UINT32, uint32_t, UInt32)
HANDLE_PACKED_TYPE(UINT64, uint64_t, UInt64)
HANDLE_PACKED_TYPE(FIXED32, uint32_t, UInt32)
HANDLE_PACKED_TYPE(FIXED64, uint64_t, UInt64)
HANDLE_PACKED_TYPE(SFIXED32, int32_t, Int32)
HANDLE_PACKED_TYPE(SFIXED64, int64_t, Int64)
HANDLE_PACKED_TYPE(FLOAT, float, Float)
HANDLE_PACKED_TYPE(DOUBLE, double, Double)
HANDLE_PACKED_TYPE(BOOL, bool, Bool)
#undef HANDLE_PACKED_TYPE
case WireFormatLite::TYPE_ENUM: {
// To avoid unnecessarily calling MutableUnknownFields (which mutates
// InternalMetadata) when all inputs in the repeated series
// are valid, we implement our own parser rather than call
// WireFormat::ReadPackedEnumPreserveUnknowns.
uint32_t length;
if (PROTOBUF_PREDICT_FALSE(!input->ReadVarint32(&length))) {
return false;
}
AuxiliaryParseTableField::EnumValidator validator =
table.aux[field_number].enums.validator;
RepeatedField<int>* values = Raw<RepeatedField<int>>(msg, offset);
io::CodedInputStream::Limit limit = input->PushLimit(length);
while (input->BytesUntilLimit() > 0) {
int value;
if (PROTOBUF_PREDICT_FALSE(
(!WireFormatLite::ReadPrimitive<
int, WireFormatLite::TYPE_ENUM>(input, &value)))) {
return false;
}
if (validator == nullptr || validator(value)) {
values->Add(value);
} else {
// TODO(ckennelly): Consider caching here.
UnknownFieldHandler::Varint(msg, table, tag, value);
}
}
input->PopLimit(limit);
break;
}
case WireFormatLite::TYPE_STRING:
case WireFormatLite::TYPE_GROUP:
case WireFormatLite::TYPE_MESSAGE:
case WireFormatLite::TYPE_BYTES:
GOOGLE_DCHECK(false);
return false;
default:
PROTOBUF_ASSUME(false);
}
} else {
if (wire_type == WireFormatLite::WIRETYPE_END_GROUP) {
// Must be the end of the message.
input->SetLastTag(tag);
return true;
}
// check for possible extensions
if (UnknownFieldHandler::ParseExtension(msg, table, input, tag)) {
// successfully parsed
continue;
}
// process unknown field.
if (PROTOBUF_PREDICT_FALSE(
!UnknownFieldHandler::Skip(msg, table, input, tag))) {
return false;
}
}
}
} // NOLINT(readability/fn_size)