[api] Second cleanup pass over the decode generator

Repeated fields encode their elements through one encode_element() hook instead of two
isinstance ladders, the fixed32 precomputed tag path owns its own guard, the generated
switches drop the dead default case, StringRef takes the byte pointer directly, the
three hand written tag expressions in proto.h go through proto_tag(), and stale comments
about the previous decode design go. The compiled functions are unchanged.
This commit is contained in:
J. Nick Koston
2026-09-07 15:24:34 +02:00
parent c26c830f82
commit 06a1de692d
5 changed files with 58 additions and 195 deletions
+28 -146
View File
@@ -11,7 +11,7 @@ void HelloRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_
const ProtoFieldValue value(data, scalar);
switch (tag) {
case proto_tag(1, WIRE_TYPE_LENGTH_DELIMITED):
this->client_info = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->client_info = StringRef(value.data(), value.size());
break;
case proto_tag(2, WIRE_TYPE_VARINT):
this->api_version_major = value.as_varint();
@@ -19,8 +19,6 @@ void HelloRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_
case proto_tag(3, WIRE_TYPE_VARINT):
this->api_version_minor = value.as_varint();
break;
default:
break;
}
}
uint8_t *HelloResponse::encode_msg(const void *self, ProtoWriteBuffer &buffer PROTO_ENCODE_DEBUG_PARAM) {
@@ -47,8 +45,6 @@ void DisconnectRequest::decode_field(uint32_t tag, const uint8_t *data, proto_va
case proto_tag(1, WIRE_TYPE_VARINT):
this->reason = static_cast<enums::DisconnectReason>(value.as_varint());
break;
default:
break;
}
}
uint8_t *DisconnectRequest::encode_msg(const void *self, ProtoWriteBuffer &buffer PROTO_ENCODE_DEBUG_PARAM) {
@@ -489,8 +485,6 @@ void CoverCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_
this->device_id = value.as_varint();
break;
#endif
default:
break;
}
}
#endif
@@ -605,15 +599,13 @@ void FanCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_va
this->has_preset_mode = value.as_bool();
break;
case proto_tag(13, WIRE_TYPE_LENGTH_DELIMITED):
this->preset_mode = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->preset_mode = StringRef(value.data(), value.size());
break;
#ifdef USE_DEVICES
case proto_tag(14, WIRE_TYPE_VARINT):
this->device_id = value.as_varint();
break;
#endif
default:
break;
}
}
#endif
@@ -814,15 +806,13 @@ void LightCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_
this->has_effect = value.as_bool();
break;
case proto_tag(19, WIRE_TYPE_LENGTH_DELIMITED):
this->effect = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->effect = StringRef(value.data(), value.size());
break;
#ifdef USE_DEVICES
case proto_tag(28, WIRE_TYPE_VARINT):
this->device_id = value.as_varint();
break;
#endif
default:
break;
}
}
#endif
@@ -969,8 +959,6 @@ void SwitchCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto
this->device_id = value.as_varint();
break;
#endif
default:
break;
}
}
#endif
@@ -1042,8 +1030,6 @@ void SubscribeLogsRequest::decode_field(uint32_t tag, const uint8_t *data, proto
case proto_tag(2, WIRE_TYPE_VARINT):
this->dump_config = value.as_bool();
break;
default:
break;
}
}
__attribute__((optimize("O2"))) // NOLINT(clang-diagnostic-unknown-attributes)
@@ -1074,8 +1060,6 @@ void NoiseEncryptionSetKeyRequest::decode_field(uint32_t tag, const uint8_t *dat
this->key = value.data();
this->key_len = value.size();
break;
default:
break;
}
}
uint8_t *NoiseEncryptionSetKeyResponse::encode_msg(const void *self,
@@ -1175,7 +1159,7 @@ void HomeassistantActionResponse::decode_field(uint32_t tag, const uint8_t *data
this->success = value.as_bool();
break;
case proto_tag(3, WIRE_TYPE_LENGTH_DELIMITED):
this->error_message = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->error_message = StringRef(value.data(), value.size());
break;
#ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON
case proto_tag(4, WIRE_TYPE_LENGTH_DELIMITED):
@@ -1183,8 +1167,6 @@ void HomeassistantActionResponse::decode_field(uint32_t tag, const uint8_t *data
this->response_data_len = value.size();
break;
#endif
default:
break;
}
}
#endif
@@ -1210,15 +1192,13 @@ void HomeAssistantStateResponse::decode_field(uint32_t tag, const uint8_t *data,
const ProtoFieldValue value(data, scalar);
switch (tag) {
case proto_tag(1, WIRE_TYPE_LENGTH_DELIMITED):
this->entity_id = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->entity_id = StringRef(value.data(), value.size());
break;
case proto_tag(2, WIRE_TYPE_LENGTH_DELIMITED):
this->state = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->state = StringRef(value.data(), value.size());
break;
case proto_tag(3, WIRE_TYPE_LENGTH_DELIMITED):
this->attribute = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
break;
default:
this->attribute = StringRef(value.data(), value.size());
break;
}
}
@@ -1244,8 +1224,6 @@ void DSTRule::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value
case proto_tag(6, WIRE_TYPE_VARINT):
this->day_of_week = value.as_varint();
break;
default:
break;
}
}
void ParsedTimezone::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) {
@@ -1263,8 +1241,6 @@ void ParsedTimezone::decode_field(uint32_t tag, const uint8_t *data, proto_varin
case proto_tag(4, WIRE_TYPE_LENGTH_DELIMITED):
value.decode_to_message(this->dst_end);
break;
default:
break;
}
}
void GetTimeResponse::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) {
@@ -1277,8 +1253,6 @@ void GetTimeResponse::decode_field(uint32_t tag, const uint8_t *data, proto_vari
value.decode_to_message(this->parsed_timezone);
this->has_parsed_timezone = true;
break;
default:
break;
}
}
#ifdef USE_API_USER_DEFINED_ACTIONS
@@ -1351,7 +1325,7 @@ void ExecuteServiceArgument::decode_field(uint32_t tag, const uint8_t *data, pro
this->float_ = value.as_float();
break;
case proto_tag(4, WIRE_TYPE_LENGTH_DELIMITED):
this->string_ = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->string_ = StringRef(value.data(), value.size());
break;
case proto_tag(5, WIRE_TYPE_VARINT):
this->int_ = decode_zigzag32(static_cast<uint32_t>(value.as_varint()));
@@ -1368,8 +1342,6 @@ void ExecuteServiceArgument::decode_field(uint32_t tag, const uint8_t *data, pro
case proto_tag(9, WIRE_TYPE_LENGTH_DELIMITED):
this->string_array.push_back(value.as_string());
break;
default:
break;
}
}
void ExecuteServiceArgument::decode(const uint8_t *buffer, size_t length) {
@@ -1403,8 +1375,6 @@ void ExecuteServiceRequest::decode_field(uint32_t tag, const uint8_t *data, prot
this->return_response = value.as_bool();
break;
#endif
default:
break;
}
}
void ExecuteServiceRequest::decode(const uint8_t *buffer, size_t length) {
@@ -1501,8 +1471,6 @@ void CameraImageRequest::decode_field(uint32_t tag, const uint8_t *data, proto_v
case proto_tag(2, WIRE_TYPE_VARINT):
this->stream = value.as_bool();
break;
default:
break;
}
}
#endif
@@ -1713,7 +1681,7 @@ void ClimateCommandRequest::decode_field(uint32_t tag, const uint8_t *data, prot
this->has_custom_fan_mode = value.as_bool();
break;
case proto_tag(17, WIRE_TYPE_LENGTH_DELIMITED):
this->custom_fan_mode = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->custom_fan_mode = StringRef(value.data(), value.size());
break;
case proto_tag(18, WIRE_TYPE_VARINT):
this->has_preset = value.as_bool();
@@ -1725,7 +1693,7 @@ void ClimateCommandRequest::decode_field(uint32_t tag, const uint8_t *data, prot
this->has_custom_preset = value.as_bool();
break;
case proto_tag(21, WIRE_TYPE_LENGTH_DELIMITED):
this->custom_preset = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->custom_preset = StringRef(value.data(), value.size());
break;
case proto_tag(22, WIRE_TYPE_VARINT):
this->has_target_humidity = value.as_bool();
@@ -1738,8 +1706,6 @@ void ClimateCommandRequest::decode_field(uint32_t tag, const uint8_t *data, prot
this->device_id = value.as_varint();
break;
#endif
default:
break;
}
}
#endif
@@ -1866,8 +1832,6 @@ void WaterHeaterCommandRequest::decode_field(uint32_t tag, const uint8_t *data,
case proto_tag(8, WIRE_TYPE_FIXED32):
this->target_temperature_high = value.as_float();
break;
default:
break;
}
}
#endif
@@ -1960,8 +1924,6 @@ void NumberCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto
this->device_id = value.as_varint();
break;
#endif
default:
break;
}
}
#endif
@@ -2035,15 +1997,13 @@ void SelectCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto
this->key = value.as_fixed32();
break;
case proto_tag(2, WIRE_TYPE_LENGTH_DELIMITED):
this->state = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->state = StringRef(value.data(), value.size());
break;
#ifdef USE_DEVICES
case proto_tag(3, WIRE_TYPE_VARINT):
this->device_id = value.as_varint();
break;
#endif
default:
break;
}
}
#endif
@@ -2128,7 +2088,7 @@ void SirenCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_
this->has_tone = value.as_bool();
break;
case proto_tag(5, WIRE_TYPE_LENGTH_DELIMITED):
this->tone = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->tone = StringRef(value.data(), value.size());
break;
case proto_tag(6, WIRE_TYPE_VARINT):
this->has_duration = value.as_bool();
@@ -2147,8 +2107,6 @@ void SirenCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_
this->device_id = value.as_varint();
break;
#endif
default:
break;
}
}
#endif
@@ -2226,15 +2184,13 @@ void LockCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_v
this->has_code = value.as_bool();
break;
case proto_tag(4, WIRE_TYPE_LENGTH_DELIMITED):
this->code = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->code = StringRef(value.data(), value.size());
break;
#ifdef USE_DEVICES
case proto_tag(5, WIRE_TYPE_VARINT):
this->device_id = value.as_varint();
break;
#endif
default:
break;
}
}
#endif
@@ -2284,8 +2240,6 @@ void ButtonCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto
this->device_id = value.as_varint();
break;
#endif
default:
break;
}
}
#endif
@@ -2401,7 +2355,7 @@ void MediaPlayerCommandRequest::decode_field(uint32_t tag, const uint8_t *data,
this->has_media_url = value.as_bool();
break;
case proto_tag(7, WIRE_TYPE_LENGTH_DELIMITED):
this->media_url = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->media_url = StringRef(value.data(), value.size());
break;
case proto_tag(8, WIRE_TYPE_VARINT):
this->has_announcement = value.as_bool();
@@ -2414,8 +2368,6 @@ void MediaPlayerCommandRequest::decode_field(uint32_t tag, const uint8_t *data,
this->device_id = value.as_varint();
break;
#endif
default:
break;
}
}
#endif
@@ -2427,8 +2379,6 @@ void SubscribeBluetoothLEAdvertisementsRequest::decode_field(uint32_t tag, const
case proto_tag(1, WIRE_TYPE_VARINT):
this->flags = value.as_varint();
break;
default:
break;
}
}
__attribute__((optimize("O2"))) // NOLINT(clang-diagnostic-unknown-attributes)
@@ -2488,8 +2438,6 @@ void BluetoothDeviceRequest::decode_field(uint32_t tag, const uint8_t *data, pro
case proto_tag(4, WIRE_TYPE_VARINT):
this->address_type = value.as_varint();
break;
default:
break;
}
}
uint8_t *BluetoothDeviceConnectionResponse::encode_msg(const void *self,
@@ -2517,8 +2465,6 @@ void BluetoothGATTGetServicesRequest::decode_field(uint32_t tag, const uint8_t *
case proto_tag(1, WIRE_TYPE_VARINT):
this->address = value.as_varint();
break;
default:
break;
}
}
uint8_t *BluetoothGATTDescriptor::encode_msg(const void *self, ProtoWriteBuffer &buffer PROTO_ENCODE_DEBUG_PARAM) {
@@ -2648,8 +2594,6 @@ void BluetoothGATTReadRequest::decode_field(uint32_t tag, const uint8_t *data, p
case proto_tag(2, WIRE_TYPE_VARINT):
this->handle = value.as_varint();
break;
default:
break;
}
}
uint8_t *BluetoothGATTReadResponse::encode_msg(const void *self, ProtoWriteBuffer &buffer PROTO_ENCODE_DEBUG_PARAM) {
@@ -2684,8 +2628,6 @@ void BluetoothGATTWriteRequest::decode_field(uint32_t tag, const uint8_t *data,
this->data = value.data();
this->data_len = value.size();
break;
default:
break;
}
}
void BluetoothGATTReadDescriptorRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) {
@@ -2697,8 +2639,6 @@ void BluetoothGATTReadDescriptorRequest::decode_field(uint32_t tag, const uint8_
case proto_tag(2, WIRE_TYPE_VARINT):
this->handle = value.as_varint();
break;
default:
break;
}
}
void BluetoothGATTWriteDescriptorRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) {
@@ -2714,8 +2654,6 @@ void BluetoothGATTWriteDescriptorRequest::decode_field(uint32_t tag, const uint8
this->data = value.data();
this->data_len = value.size();
break;
default:
break;
}
}
void BluetoothGATTNotifyRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) {
@@ -2730,8 +2668,6 @@ void BluetoothGATTNotifyRequest::decode_field(uint32_t tag, const uint8_t *data,
case proto_tag(3, WIRE_TYPE_VARINT):
this->enable = value.as_bool();
break;
default:
break;
}
}
uint8_t *BluetoothGATTNotifyDataResponse::encode_msg(const void *self,
@@ -2896,8 +2832,6 @@ void BluetoothScannerSetModeRequest::decode_field(uint32_t tag, const uint8_t *d
case proto_tag(1, WIRE_TYPE_VARINT):
this->mode = static_cast<enums::BluetoothScannerMode>(value.as_varint());
break;
default:
break;
}
}
#endif
@@ -2911,8 +2845,6 @@ void SubscribeVoiceAssistantRequest::decode_field(uint32_t tag, const uint8_t *d
case proto_tag(2, WIRE_TYPE_VARINT):
this->flags = value.as_varint();
break;
default:
break;
}
}
uint8_t *VoiceAssistantAudioSettings::encode_msg(const void *self, ProtoWriteBuffer &buffer PROTO_ENCODE_DEBUG_PARAM) {
@@ -2962,20 +2894,16 @@ void VoiceAssistantResponse::decode_field(uint32_t tag, const uint8_t *data, pro
case proto_tag(2, WIRE_TYPE_VARINT):
this->error = value.as_bool();
break;
default:
break;
}
}
void VoiceAssistantEventData::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) {
const ProtoFieldValue value(data, scalar);
switch (tag) {
case proto_tag(1, WIRE_TYPE_LENGTH_DELIMITED):
this->name = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->name = StringRef(value.data(), value.size());
break;
case proto_tag(2, WIRE_TYPE_LENGTH_DELIMITED):
this->value = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
break;
default:
this->value = StringRef(value.data(), value.size());
break;
}
}
@@ -2989,8 +2917,6 @@ void VoiceAssistantEventResponse::decode_field(uint32_t tag, const uint8_t *data
this->data.emplace_back();
value.decode_to_message(this->data.back());
break;
default:
break;
}
}
void VoiceAssistantAudio::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) {
@@ -3007,8 +2933,6 @@ void VoiceAssistantAudio::decode_field(uint32_t tag, const uint8_t *data, proto_
this->data2 = value.data();
this->data2_len = value.size();
break;
default:
break;
}
}
uint8_t *VoiceAssistantAudio::encode_msg(const void *self, ProtoWriteBuffer &buffer PROTO_ENCODE_DEBUG_PARAM) {
@@ -3034,10 +2958,10 @@ void VoiceAssistantTimerEventResponse::decode_field(uint32_t tag, const uint8_t
this->event_type = static_cast<enums::VoiceAssistantTimerEvent>(value.as_varint());
break;
case proto_tag(2, WIRE_TYPE_LENGTH_DELIMITED):
this->timer_id = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->timer_id = StringRef(value.data(), value.size());
break;
case proto_tag(3, WIRE_TYPE_LENGTH_DELIMITED):
this->name = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->name = StringRef(value.data(), value.size());
break;
case proto_tag(4, WIRE_TYPE_VARINT):
this->total_seconds = value.as_varint();
@@ -3048,27 +2972,23 @@ void VoiceAssistantTimerEventResponse::decode_field(uint32_t tag, const uint8_t
case proto_tag(6, WIRE_TYPE_VARINT):
this->is_active = value.as_bool();
break;
default:
break;
}
}
void VoiceAssistantAnnounceRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) {
const ProtoFieldValue value(data, scalar);
switch (tag) {
case proto_tag(1, WIRE_TYPE_LENGTH_DELIMITED):
this->media_id = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->media_id = StringRef(value.data(), value.size());
break;
case proto_tag(2, WIRE_TYPE_LENGTH_DELIMITED):
this->text = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->text = StringRef(value.data(), value.size());
break;
case proto_tag(3, WIRE_TYPE_LENGTH_DELIMITED):
this->preannounce_media_id = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->preannounce_media_id = StringRef(value.data(), value.size());
break;
case proto_tag(4, WIRE_TYPE_VARINT):
this->start_conversation = value.as_bool();
break;
default:
break;
}
}
uint8_t *VoiceAssistantAnnounceFinished::encode_msg(const void *self,
@@ -3110,27 +3030,25 @@ void VoiceAssistantExternalWakeWord::decode_field(uint32_t tag, const uint8_t *d
const ProtoFieldValue value(data, scalar);
switch (tag) {
case proto_tag(1, WIRE_TYPE_LENGTH_DELIMITED):
this->id = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->id = StringRef(value.data(), value.size());
break;
case proto_tag(2, WIRE_TYPE_LENGTH_DELIMITED):
this->wake_word = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->wake_word = StringRef(value.data(), value.size());
break;
case proto_tag(3, WIRE_TYPE_LENGTH_DELIMITED):
this->trained_languages.push_back(value.as_string());
break;
case proto_tag(4, WIRE_TYPE_LENGTH_DELIMITED):
this->model_type = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->model_type = StringRef(value.data(), value.size());
break;
case proto_tag(5, WIRE_TYPE_VARINT):
this->model_size = value.as_varint();
break;
case proto_tag(6, WIRE_TYPE_LENGTH_DELIMITED):
this->model_hash = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->model_hash = StringRef(value.data(), value.size());
break;
case proto_tag(7, WIRE_TYPE_LENGTH_DELIMITED):
this->url = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
break;
default:
this->url = StringRef(value.data(), value.size());
break;
}
}
@@ -3141,8 +3059,6 @@ void VoiceAssistantConfigurationRequest::decode_field(uint32_t tag, const uint8_
this->external_wake_words.emplace_back();
value.decode_to_message(this->external_wake_words.back());
break;
default:
break;
}
}
uint8_t *VoiceAssistantConfigurationResponse::encode_msg(const void *self,
@@ -3180,8 +3096,6 @@ void VoiceAssistantSetConfiguration::decode_field(uint32_t tag, const uint8_t *d
case proto_tag(1, WIRE_TYPE_LENGTH_DELIMITED):
this->active_wake_words.push_back(value.as_string());
break;
default:
break;
}
}
#endif
@@ -3256,15 +3170,13 @@ void AlarmControlPanelCommandRequest::decode_field(uint32_t tag, const uint8_t *
this->command = static_cast<enums::AlarmControlPanelStateCommand>(value.as_varint());
break;
case proto_tag(3, WIRE_TYPE_LENGTH_DELIMITED):
this->code = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->code = StringRef(value.data(), value.size());
break;
#ifdef USE_DEVICES
case proto_tag(4, WIRE_TYPE_VARINT):
this->device_id = value.as_varint();
break;
#endif
default:
break;
}
}
#endif
@@ -3338,15 +3250,13 @@ void TextCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_v
this->key = value.as_fixed32();
break;
case proto_tag(2, WIRE_TYPE_LENGTH_DELIMITED):
this->state = StringRef(reinterpret_cast<const char *>(value.data()), value.size());
this->state = StringRef(value.data(), value.size());
break;
#ifdef USE_DEVICES
case proto_tag(3, WIRE_TYPE_VARINT):
this->device_id = value.as_varint();
break;
#endif
default:
break;
}
}
#endif
@@ -3429,8 +3339,6 @@ void DateCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_v
this->device_id = value.as_varint();
break;
#endif
default:
break;
}
}
#endif
@@ -3513,8 +3421,6 @@ void TimeCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_v
this->device_id = value.as_varint();
break;
#endif
default:
break;
}
}
#endif
@@ -3667,8 +3573,6 @@ void ValveCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_
this->device_id = value.as_varint();
break;
#endif
default:
break;
}
}
#endif
@@ -3743,8 +3647,6 @@ void DateTimeCommandRequest::decode_field(uint32_t tag, const uint8_t *data, pro
this->device_id = value.as_varint();
break;
#endif
default:
break;
}
}
#endif
@@ -3835,8 +3737,6 @@ void UpdateCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto
this->device_id = value.as_varint();
break;
#endif
default:
break;
}
}
#endif
@@ -3848,8 +3748,6 @@ void ZWaveProxyFrame::decode_field(uint32_t tag, const uint8_t *data, proto_vari
this->data = value.data();
this->data_len = value.size();
break;
default:
break;
}
}
__attribute__((optimize("O2"))) // NOLINT(clang-diagnostic-unknown-attributes)
@@ -3878,8 +3776,6 @@ void ZWaveProxyRequest::decode_field(uint32_t tag, const uint8_t *data, proto_va
this->data = value.data();
this->data_len = value.size();
break;
default:
break;
}
}
uint8_t *ZWaveProxyRequest::encode_msg(const void *self, ProtoWriteBuffer &buffer PROTO_ENCODE_DEBUG_PARAM) {
@@ -3975,8 +3871,6 @@ void InfraredRFTransmitRawTimingsRequest::decode_field(uint32_t tag, const uint8
case proto_tag(6, WIRE_TYPE_VARINT):
this->modulation = value.as_varint();
break;
default:
break;
}
}
__attribute__((optimize("O2"))) // NOLINT(clang-diagnostic-unknown-attributes)
@@ -4075,8 +3969,6 @@ void SerialProxyConfigureRequest::decode_field(uint32_t tag, const uint8_t *data
case proto_tag(6, WIRE_TYPE_VARINT):
this->data_size = value.as_varint();
break;
default:
break;
}
}
__attribute__((optimize("O2"))) // NOLINT(clang-diagnostic-unknown-attributes)
@@ -4107,8 +3999,6 @@ void SerialProxyWriteRequest::decode_field(uint32_t tag, const uint8_t *data, pr
this->data = value.data();
this->data_len = value.size();
break;
default:
break;
}
}
void SerialProxySetModemPinsRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) {
@@ -4120,8 +4010,6 @@ void SerialProxySetModemPinsRequest::decode_field(uint32_t tag, const uint8_t *d
case proto_tag(2, WIRE_TYPE_VARINT):
this->line_states = value.as_varint();
break;
default:
break;
}
}
void SerialProxyGetModemPinsRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) {
@@ -4130,8 +4018,6 @@ void SerialProxyGetModemPinsRequest::decode_field(uint32_t tag, const uint8_t *d
case proto_tag(1, WIRE_TYPE_VARINT):
this->instance = value.as_varint();
break;
default:
break;
}
}
uint8_t *SerialProxyGetModemPinsResponse::encode_msg(const void *self,
@@ -4160,8 +4046,6 @@ void SerialProxyRequest::decode_field(uint32_t tag, const uint8_t *data, proto_v
case proto_tag(2, WIRE_TYPE_VARINT):
this->type = static_cast<enums::SerialProxyRequestType>(value.as_varint());
break;
default:
break;
}
}
uint8_t *SerialProxyRequestResponse::encode_msg(const void *self, ProtoWriteBuffer &buffer PROTO_ENCODE_DEBUG_PARAM) {
@@ -4202,8 +4086,6 @@ void BluetoothSetConnectionParamsRequest::decode_field(uint32_t tag, const uint8
case proto_tag(5, WIRE_TYPE_VARINT):
this->timeout = value.as_varint();
break;
default:
break;
}
}
uint8_t *BluetoothSetConnectionParamsResponse::encode_msg(const void *self,
+3 -4
View File
@@ -255,7 +255,7 @@ class ProtoWriteBuffer {
*
* Following https://protobuf.dev/programming-guides/encoding/#structure
*/
void encode_field_raw(uint32_t field_id, uint32_t type) { this->encode_varint_raw((field_id << 3) | type); }
void encode_field_raw(uint32_t field_id, uint32_t type) { this->encode_varint_raw(proto_tag(field_id, type)); }
/// Single-pass encode for repeated submessage elements.
/// Thin template wrapper; all buffer work is in the non-template core.
template<typename T> void encode_sub_message(uint32_t field_id, const T &value);
@@ -385,7 +385,7 @@ class ProtoEncode {
}
[[nodiscard]] static inline uint8_t *ESPHOME_ALWAYS_INLINE
encode_field_raw(uint8_t *__restrict__ pos PROTO_ENCODE_DEBUG_PARAM, uint32_t field_id, uint32_t type) {
return encode_varint_raw(pos PROTO_ENCODE_DEBUG_ARG, (field_id << 3) | type);
return encode_varint_raw(pos PROTO_ENCODE_DEBUG_ARG, proto_tag(field_id, type));
}
/// Write a single precomputed tag byte. Tag must be < 128.
[[nodiscard]] static inline uint8_t *ESPHOME_ALWAYS_INLINE
@@ -734,7 +734,6 @@ class ProtoDecodableMessage : public ProtoMessage {
/// Store one decoded field; \p scalar is the varint or fixed32 value, or the length of the
/// length-delimited payload at \p data. An unknown field or wrong wire type matches no case and is skipped.
/// Three register arguments keep the decode loop free of spills.
// NOTE: wire type 1 (64-bit fixed) is not supported
virtual void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) {}
};
@@ -861,7 +860,7 @@ class ProtoSize {
* @return The number of bytes needed to encode the field ID and wire type
*/
static constexpr uint32_t field(uint32_t field_id, uint32_t type) {
uint32_t tag = (field_id << 3) | (type & WIRE_TYPE_MASK);
uint32_t tag = proto_tag(field_id, type & WIRE_TYPE_MASK);
return varint(tag);
}
+26 -43
View File
@@ -321,11 +321,12 @@ class TypeInfo(ABC):
)
)
def _encode_fixed32_with_precomputed_tag(self, value_expr: str) -> str | None:
"""Single-byte tag fixed32 write, or None for multi-byte tags."""
def _encode_fixed32_with_precomputed_tag(self, value: str) -> str | None:
"""Single-byte tag fixed32 write, or None for other types and multi-byte tags."""
tag = self.calculate_tag()
if tag >= 128:
if self.fixed32_value_template is None or tag >= 128:
return None
value_expr = self.fixed32_value_template.format(value=value)
if self.force:
return _encode_call("write_tag_and_fixed32", str(tag), value_expr)
return (
@@ -339,14 +340,14 @@ class TypeInfo(ABC):
value = f"this->{self.field_name}"
if result := self._encode_with_precomputed_tag(value):
return result
if self.fixed32_value_template is not None and (
result := self._encode_fixed32_with_precomputed_tag(
self.fixed32_value_template.format(value=value)
)
):
if result := self._encode_fixed32_with_precomputed_tag(value):
return result
return _encode_call(self.encode_func, str(self.number), value, force=self.force)
def encode_element(self, number: int, element: str) -> str:
"""Encode one element of a repeated field; elements are always written."""
return _encode_call(self.encode_func, str(number), element, force=True)
encode_func = None
@classmethod
@@ -939,6 +940,9 @@ class MessageType(TypeInfo):
def can_use_dump_field(cls) -> bool:
return False
def encode_element(self, number: int, element: str) -> str:
return _encode_call("encode_sub_message", "buffer", str(number), element)
@property
def cpp_type(self) -> str:
return self._field.type_name[1:]
@@ -981,7 +985,6 @@ class MessageType(TypeInfo):
@property
def decode_content(self) -> str:
# Custom decode that doesn't use templates
body = f"value.decode_to_message(this->{self.field_name});"
if self._track_presence:
# decode_to_message() cannot report failure, so setting the flag
@@ -1244,7 +1247,7 @@ class PointerToStringBufferType(PointerToBufferTypeBase):
@property
def decode_content(self) -> str:
return self.decode_case(
f"this->{self.field_name} = StringRef(reinterpret_cast<const char *>(value.data()), value.size());",
f"this->{self.field_name} = StringRef(value.data(), value.size());",
)
def dump(self, name: str) -> str:
@@ -1495,6 +1498,14 @@ class UInt32Type(VarintTypeMixin, TypeInfo):
class EnumType(VarintTypeMixin, TypeInfo):
_varint_max_bits = 32
def encode_element(self, number: int, element: str) -> str:
return _encode_call(
self.encode_func,
str(number),
f"static_cast<uint32_t>({element})",
force=True,
)
@property
def cpp_type(self) -> str:
return f"enums::{self._field.type_name[1:]}"
@@ -1774,23 +1785,11 @@ class FixedArrayRepeatedType(TypeInfo):
def _encode_element(self, element: str) -> str:
"""Helper to generate encode statement for a single element."""
if isinstance(self._ti, EnumType):
return _encode_call(
self._ti.encode_func,
str(self.number),
f"static_cast<uint32_t>({element})",
force=True,
if isinstance(self._ti, MessageType) and _is_inline_encode(self._ti.cpp_type):
return _generate_inline_encode_block(
self.number, self._ti.cpp_type, element
)
# Repeated message elements use encode_sub_message (force=true is default)
if isinstance(self._ti, MessageType):
if _is_inline_encode(self._ti.cpp_type):
return _generate_inline_encode_block(
self.number, self._ti.cpp_type, element
)
return _encode_call(
"encode_sub_message", "buffer", str(self.number), element
)
return _encode_call(self._ti.encode_func, str(self.number), element, force=True)
return self._ti.encode_element(self.number, element)
@property
def cpp_type(self) -> str:
@@ -2096,7 +2095,6 @@ class RepeatedTypeInfo(TypeInfo):
if self._use_pointer:
return None
if isinstance(self._ti, MessageType):
# Special handling for non-template message decoding
return self.decode_case(
f"this->{self.field_name}.emplace_back();\n"
f"value.decode_to_message(this->{self.field_name}.back());"
@@ -2109,20 +2107,7 @@ class RepeatedTypeInfo(TypeInfo):
return isinstance(self._ti, BoolType)
def _encode_element_call(self, element: str) -> str:
"""Helper to generate encode call for a single element."""
if isinstance(self._ti, EnumType):
return _encode_call(
self._ti.encode_func,
str(self.number),
f"static_cast<uint32_t>({element})",
force=True,
)
# Repeated message elements use encode_sub_message (force=true is default)
if isinstance(self._ti, MessageType):
return _encode_call(
"encode_sub_message", "buffer", str(self.number), element
)
return _encode_call(self._ti.encode_func, str(self.number), element, force=True)
return self._ti.encode_element(self.number, element)
@property
def encode_content(self) -> str:
@@ -2662,8 +2647,6 @@ def build_message_type(
o += " const ProtoFieldValue value(data, scalar);\n"
o += " switch (tag) {\n"
o += indent("\n".join(decode), " ") + "\n"
o += " default:\n"
o += " break;\n"
o += " }\n"
o += "}\n"
cpp += o
@@ -249,7 +249,7 @@ static APIBuffer build_infrared_rf_transmit_wire() {
std::memcpy(bytes + len, packed, packed_len);
len += packed_len;
// field 6: modulation = 1 (non-zero so it's actually emitted and exercises
// decode_varint for this field, matching the documented layout above).
// decode_field for this field, matching the documented layout above).
put_byte(0x30);
put_varint(1);
@@ -225,7 +225,6 @@ def test_message_gets_a_single_decode_field_override() -> None:
header, cpp, _ = build_message_type(desc, {}, {"Mixed": SOURCE_CLIENT})
decl = "void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override;"
assert header.count(decl) == 1
assert "decode_varint" not in header and "decode_length" not in header
assert (
cpp.count(
"void Mixed::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) {"