From 0e3554f6f8aa3637a13671b45e1a18f279e03ee0 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 8 Sep 2026 02:32:35 +0200 Subject: [PATCH] [api] Decode without a vtable decode_field() becomes a static per message function and the generated decode() hands it to the shared loop as a function pointer, so decodable messages carry no vtable and no vptr store at every construction site. The loop loses the two vtable loads per field. The protected destructor on ProtoDecodableMessage goes with the virtuals; ProtoMessage keeps its own guard for the dump builds that still have them. --- esphome/components/api/api_pb2.cpp | 756 ++++++++++-------- esphome/components/api/api_pb2.h | 289 +++++-- esphome/components/api/proto.cpp | 4 +- esphome/components/api/proto.h | 17 +- script/api_protobuf/api_protobuf.py | 17 +- .../api/test_api_protobuf_generator.py | 4 +- 6 files changed, 675 insertions(+), 412 deletions(-) diff --git a/esphome/components/api/api_pb2.cpp b/esphome/components/api/api_pb2.cpp index 53bafcde37..d0aff048f8 100644 --- a/esphome/components/api/api_pb2.cpp +++ b/esphome/components/api/api_pb2.cpp @@ -7,17 +7,18 @@ namespace esphome::api { -void HelloRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void HelloRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_LENGTH_DELIMITED): - this->client_info = StringRef(value.data(), value.size()); + msg.client_info = StringRef(value.data(), value.size()); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->api_version_major = value.as_varint(); + msg.api_version_major = value.as_varint(); break; case proto_tag(3, WIRE_TYPE_VARINT): - this->api_version_minor = value.as_varint(); + msg.api_version_minor = value.as_varint(); break; } } @@ -39,11 +40,12 @@ uint32_t HelloResponse::calc_size_msg(const void *self) { size += 2 + msg.name.size(); return size; } -void DisconnectRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void DisconnectRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->reason = static_cast(value.as_varint()); + msg.reason = static_cast(value.as_varint()); break; } } @@ -459,30 +461,31 @@ uint32_t CoverStateResponse::calc_size_msg(const void *self) { #endif return size; } -void CoverCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void CoverCommandRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_FIXED32): - this->key = value.as_fixed32(); + msg.key = value.as_fixed32(); break; case proto_tag(4, WIRE_TYPE_VARINT): - this->has_position = value.as_bool(); + msg.has_position = value.as_bool(); break; case proto_tag(5, WIRE_TYPE_FIXED32): - this->position = value.as_float(); + msg.position = value.as_float(); break; case proto_tag(6, WIRE_TYPE_VARINT): - this->has_tilt = value.as_bool(); + msg.has_tilt = value.as_bool(); break; case proto_tag(7, WIRE_TYPE_FIXED32): - this->tilt = value.as_float(); + msg.tilt = value.as_float(); break; case proto_tag(8, WIRE_TYPE_VARINT): - this->stop = value.as_bool(); + msg.stop = value.as_bool(); break; #ifdef USE_DEVICES case proto_tag(9, WIRE_TYPE_VARINT): - this->device_id = value.as_varint(); + msg.device_id = value.as_varint(); break; #endif } @@ -565,45 +568,46 @@ uint32_t FanStateResponse::calc_size_msg(const void *self) { #endif return size; } -void FanCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void FanCommandRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_FIXED32): - this->key = value.as_fixed32(); + msg.key = value.as_fixed32(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->has_state = value.as_bool(); + msg.has_state = value.as_bool(); break; case proto_tag(3, WIRE_TYPE_VARINT): - this->state = value.as_bool(); + msg.state = value.as_bool(); break; case proto_tag(6, WIRE_TYPE_VARINT): - this->has_oscillating = value.as_bool(); + msg.has_oscillating = value.as_bool(); break; case proto_tag(7, WIRE_TYPE_VARINT): - this->oscillating = value.as_bool(); + msg.oscillating = value.as_bool(); break; case proto_tag(8, WIRE_TYPE_VARINT): - this->has_direction = value.as_bool(); + msg.has_direction = value.as_bool(); break; case proto_tag(9, WIRE_TYPE_VARINT): - this->direction = static_cast(value.as_varint()); + msg.direction = static_cast(value.as_varint()); break; case proto_tag(10, WIRE_TYPE_VARINT): - this->has_speed_level = value.as_bool(); + msg.has_speed_level = value.as_bool(); break; case proto_tag(11, WIRE_TYPE_VARINT): - this->speed_level = static_cast(value.as_varint()); + msg.speed_level = static_cast(value.as_varint()); break; case proto_tag(12, WIRE_TYPE_VARINT): - this->has_preset_mode = value.as_bool(); + msg.has_preset_mode = value.as_bool(); break; case proto_tag(13, WIRE_TYPE_LENGTH_DELIMITED): - this->preset_mode = StringRef(value.data(), value.size()); + msg.preset_mode = StringRef(value.data(), value.size()); break; #ifdef USE_DEVICES case proto_tag(14, WIRE_TYPE_VARINT): - this->device_id = value.as_varint(); + msg.device_id = value.as_varint(); break; #endif } @@ -724,93 +728,94 @@ uint32_t LightStateResponse::calc_size_msg(const void *self) { #endif return size; } -void LightCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void LightCommandRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_FIXED32): - this->key = value.as_fixed32(); + msg.key = value.as_fixed32(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->has_state = value.as_bool(); + msg.has_state = value.as_bool(); break; case proto_tag(3, WIRE_TYPE_VARINT): - this->state = value.as_bool(); + msg.state = value.as_bool(); break; case proto_tag(4, WIRE_TYPE_VARINT): - this->has_brightness = value.as_bool(); + msg.has_brightness = value.as_bool(); break; case proto_tag(5, WIRE_TYPE_FIXED32): - this->brightness = value.as_float(); + msg.brightness = value.as_float(); break; case proto_tag(22, WIRE_TYPE_VARINT): - this->has_color_mode = value.as_bool(); + msg.has_color_mode = value.as_bool(); break; case proto_tag(23, WIRE_TYPE_VARINT): - this->color_mode = static_cast(value.as_varint()); + msg.color_mode = static_cast(value.as_varint()); break; case proto_tag(20, WIRE_TYPE_VARINT): - this->has_color_brightness = value.as_bool(); + msg.has_color_brightness = value.as_bool(); break; case proto_tag(21, WIRE_TYPE_FIXED32): - this->color_brightness = value.as_float(); + msg.color_brightness = value.as_float(); break; case proto_tag(6, WIRE_TYPE_VARINT): - this->has_rgb = value.as_bool(); + msg.has_rgb = value.as_bool(); break; case proto_tag(7, WIRE_TYPE_FIXED32): - this->red = value.as_float(); + msg.red = value.as_float(); break; case proto_tag(8, WIRE_TYPE_FIXED32): - this->green = value.as_float(); + msg.green = value.as_float(); break; case proto_tag(9, WIRE_TYPE_FIXED32): - this->blue = value.as_float(); + msg.blue = value.as_float(); break; case proto_tag(10, WIRE_TYPE_VARINT): - this->has_white = value.as_bool(); + msg.has_white = value.as_bool(); break; case proto_tag(11, WIRE_TYPE_FIXED32): - this->white = value.as_float(); + msg.white = value.as_float(); break; case proto_tag(12, WIRE_TYPE_VARINT): - this->has_color_temperature = value.as_bool(); + msg.has_color_temperature = value.as_bool(); break; case proto_tag(13, WIRE_TYPE_FIXED32): - this->color_temperature = value.as_float(); + msg.color_temperature = value.as_float(); break; case proto_tag(24, WIRE_TYPE_VARINT): - this->has_cold_white = value.as_bool(); + msg.has_cold_white = value.as_bool(); break; case proto_tag(25, WIRE_TYPE_FIXED32): - this->cold_white = value.as_float(); + msg.cold_white = value.as_float(); break; case proto_tag(26, WIRE_TYPE_VARINT): - this->has_warm_white = value.as_bool(); + msg.has_warm_white = value.as_bool(); break; case proto_tag(27, WIRE_TYPE_FIXED32): - this->warm_white = value.as_float(); + msg.warm_white = value.as_float(); break; case proto_tag(14, WIRE_TYPE_VARINT): - this->has_transition_length = value.as_bool(); + msg.has_transition_length = value.as_bool(); break; case proto_tag(15, WIRE_TYPE_VARINT): - this->transition_length = value.as_varint(); + msg.transition_length = value.as_varint(); break; case proto_tag(16, WIRE_TYPE_VARINT): - this->has_flash_length = value.as_bool(); + msg.has_flash_length = value.as_bool(); break; case proto_tag(17, WIRE_TYPE_VARINT): - this->flash_length = value.as_varint(); + msg.flash_length = value.as_varint(); break; case proto_tag(18, WIRE_TYPE_VARINT): - this->has_effect = value.as_bool(); + msg.has_effect = value.as_bool(); break; case proto_tag(19, WIRE_TYPE_LENGTH_DELIMITED): - this->effect = StringRef(value.data(), value.size()); + msg.effect = StringRef(value.data(), value.size()); break; #ifdef USE_DEVICES case proto_tag(28, WIRE_TYPE_VARINT): - this->device_id = value.as_varint(); + msg.device_id = value.as_varint(); break; #endif } @@ -945,18 +950,19 @@ uint32_t SwitchStateResponse::calc_size_msg(const void *self) { #endif return size; } -void SwitchCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void SwitchCommandRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_FIXED32): - this->key = value.as_fixed32(); + msg.key = value.as_fixed32(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->state = value.as_bool(); + msg.state = value.as_bool(); break; #ifdef USE_DEVICES case proto_tag(3, WIRE_TYPE_VARINT): - this->device_id = value.as_varint(); + msg.device_id = value.as_varint(); break; #endif } @@ -1021,14 +1027,15 @@ uint32_t TextSensorStateResponse::calc_size_msg(const void *self) { return size; } #endif -void SubscribeLogsRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void SubscribeLogsRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->level = static_cast(value.as_varint()); + msg.level = static_cast(value.as_varint()); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->dump_config = value.as_bool(); + msg.dump_config = value.as_bool(); break; } } @@ -1053,12 +1060,14 @@ SubscribeLogsResponse::calc_size_msg(const void *self) { return size; } #ifdef USE_API_NOISE -void NoiseEncryptionSetKeyRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void NoiseEncryptionSetKeyRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_LENGTH_DELIMITED): - this->key = value.data(); - this->key_len = value.size(); + msg.key = value.data(); + msg.key_len = value.size(); break; } } @@ -1149,22 +1158,24 @@ uint32_t HomeassistantActionRequest::calc_size_msg(const void *self) { } #endif #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES -void HomeassistantActionResponse::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void HomeassistantActionResponse::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->call_id = value.as_varint(); + msg.call_id = value.as_varint(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->success = value.as_bool(); + msg.success = value.as_bool(); break; case proto_tag(3, WIRE_TYPE_LENGTH_DELIMITED): - this->error_message = StringRef(value.data(), value.size()); + msg.error_message = StringRef(value.data(), value.size()); break; #ifdef USE_API_HOMEASSISTANT_ACTION_RESPONSES_JSON case proto_tag(4, WIRE_TYPE_LENGTH_DELIMITED): - this->response_data = value.data(); - this->response_data_len = value.size(); + msg.response_data = value.data(); + msg.response_data_len = value.size(); break; #endif } @@ -1188,70 +1199,75 @@ uint32_t SubscribeHomeAssistantStateResponse::calc_size_msg(const void *self) { size += ProtoSize::calc_bool(1, msg.once); return size; } -void HomeAssistantStateResponse::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void HomeAssistantStateResponse::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_LENGTH_DELIMITED): - this->entity_id = StringRef(value.data(), value.size()); + msg.entity_id = StringRef(value.data(), value.size()); break; case proto_tag(2, WIRE_TYPE_LENGTH_DELIMITED): - this->state = StringRef(value.data(), value.size()); + msg.state = StringRef(value.data(), value.size()); break; case proto_tag(3, WIRE_TYPE_LENGTH_DELIMITED): - this->attribute = StringRef(value.data(), value.size()); + msg.attribute = StringRef(value.data(), value.size()); break; } } #endif -void DSTRule::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void DSTRule::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->time_seconds = decode_zigzag32(static_cast(value.as_varint())); + msg.time_seconds = decode_zigzag32(static_cast(value.as_varint())); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->day = value.as_varint(); + msg.day = value.as_varint(); break; case proto_tag(3, WIRE_TYPE_VARINT): - this->type = static_cast(value.as_varint()); + msg.type = static_cast(value.as_varint()); break; case proto_tag(4, WIRE_TYPE_VARINT): - this->month = value.as_varint(); + msg.month = value.as_varint(); break; case proto_tag(5, WIRE_TYPE_VARINT): - this->week = value.as_varint(); + msg.week = value.as_varint(); break; case proto_tag(6, WIRE_TYPE_VARINT): - this->day_of_week = value.as_varint(); + msg.day_of_week = value.as_varint(); break; } } -void ParsedTimezone::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void ParsedTimezone::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->std_offset_seconds = decode_zigzag32(static_cast(value.as_varint())); + msg.std_offset_seconds = decode_zigzag32(static_cast(value.as_varint())); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->dst_offset_seconds = decode_zigzag32(static_cast(value.as_varint())); + msg.dst_offset_seconds = decode_zigzag32(static_cast(value.as_varint())); break; case proto_tag(3, WIRE_TYPE_LENGTH_DELIMITED): - value.decode_to_message(this->dst_start); + value.decode_to_message(msg.dst_start); break; case proto_tag(4, WIRE_TYPE_LENGTH_DELIMITED): - value.decode_to_message(this->dst_end); + value.decode_to_message(msg.dst_end); break; } } -void GetTimeResponse::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void GetTimeResponse::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_FIXED32): - this->epoch_seconds = value.as_fixed32(); + msg.epoch_seconds = value.as_fixed32(); break; case proto_tag(3, WIRE_TYPE_LENGTH_DELIMITED): - value.decode_to_message(this->parsed_timezone); - this->has_parsed_timezone = true; + value.decode_to_message(msg.parsed_timezone); + msg.has_parsed_timezone = true; break; } } @@ -1312,35 +1328,36 @@ uint32_t ListEntitiesServicesResponse::calc_size_msg(const void *self) { #endif return size; } -void ExecuteServiceArgument::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void ExecuteServiceArgument::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->bool_ = value.as_bool(); + msg.bool_ = value.as_bool(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->legacy_int = static_cast(value.as_varint()); + msg.legacy_int = static_cast(value.as_varint()); break; case proto_tag(3, WIRE_TYPE_FIXED32): - this->float_ = value.as_float(); + msg.float_ = value.as_float(); break; case proto_tag(4, WIRE_TYPE_LENGTH_DELIMITED): - this->string_ = StringRef(value.data(), value.size()); + msg.string_ = StringRef(value.data(), value.size()); break; case proto_tag(5, WIRE_TYPE_VARINT): - this->int_ = decode_zigzag32(static_cast(value.as_varint())); + msg.int_ = decode_zigzag32(static_cast(value.as_varint())); break; case proto_tag(6, WIRE_TYPE_VARINT): - this->bool_array.push_back(value.as_bool()); + msg.bool_array.push_back(value.as_bool()); break; case proto_tag(7, WIRE_TYPE_VARINT): - this->int_array.push_back(decode_zigzag32(static_cast(value.as_varint()))); + msg.int_array.push_back(decode_zigzag32(static_cast(value.as_varint()))); break; case proto_tag(8, WIRE_TYPE_FIXED32): - this->float_array.push_back(value.as_float()); + msg.float_array.push_back(value.as_float()); break; case proto_tag(9, WIRE_TYPE_LENGTH_DELIMITED): - this->string_array.push_back(value.as_string()); + msg.string_array.push_back(value.as_string()); break; } } @@ -1353,26 +1370,27 @@ void ExecuteServiceArgument::decode(const uint8_t *buffer, size_t length) { this->float_array.init(count_float_array); uint32_t count_string_array = ProtoDecodableMessage::count_repeated_field(buffer, length, 9); this->string_array.init(count_string_array); - ProtoDecodableMessage::decode(buffer, length); + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); } -void ExecuteServiceRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void ExecuteServiceRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_FIXED32): - this->key = value.as_fixed32(); + msg.key = value.as_fixed32(); break; case proto_tag(2, WIRE_TYPE_LENGTH_DELIMITED): - this->args.emplace_back(); - value.decode_to_message(this->args.back()); + msg.args.emplace_back(); + value.decode_to_message(msg.args.back()); break; #ifdef USE_API_USER_DEFINED_ACTION_RESPONSES case proto_tag(3, WIRE_TYPE_VARINT): - this->call_id = value.as_varint(); + msg.call_id = value.as_varint(); break; #endif #ifdef USE_API_USER_DEFINED_ACTION_RESPONSES case proto_tag(4, WIRE_TYPE_VARINT): - this->return_response = value.as_bool(); + msg.return_response = value.as_bool(); break; #endif } @@ -1380,7 +1398,7 @@ void ExecuteServiceRequest::decode_field(uint32_t tag, const uint8_t *data, prot void ExecuteServiceRequest::decode(const uint8_t *buffer, size_t length) { uint32_t count_args = ProtoDecodableMessage::count_repeated_field(buffer, length, 2); this->args.init(count_args); - ProtoDecodableMessage::decode(buffer, length); + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); } #endif #ifdef USE_API_USER_DEFINED_ACTION_RESPONSES @@ -1462,14 +1480,15 @@ uint32_t CameraImageResponse::calc_size_msg(const void *self) { #endif return size; } -void CameraImageRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void CameraImageRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->single = value.as_bool(); + msg.single = value.as_bool(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->stream = value.as_bool(); + msg.stream = value.as_bool(); break; } } @@ -1635,75 +1654,76 @@ uint32_t ClimateStateResponse::calc_size_msg(const void *self) { #endif return size; } -void ClimateCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void ClimateCommandRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_FIXED32): - this->key = value.as_fixed32(); + msg.key = value.as_fixed32(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->has_mode = value.as_bool(); + msg.has_mode = value.as_bool(); break; case proto_tag(3, WIRE_TYPE_VARINT): - this->mode = static_cast(value.as_varint()); + msg.mode = static_cast(value.as_varint()); break; case proto_tag(4, WIRE_TYPE_VARINT): - this->has_target_temperature = value.as_bool(); + msg.has_target_temperature = value.as_bool(); break; case proto_tag(5, WIRE_TYPE_FIXED32): - this->target_temperature = value.as_float(); + msg.target_temperature = value.as_float(); break; case proto_tag(6, WIRE_TYPE_VARINT): - this->has_target_temperature_low = value.as_bool(); + msg.has_target_temperature_low = value.as_bool(); break; case proto_tag(7, WIRE_TYPE_FIXED32): - this->target_temperature_low = value.as_float(); + msg.target_temperature_low = value.as_float(); break; case proto_tag(8, WIRE_TYPE_VARINT): - this->has_target_temperature_high = value.as_bool(); + msg.has_target_temperature_high = value.as_bool(); break; case proto_tag(9, WIRE_TYPE_FIXED32): - this->target_temperature_high = value.as_float(); + msg.target_temperature_high = value.as_float(); break; case proto_tag(12, WIRE_TYPE_VARINT): - this->has_fan_mode = value.as_bool(); + msg.has_fan_mode = value.as_bool(); break; case proto_tag(13, WIRE_TYPE_VARINT): - this->fan_mode = static_cast(value.as_varint()); + msg.fan_mode = static_cast(value.as_varint()); break; case proto_tag(14, WIRE_TYPE_VARINT): - this->has_swing_mode = value.as_bool(); + msg.has_swing_mode = value.as_bool(); break; case proto_tag(15, WIRE_TYPE_VARINT): - this->swing_mode = static_cast(value.as_varint()); + msg.swing_mode = static_cast(value.as_varint()); break; case proto_tag(16, WIRE_TYPE_VARINT): - this->has_custom_fan_mode = value.as_bool(); + msg.has_custom_fan_mode = value.as_bool(); break; case proto_tag(17, WIRE_TYPE_LENGTH_DELIMITED): - this->custom_fan_mode = StringRef(value.data(), value.size()); + msg.custom_fan_mode = StringRef(value.data(), value.size()); break; case proto_tag(18, WIRE_TYPE_VARINT): - this->has_preset = value.as_bool(); + msg.has_preset = value.as_bool(); break; case proto_tag(19, WIRE_TYPE_VARINT): - this->preset = static_cast(value.as_varint()); + msg.preset = static_cast(value.as_varint()); break; case proto_tag(20, WIRE_TYPE_VARINT): - this->has_custom_preset = value.as_bool(); + msg.has_custom_preset = value.as_bool(); break; case proto_tag(21, WIRE_TYPE_LENGTH_DELIMITED): - this->custom_preset = StringRef(value.data(), value.size()); + msg.custom_preset = StringRef(value.data(), value.size()); break; case proto_tag(22, WIRE_TYPE_VARINT): - this->has_target_humidity = value.as_bool(); + msg.has_target_humidity = value.as_bool(); break; case proto_tag(23, WIRE_TYPE_FIXED32): - this->target_humidity = value.as_float(); + msg.target_humidity = value.as_float(); break; #ifdef USE_DEVICES case proto_tag(24, WIRE_TYPE_VARINT): - this->device_id = value.as_varint(); + msg.device_id = value.as_varint(); break; #endif } @@ -1803,34 +1823,36 @@ uint32_t WaterHeaterStateResponse::calc_size_msg(const void *self) { size += ProtoSize::calc_float(1, msg.target_temperature_high); return size; } -void WaterHeaterCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void WaterHeaterCommandRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_FIXED32): - this->key = value.as_fixed32(); + msg.key = value.as_fixed32(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->has_fields = value.as_varint(); + msg.has_fields = value.as_varint(); break; case proto_tag(3, WIRE_TYPE_VARINT): - this->mode = static_cast(value.as_varint()); + msg.mode = static_cast(value.as_varint()); break; case proto_tag(4, WIRE_TYPE_FIXED32): - this->target_temperature = value.as_float(); + msg.target_temperature = value.as_float(); break; #ifdef USE_DEVICES case proto_tag(5, WIRE_TYPE_VARINT): - this->device_id = value.as_varint(); + msg.device_id = value.as_varint(); break; #endif case proto_tag(6, WIRE_TYPE_VARINT): - this->state = value.as_varint(); + msg.state = value.as_varint(); break; case proto_tag(7, WIRE_TYPE_FIXED32): - this->target_temperature_low = value.as_float(); + msg.target_temperature_low = value.as_float(); break; case proto_tag(8, WIRE_TYPE_FIXED32): - this->target_temperature_high = value.as_float(); + msg.target_temperature_high = value.as_float(); break; } } @@ -1910,18 +1932,19 @@ uint32_t NumberStateResponse::calc_size_msg(const void *self) { #endif return size; } -void NumberCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void NumberCommandRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_FIXED32): - this->key = value.as_fixed32(); + msg.key = value.as_fixed32(); break; case proto_tag(2, WIRE_TYPE_FIXED32): - this->state = value.as_float(); + msg.state = value.as_float(); break; #ifdef USE_DEVICES case proto_tag(3, WIRE_TYPE_VARINT): - this->device_id = value.as_varint(); + msg.device_id = value.as_varint(); break; #endif } @@ -1990,18 +2013,19 @@ uint32_t SelectStateResponse::calc_size_msg(const void *self) { #endif return size; } -void SelectCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void SelectCommandRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_FIXED32): - this->key = value.as_fixed32(); + msg.key = value.as_fixed32(); break; case proto_tag(2, WIRE_TYPE_LENGTH_DELIMITED): - this->state = StringRef(value.data(), value.size()); + msg.state = StringRef(value.data(), value.size()); break; #ifdef USE_DEVICES case proto_tag(3, WIRE_TYPE_VARINT): - this->device_id = value.as_varint(); + msg.device_id = value.as_varint(); break; #endif } @@ -2072,39 +2096,40 @@ uint32_t SirenStateResponse::calc_size_msg(const void *self) { #endif return size; } -void SirenCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void SirenCommandRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_FIXED32): - this->key = value.as_fixed32(); + msg.key = value.as_fixed32(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->has_state = value.as_bool(); + msg.has_state = value.as_bool(); break; case proto_tag(3, WIRE_TYPE_VARINT): - this->state = value.as_bool(); + msg.state = value.as_bool(); break; case proto_tag(4, WIRE_TYPE_VARINT): - this->has_tone = value.as_bool(); + msg.has_tone = value.as_bool(); break; case proto_tag(5, WIRE_TYPE_LENGTH_DELIMITED): - this->tone = StringRef(value.data(), value.size()); + msg.tone = StringRef(value.data(), value.size()); break; case proto_tag(6, WIRE_TYPE_VARINT): - this->has_duration = value.as_bool(); + msg.has_duration = value.as_bool(); break; case proto_tag(7, WIRE_TYPE_VARINT): - this->duration = value.as_varint(); + msg.duration = value.as_varint(); break; case proto_tag(8, WIRE_TYPE_VARINT): - this->has_volume = value.as_bool(); + msg.has_volume = value.as_bool(); break; case proto_tag(9, WIRE_TYPE_FIXED32): - this->volume = value.as_float(); + msg.volume = value.as_float(); break; #ifdef USE_DEVICES case proto_tag(10, WIRE_TYPE_VARINT): - this->device_id = value.as_varint(); + msg.device_id = value.as_varint(); break; #endif } @@ -2171,24 +2196,25 @@ uint32_t LockStateResponse::calc_size_msg(const void *self) { #endif return size; } -void LockCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void LockCommandRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_FIXED32): - this->key = value.as_fixed32(); + msg.key = value.as_fixed32(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->command = static_cast(value.as_varint()); + msg.command = static_cast(value.as_varint()); break; case proto_tag(3, WIRE_TYPE_VARINT): - this->has_code = value.as_bool(); + msg.has_code = value.as_bool(); break; case proto_tag(4, WIRE_TYPE_LENGTH_DELIMITED): - this->code = StringRef(value.data(), value.size()); + msg.code = StringRef(value.data(), value.size()); break; #ifdef USE_DEVICES case proto_tag(5, WIRE_TYPE_VARINT): - this->device_id = value.as_varint(); + msg.device_id = value.as_varint(); break; #endif } @@ -2229,15 +2255,16 @@ uint32_t ListEntitiesButtonResponse::calc_size_msg(const void *self) { #endif return size; } -void ButtonCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void ButtonCommandRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_FIXED32): - this->key = value.as_fixed32(); + msg.key = value.as_fixed32(); break; #ifdef USE_DEVICES case proto_tag(2, WIRE_TYPE_VARINT): - this->device_id = value.as_varint(); + msg.device_id = value.as_varint(); break; #endif } @@ -2333,51 +2360,54 @@ uint32_t MediaPlayerStateResponse::calc_size_msg(const void *self) { #endif return size; } -void MediaPlayerCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void MediaPlayerCommandRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_FIXED32): - this->key = value.as_fixed32(); + msg.key = value.as_fixed32(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->has_command = value.as_bool(); + msg.has_command = value.as_bool(); break; case proto_tag(3, WIRE_TYPE_VARINT): - this->command = static_cast(value.as_varint()); + msg.command = static_cast(value.as_varint()); break; case proto_tag(4, WIRE_TYPE_VARINT): - this->has_volume = value.as_bool(); + msg.has_volume = value.as_bool(); break; case proto_tag(5, WIRE_TYPE_FIXED32): - this->volume = value.as_float(); + msg.volume = value.as_float(); break; case proto_tag(6, WIRE_TYPE_VARINT): - this->has_media_url = value.as_bool(); + msg.has_media_url = value.as_bool(); break; case proto_tag(7, WIRE_TYPE_LENGTH_DELIMITED): - this->media_url = StringRef(value.data(), value.size()); + msg.media_url = StringRef(value.data(), value.size()); break; case proto_tag(8, WIRE_TYPE_VARINT): - this->has_announcement = value.as_bool(); + msg.has_announcement = value.as_bool(); break; case proto_tag(9, WIRE_TYPE_VARINT): - this->announcement = value.as_bool(); + msg.announcement = value.as_bool(); break; #ifdef USE_DEVICES case proto_tag(10, WIRE_TYPE_VARINT): - this->device_id = value.as_varint(); + msg.device_id = value.as_varint(); break; #endif } } #endif #ifdef USE_BLUETOOTH_PROXY -void SubscribeBluetoothLEAdvertisementsRequest::decode_field(uint32_t tag, const uint8_t *data, +void SubscribeBluetoothLEAdvertisementsRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->flags = value.as_varint(); + msg.flags = value.as_varint(); break; } } @@ -2423,20 +2453,21 @@ BluetoothLERawAdvertisementsResponse::calc_size_msg(const void *self) { } #endif #ifdef USE_BLUETOOTH_PROXY_CONNECTIONS -void BluetoothDeviceRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void BluetoothDeviceRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->address = value.as_varint(); + msg.address = value.as_varint(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->request_type = static_cast(value.as_varint()); + msg.request_type = static_cast(value.as_varint()); break; case proto_tag(3, WIRE_TYPE_VARINT): - this->has_address_type = value.as_bool(); + msg.has_address_type = value.as_bool(); break; case proto_tag(4, WIRE_TYPE_VARINT): - this->address_type = value.as_varint(); + msg.address_type = value.as_varint(); break; } } @@ -2459,11 +2490,13 @@ uint32_t BluetoothDeviceConnectionResponse::calc_size_msg(const void *self) { size += ProtoSize::calc_int32(1, msg.error); return size; } -void BluetoothGATTGetServicesRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void BluetoothGATTGetServicesRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->address = value.as_varint(); + msg.address = value.as_varint(); break; } } @@ -2585,14 +2618,16 @@ uint32_t BluetoothGATTGetServicesDoneResponse::calc_size_msg(const void *self) { size += ProtoSize::calc_uint64(1, msg.address); return size; } -void BluetoothGATTReadRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void BluetoothGATTReadRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->address = value.as_varint(); + msg.address = value.as_varint(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->handle = value.as_varint(); + msg.handle = value.as_varint(); break; } } @@ -2612,61 +2647,69 @@ uint32_t BluetoothGATTReadResponse::calc_size_msg(const void *self) { size += ProtoSize::calc_length(1, msg.data_len_); return size; } -void BluetoothGATTWriteRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void BluetoothGATTWriteRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->address = value.as_varint(); + msg.address = value.as_varint(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->handle = value.as_varint(); + msg.handle = value.as_varint(); break; case proto_tag(3, WIRE_TYPE_VARINT): - this->response = value.as_bool(); + msg.response = value.as_bool(); break; case proto_tag(4, WIRE_TYPE_LENGTH_DELIMITED): - this->data = value.data(); - this->data_len = value.size(); + msg.data = value.data(); + msg.data_len = value.size(); break; } } -void BluetoothGATTReadDescriptorRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void BluetoothGATTReadDescriptorRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->address = value.as_varint(); + msg.address = value.as_varint(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->handle = value.as_varint(); + msg.handle = value.as_varint(); break; } } -void BluetoothGATTWriteDescriptorRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void BluetoothGATTWriteDescriptorRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->address = value.as_varint(); + msg.address = value.as_varint(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->handle = value.as_varint(); + msg.handle = value.as_varint(); break; case proto_tag(3, WIRE_TYPE_LENGTH_DELIMITED): - this->data = value.data(); - this->data_len = value.size(); + msg.data = value.data(); + msg.data_len = value.size(); break; } } -void BluetoothGATTNotifyRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void BluetoothGATTNotifyRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->address = value.as_varint(); + msg.address = value.as_varint(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->handle = value.as_varint(); + msg.handle = value.as_varint(); break; case proto_tag(3, WIRE_TYPE_VARINT): - this->enable = value.as_bool(); + msg.enable = value.as_bool(); break; } } @@ -2826,24 +2869,28 @@ uint32_t BluetoothScannerStateResponse::calc_size_msg(const void *self) { size += msg.configured_mode ? 2 : 0; return size; } -void BluetoothScannerSetModeRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void BluetoothScannerSetModeRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->mode = static_cast(value.as_varint()); + msg.mode = static_cast(value.as_varint()); break; } } #endif #ifdef USE_VOICE_ASSISTANT -void SubscribeVoiceAssistantRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void SubscribeVoiceAssistantRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->subscribe = value.as_bool(); + msg.subscribe = value.as_bool(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->flags = value.as_varint(); + msg.flags = value.as_varint(); break; } } @@ -2885,53 +2932,58 @@ uint32_t VoiceAssistantRequest::calc_size_msg(const void *self) { size += ProtoSize::calc_length(1, msg.wake_word_phrase.size()); return size; } -void VoiceAssistantResponse::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void VoiceAssistantResponse::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->port = value.as_varint(); + msg.port = value.as_varint(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->error = value.as_bool(); + msg.error = value.as_bool(); break; } } -void VoiceAssistantEventData::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void VoiceAssistantEventData::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_LENGTH_DELIMITED): - this->name = StringRef(value.data(), value.size()); + msg.name = StringRef(value.data(), value.size()); break; case proto_tag(2, WIRE_TYPE_LENGTH_DELIMITED): - this->value = StringRef(value.data(), value.size()); + msg.value = StringRef(value.data(), value.size()); break; } } -void VoiceAssistantEventResponse::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void VoiceAssistantEventResponse::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->event_type = static_cast(value.as_varint()); + msg.event_type = static_cast(value.as_varint()); break; case proto_tag(2, WIRE_TYPE_LENGTH_DELIMITED): - this->data.emplace_back(); - value.decode_to_message(this->data.back()); + msg.data.emplace_back(); + value.decode_to_message(msg.data.back()); break; } } -void VoiceAssistantAudio::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void VoiceAssistantAudio::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_LENGTH_DELIMITED): - this->data = value.data(); - this->data_len = value.size(); + msg.data = value.data(); + msg.data_len = value.size(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->end = value.as_bool(); + msg.end = value.as_bool(); break; case proto_tag(3, WIRE_TYPE_LENGTH_DELIMITED): - this->data2 = value.data(); - this->data2_len = value.size(); + msg.data2 = value.data(); + msg.data2_len = value.size(); break; } } @@ -2951,43 +3003,47 @@ uint32_t VoiceAssistantAudio::calc_size_msg(const void *self) { size += ProtoSize::calc_length(1, msg.data2_len); return size; } -void VoiceAssistantTimerEventResponse::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void VoiceAssistantTimerEventResponse::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->event_type = static_cast(value.as_varint()); + msg.event_type = static_cast(value.as_varint()); break; case proto_tag(2, WIRE_TYPE_LENGTH_DELIMITED): - this->timer_id = StringRef(value.data(), value.size()); + msg.timer_id = StringRef(value.data(), value.size()); break; case proto_tag(3, WIRE_TYPE_LENGTH_DELIMITED): - this->name = StringRef(value.data(), value.size()); + msg.name = StringRef(value.data(), value.size()); break; case proto_tag(4, WIRE_TYPE_VARINT): - this->total_seconds = value.as_varint(); + msg.total_seconds = value.as_varint(); break; case proto_tag(5, WIRE_TYPE_VARINT): - this->seconds_left = value.as_varint(); + msg.seconds_left = value.as_varint(); break; case proto_tag(6, WIRE_TYPE_VARINT): - this->is_active = value.as_bool(); + msg.is_active = value.as_bool(); break; } } -void VoiceAssistantAnnounceRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void VoiceAssistantAnnounceRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_LENGTH_DELIMITED): - this->media_id = StringRef(value.data(), value.size()); + msg.media_id = StringRef(value.data(), value.size()); break; case proto_tag(2, WIRE_TYPE_LENGTH_DELIMITED): - this->text = StringRef(value.data(), value.size()); + msg.text = StringRef(value.data(), value.size()); break; case proto_tag(3, WIRE_TYPE_LENGTH_DELIMITED): - this->preannounce_media_id = StringRef(value.data(), value.size()); + msg.preannounce_media_id = StringRef(value.data(), value.size()); break; case proto_tag(4, WIRE_TYPE_VARINT): - this->start_conversation = value.as_bool(); + msg.start_conversation = value.as_bool(); break; } } @@ -3026,38 +3082,42 @@ uint32_t VoiceAssistantWakeWord::calc_size_msg(const void *self) { } return size; } -void VoiceAssistantExternalWakeWord::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void VoiceAssistantExternalWakeWord::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_LENGTH_DELIMITED): - this->id = StringRef(value.data(), value.size()); + msg.id = StringRef(value.data(), value.size()); break; case proto_tag(2, WIRE_TYPE_LENGTH_DELIMITED): - this->wake_word = StringRef(value.data(), value.size()); + msg.wake_word = StringRef(value.data(), value.size()); break; case proto_tag(3, WIRE_TYPE_LENGTH_DELIMITED): - this->trained_languages.push_back(value.as_string()); + msg.trained_languages.push_back(value.as_string()); break; case proto_tag(4, WIRE_TYPE_LENGTH_DELIMITED): - this->model_type = StringRef(value.data(), value.size()); + msg.model_type = StringRef(value.data(), value.size()); break; case proto_tag(5, WIRE_TYPE_VARINT): - this->model_size = value.as_varint(); + msg.model_size = value.as_varint(); break; case proto_tag(6, WIRE_TYPE_LENGTH_DELIMITED): - this->model_hash = StringRef(value.data(), value.size()); + msg.model_hash = StringRef(value.data(), value.size()); break; case proto_tag(7, WIRE_TYPE_LENGTH_DELIMITED): - this->url = StringRef(value.data(), value.size()); + msg.url = StringRef(value.data(), value.size()); break; } } -void VoiceAssistantConfigurationRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void VoiceAssistantConfigurationRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_LENGTH_DELIMITED): - this->external_wake_words.emplace_back(); - value.decode_to_message(this->external_wake_words.back()); + msg.external_wake_words.emplace_back(); + value.decode_to_message(msg.external_wake_words.back()); break; } } @@ -3090,11 +3150,13 @@ uint32_t VoiceAssistantConfigurationResponse::calc_size_msg(const void *self) { size += ProtoSize::calc_uint32(1, msg.max_active_wake_words); return size; } -void VoiceAssistantSetConfiguration::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void VoiceAssistantSetConfiguration::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_LENGTH_DELIMITED): - this->active_wake_words.push_back(value.as_string()); + msg.active_wake_words.push_back(value.as_string()); break; } } @@ -3160,21 +3222,23 @@ uint32_t AlarmControlPanelStateResponse::calc_size_msg(const void *self) { #endif return size; } -void AlarmControlPanelCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void AlarmControlPanelCommandRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_FIXED32): - this->key = value.as_fixed32(); + msg.key = value.as_fixed32(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->command = static_cast(value.as_varint()); + msg.command = static_cast(value.as_varint()); break; case proto_tag(3, WIRE_TYPE_LENGTH_DELIMITED): - this->code = StringRef(value.data(), value.size()); + msg.code = StringRef(value.data(), value.size()); break; #ifdef USE_DEVICES case proto_tag(4, WIRE_TYPE_VARINT): - this->device_id = value.as_varint(); + msg.device_id = value.as_varint(); break; #endif } @@ -3243,18 +3307,19 @@ uint32_t TextStateResponse::calc_size_msg(const void *self) { #endif return size; } -void TextCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void TextCommandRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_FIXED32): - this->key = value.as_fixed32(); + msg.key = value.as_fixed32(); break; case proto_tag(2, WIRE_TYPE_LENGTH_DELIMITED): - this->state = StringRef(value.data(), value.size()); + msg.state = StringRef(value.data(), value.size()); break; #ifdef USE_DEVICES case proto_tag(3, WIRE_TYPE_VARINT): - this->device_id = value.as_varint(); + msg.device_id = value.as_varint(); break; #endif } @@ -3319,24 +3384,25 @@ uint32_t DateStateResponse::calc_size_msg(const void *self) { #endif return size; } -void DateCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void DateCommandRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_FIXED32): - this->key = value.as_fixed32(); + msg.key = value.as_fixed32(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->year = value.as_varint(); + msg.year = value.as_varint(); break; case proto_tag(3, WIRE_TYPE_VARINT): - this->month = value.as_varint(); + msg.month = value.as_varint(); break; case proto_tag(4, WIRE_TYPE_VARINT): - this->day = value.as_varint(); + msg.day = value.as_varint(); break; #ifdef USE_DEVICES case proto_tag(5, WIRE_TYPE_VARINT): - this->device_id = value.as_varint(); + msg.device_id = value.as_varint(); break; #endif } @@ -3401,24 +3467,25 @@ uint32_t TimeStateResponse::calc_size_msg(const void *self) { #endif return size; } -void TimeCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void TimeCommandRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_FIXED32): - this->key = value.as_fixed32(); + msg.key = value.as_fixed32(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->hour = value.as_varint(); + msg.hour = value.as_varint(); break; case proto_tag(3, WIRE_TYPE_VARINT): - this->minute = value.as_varint(); + msg.minute = value.as_varint(); break; case proto_tag(4, WIRE_TYPE_VARINT): - this->second = value.as_varint(); + msg.second = value.as_varint(); break; #ifdef USE_DEVICES case proto_tag(5, WIRE_TYPE_VARINT): - this->device_id = value.as_varint(); + msg.device_id = value.as_varint(); break; #endif } @@ -3553,24 +3620,25 @@ uint32_t ValveStateResponse::calc_size_msg(const void *self) { #endif return size; } -void ValveCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void ValveCommandRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_FIXED32): - this->key = value.as_fixed32(); + msg.key = value.as_fixed32(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->has_position = value.as_bool(); + msg.has_position = value.as_bool(); break; case proto_tag(3, WIRE_TYPE_FIXED32): - this->position = value.as_float(); + msg.position = value.as_float(); break; case proto_tag(4, WIRE_TYPE_VARINT): - this->stop = value.as_bool(); + msg.stop = value.as_bool(); break; #ifdef USE_DEVICES case proto_tag(5, WIRE_TYPE_VARINT): - this->device_id = value.as_varint(); + msg.device_id = value.as_varint(); break; #endif } @@ -3633,18 +3701,19 @@ uint32_t DateTimeStateResponse::calc_size_msg(const void *self) { #endif return size; } -void DateTimeCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void DateTimeCommandRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_FIXED32): - this->key = value.as_fixed32(); + msg.key = value.as_fixed32(); break; case proto_tag(2, WIRE_TYPE_FIXED32): - this->epoch_seconds = value.as_fixed32(); + msg.epoch_seconds = value.as_fixed32(); break; #ifdef USE_DEVICES case proto_tag(3, WIRE_TYPE_VARINT): - this->device_id = value.as_varint(); + msg.device_id = value.as_varint(); break; #endif } @@ -3723,30 +3792,32 @@ uint32_t UpdateStateResponse::calc_size_msg(const void *self) { #endif return size; } -void UpdateCommandRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void UpdateCommandRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_FIXED32): - this->key = value.as_fixed32(); + msg.key = value.as_fixed32(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->command = static_cast(value.as_varint()); + msg.command = static_cast(value.as_varint()); break; #ifdef USE_DEVICES case proto_tag(3, WIRE_TYPE_VARINT): - this->device_id = value.as_varint(); + msg.device_id = value.as_varint(); break; #endif } } #endif #ifdef USE_ZWAVE_PROXY -void ZWaveProxyFrame::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void ZWaveProxyFrame::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_LENGTH_DELIMITED): - this->data = value.data(); - this->data_len = value.size(); + msg.data = value.data(); + msg.data_len = value.size(); break; } } @@ -3766,15 +3837,16 @@ ZWaveProxyFrame::calc_size_msg(const void *self) { size += ProtoSize::calc_length(1, msg.data_len); return size; } -void ZWaveProxyRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void ZWaveProxyRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->type = static_cast(value.as_varint()); + msg.type = static_cast(value.as_varint()); break; case proto_tag(2, WIRE_TYPE_LENGTH_DELIMITED): - this->data = value.data(); - this->data_len = value.size(); + msg.data = value.data(); + msg.data_len = value.size(); break; } } @@ -3846,30 +3918,32 @@ uint32_t ListEntitiesInfraredResponse::calc_size_msg(const void *self) { } #endif #if defined(USE_IR_RF) || defined(USE_RADIO_FREQUENCY) -void InfraredRFTransmitRawTimingsRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void InfraredRFTransmitRawTimingsRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { #ifdef USE_DEVICES case proto_tag(1, WIRE_TYPE_VARINT): - this->device_id = value.as_varint(); + msg.device_id = value.as_varint(); break; #endif case proto_tag(2, WIRE_TYPE_FIXED32): - this->key = value.as_fixed32(); + msg.key = value.as_fixed32(); break; case proto_tag(3, WIRE_TYPE_VARINT): - this->carrier_frequency = value.as_varint(); + msg.carrier_frequency = value.as_varint(); break; case proto_tag(4, WIRE_TYPE_VARINT): - this->repeat_count = value.as_varint(); + msg.repeat_count = value.as_varint(); break; case proto_tag(5, WIRE_TYPE_LENGTH_DELIMITED): - this->timings_data_ = value.data(); - this->timings_length_ = value.size(); - this->timings_count_ = count_packed_varints(value.data(), value.size()); + msg.timings_data_ = value.data(); + msg.timings_length_ = value.size(); + msg.timings_count_ = count_packed_varints(value.data(), value.size()); break; case proto_tag(6, WIRE_TYPE_VARINT): - this->modulation = value.as_varint(); + msg.modulation = value.as_varint(); break; } } @@ -3948,26 +4022,28 @@ uint32_t ListEntitiesRadioFrequencyResponse::calc_size_msg(const void *self) { } #endif #ifdef USE_SERIAL_PROXY -void SerialProxyConfigureRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void SerialProxyConfigureRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->instance = value.as_varint(); + msg.instance = value.as_varint(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->baudrate = value.as_varint(); + msg.baudrate = value.as_varint(); break; case proto_tag(3, WIRE_TYPE_VARINT): - this->flow_control = value.as_bool(); + msg.flow_control = value.as_bool(); break; case proto_tag(4, WIRE_TYPE_VARINT): - this->parity = static_cast(value.as_varint()); + msg.parity = static_cast(value.as_varint()); break; case proto_tag(5, WIRE_TYPE_VARINT): - this->stop_bits = value.as_varint(); + msg.stop_bits = value.as_varint(); break; case proto_tag(6, WIRE_TYPE_VARINT): - this->data_size = value.as_varint(); + msg.data_size = value.as_varint(); break; } } @@ -3989,34 +4065,39 @@ SerialProxyDataReceived::calc_size_msg(const void *self) { size += ProtoSize::calc_length(1, msg.data_len_); return size; } -void SerialProxyWriteRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void SerialProxyWriteRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->instance = value.as_varint(); + msg.instance = value.as_varint(); break; case proto_tag(2, WIRE_TYPE_LENGTH_DELIMITED): - this->data = value.data(); - this->data_len = value.size(); + msg.data = value.data(); + msg.data_len = value.size(); break; } } -void SerialProxySetModemPinsRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void SerialProxySetModemPinsRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->instance = value.as_varint(); + msg.instance = value.as_varint(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->line_states = value.as_varint(); + msg.line_states = value.as_varint(); break; } } -void SerialProxyGetModemPinsRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void SerialProxyGetModemPinsRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->instance = value.as_varint(); + msg.instance = value.as_varint(); break; } } @@ -4037,14 +4118,15 @@ uint32_t SerialProxyGetModemPinsResponse::calc_size_msg(const void *self) { size += msg.status ? 2 : 0; return size; } -void SerialProxyRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void SerialProxyRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->instance = value.as_varint(); + msg.instance = value.as_varint(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->type = static_cast(value.as_varint()); + msg.type = static_cast(value.as_varint()); break; } } @@ -4068,23 +4150,25 @@ uint32_t SerialProxyRequestResponse::calc_size_msg(const void *self) { } #endif #ifdef USE_BLUETOOTH_PROXY_CONNECTIONS -void BluetoothSetConnectionParamsRequest::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) { +void BluetoothSetConnectionParamsRequest::decode_field(void *self, uint32_t tag, const uint8_t *data, + proto_varint_value_t scalar) { + auto &msg = *static_cast(self); const ProtoFieldValue value(data, scalar); switch (tag) { case proto_tag(1, WIRE_TYPE_VARINT): - this->address = value.as_varint(); + msg.address = value.as_varint(); break; case proto_tag(2, WIRE_TYPE_VARINT): - this->min_interval = value.as_varint(); + msg.min_interval = value.as_varint(); break; case proto_tag(3, WIRE_TYPE_VARINT): - this->max_interval = value.as_varint(); + msg.max_interval = value.as_varint(); break; case proto_tag(4, WIRE_TYPE_VARINT): - this->latency = value.as_varint(); + msg.latency = value.as_varint(); break; case proto_tag(5, WIRE_TYPE_VARINT): - this->timeout = value.as_varint(); + msg.timeout = value.as_varint(); break; } } diff --git a/esphome/components/api/api_pb2.h b/esphome/components/api/api_pb2.h index f454a86a32..d356da2c78 100644 --- a/esphome/components/api/api_pb2.h +++ b/esphome/components/api/api_pb2.h @@ -419,12 +419,15 @@ class HelloRequest final : public ProtoDecodableMessage { StringRef client_info{}; uint32_t api_version_major{0}; uint32_t api_version_minor{0}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class HelloResponse final : public ProtoMessage { public: @@ -457,6 +460,9 @@ class DisconnectRequest final : public ProtoDecodableMessage { const LogString *message_name() const override { return LOG_STR("disconnect_request"); } #endif enums::DisconnectReason reason{}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } static uint8_t *encode_msg(const void *self, ProtoWriteBuffer &buffer PROTO_ENCODE_DEBUG_PARAM); uint8_t *encode(ProtoWriteBuffer &buffer PROTO_ENCODE_DEBUG_PARAM) const { return encode_msg(this, buffer PROTO_ENCODE_DEBUG_ARG); @@ -468,7 +474,7 @@ class DisconnectRequest final : public ProtoDecodableMessage { #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class DisconnectResponse final : public ProtoMessage { public: @@ -839,12 +845,15 @@ class CoverCommandRequest final : public CommandProtoMessage { bool has_tilt{false}; float tilt{0.0f}; bool stop{false}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_FAN @@ -913,12 +922,15 @@ class FanCommandRequest final : public CommandProtoMessage { int32_t speed_level{0}; bool has_preset_mode{false}; StringRef preset_mode{}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_LIGHT @@ -1009,12 +1021,15 @@ class LightCommandRequest final : public CommandProtoMessage { uint32_t flash_length{0}; bool has_effect{false}; StringRef effect{}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_SENSOR @@ -1114,12 +1129,15 @@ class SwitchCommandRequest final : public CommandProtoMessage { const LogString *message_name() const override { return LOG_STR("switch_command_request"); } #endif bool state{false}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_TEXT_SENSOR @@ -1174,12 +1192,15 @@ class SubscribeLogsRequest final : public ProtoDecodableMessage { #endif enums::LogLevel level{}; bool dump_config{false}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class SubscribeLogsResponse final : public ProtoMessage { public: @@ -1217,12 +1238,15 @@ class NoiseEncryptionSetKeyRequest final : public ProtoDecodableMessage { #endif const uint8_t *key{nullptr}; uint16_t key_len{0}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class NoiseEncryptionSetKeyResponse final : public ProtoMessage { public: @@ -1311,12 +1335,15 @@ class HomeassistantActionResponse final : public ProtoDecodableMessage { const uint8_t *response_data{nullptr}; uint16_t response_data_len{0}; #endif + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_API_HOMEASSISTANT_STATES @@ -1352,12 +1379,15 @@ class HomeAssistantStateResponse final : public ProtoDecodableMessage { StringRef entity_id{}; StringRef state{}; StringRef attribute{}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif class GetTimeRequest final : public ProtoMessage { @@ -1381,12 +1411,15 @@ class DSTRule final : public ProtoDecodableMessage { uint32_t month{0}; uint32_t week{0}; uint32_t day_of_week{0}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class ParsedTimezone final : public ProtoDecodableMessage { public: @@ -1394,12 +1427,15 @@ class ParsedTimezone final : public ProtoDecodableMessage { int32_t dst_offset_seconds{0}; DSTRule dst_start{}; DSTRule dst_end{}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class GetTimeResponse final : public ProtoDecodableMessage { public: @@ -1411,12 +1447,15 @@ class GetTimeResponse final : public ProtoDecodableMessage { uint32_t epoch_seconds{0}; ParsedTimezone parsed_timezone{}; bool has_parsed_timezone{false}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #ifdef USE_API_USER_DEFINED_ACTIONS class ListEntitiesServicesArgument final : public ProtoMessage { @@ -1484,7 +1523,7 @@ class ExecuteServiceArgument final : public ProtoDecodableMessage { #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class ExecuteServiceRequest final : public ProtoDecodableMessage { public: @@ -1507,7 +1546,7 @@ class ExecuteServiceRequest final : public ProtoDecodableMessage { #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_API_USER_DEFINED_ACTION_RESPONSES @@ -1593,12 +1632,15 @@ class CameraImageRequest final : public ProtoDecodableMessage { #endif bool single{false}; bool stream{false}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_CLIMATE @@ -1699,12 +1741,15 @@ class ClimateCommandRequest final : public CommandProtoMessage { StringRef custom_preset{}; bool has_target_humidity{false}; float target_humidity{0.0f}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_WATER_HEATER @@ -1771,12 +1816,15 @@ class WaterHeaterCommandRequest final : public CommandProtoMessage { uint32_t state{0}; float target_temperature_low{0.0f}; float target_temperature_high{0.0f}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_NUMBER @@ -1834,12 +1882,15 @@ class NumberCommandRequest final : public CommandProtoMessage { const LogString *message_name() const override { return LOG_STR("number_command_request"); } #endif float state{0.0f}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_SELECT @@ -1892,12 +1943,15 @@ class SelectCommandRequest final : public CommandProtoMessage { const LogString *message_name() const override { return LOG_STR("select_command_request"); } #endif StringRef state{}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_SIREN @@ -1958,12 +2012,15 @@ class SirenCommandRequest final : public CommandProtoMessage { uint32_t duration{0}; bool has_volume{false}; float volume{0.0f}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_LOCK @@ -2020,12 +2077,15 @@ class LockCommandRequest final : public CommandProtoMessage { enums::LockCommand command{}; bool has_code{false}; StringRef code{}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_BUTTON @@ -2056,12 +2116,15 @@ class ButtonCommandRequest final : public CommandProtoMessage { #ifdef HAS_PROTO_MESSAGE_DUMP const LogString *message_name() const override { return LOG_STR("button_command_request"); } #endif + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_MEDIA_PLAYER @@ -2142,12 +2205,15 @@ class MediaPlayerCommandRequest final : public CommandProtoMessage { StringRef media_url{}; bool has_announcement{false}; bool announcement{false}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_BLUETOOTH_PROXY @@ -2159,12 +2225,15 @@ class SubscribeBluetoothLEAdvertisementsRequest final : public ProtoDecodableMes const LogString *message_name() const override { return LOG_STR("subscribe_bluetooth_le_advertisements_request"); } #endif uint32_t flags{0}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class BluetoothLERawAdvertisement final : public ProtoMessage { public: @@ -2213,12 +2282,15 @@ class BluetoothDeviceRequest final : public ProtoDecodableMessage { enums::BluetoothDeviceRequestType request_type{}; bool has_address_type{false}; uint32_t address_type{0}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class BluetoothDeviceConnectionResponse final : public ProtoMessage { public: @@ -2251,12 +2323,15 @@ class BluetoothGATTGetServicesRequest final : public ProtoDecodableMessage { const LogString *message_name() const override { return LOG_STR("bluetooth_gatt_get_services_request"); } #endif uint64_t address{0}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class BluetoothGATTDescriptor final : public ProtoMessage { public: @@ -2362,12 +2437,15 @@ class BluetoothGATTReadRequest final : public ProtoDecodableMessage { #endif uint64_t address{0}; uint32_t handle{0}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class BluetoothGATTReadResponse final : public ProtoMessage { public: @@ -2408,12 +2486,15 @@ class BluetoothGATTWriteRequest final : public ProtoDecodableMessage { bool response{false}; const uint8_t *data{nullptr}; uint16_t data_len{0}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class BluetoothGATTReadDescriptorRequest final : public ProtoDecodableMessage { public: @@ -2424,12 +2505,15 @@ class BluetoothGATTReadDescriptorRequest final : public ProtoDecodableMessage { #endif uint64_t address{0}; uint32_t handle{0}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class BluetoothGATTWriteDescriptorRequest final : public ProtoDecodableMessage { public: @@ -2442,12 +2526,15 @@ class BluetoothGATTWriteDescriptorRequest final : public ProtoDecodableMessage { uint32_t handle{0}; const uint8_t *data{nullptr}; uint16_t data_len{0}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class BluetoothGATTNotifyRequest final : public ProtoDecodableMessage { public: @@ -2459,12 +2546,15 @@ class BluetoothGATTNotifyRequest final : public ProtoDecodableMessage { uint64_t address{0}; uint32_t handle{0}; bool enable{false}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class BluetoothGATTNotifyDataResponse final : public ProtoMessage { public: @@ -2677,12 +2767,15 @@ class BluetoothScannerSetModeRequest final : public ProtoDecodableMessage { const LogString *message_name() const override { return LOG_STR("bluetooth_scanner_set_mode_request"); } #endif enums::BluetoothScannerMode mode{}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_VOICE_ASSISTANT @@ -2695,12 +2788,15 @@ class SubscribeVoiceAssistantRequest final : public ProtoDecodableMessage { #endif bool subscribe{false}; uint32_t flags{0}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class VoiceAssistantAudioSettings final : public ProtoMessage { public: @@ -2752,23 +2848,29 @@ class VoiceAssistantResponse final : public ProtoDecodableMessage { #endif uint32_t port{0}; bool error{false}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class VoiceAssistantEventData final : public ProtoDecodableMessage { public: StringRef name{}; StringRef value{}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class VoiceAssistantEventResponse final : public ProtoDecodableMessage { public: @@ -2779,12 +2881,15 @@ class VoiceAssistantEventResponse final : public ProtoDecodableMessage { #endif enums::VoiceAssistantEvent event_type{}; std::vector data{}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class VoiceAssistantAudio final : public ProtoDecodableMessage { public: @@ -2798,6 +2903,9 @@ class VoiceAssistantAudio final : public ProtoDecodableMessage { bool end{false}; const uint8_t *data2{nullptr}; uint16_t data2_len{0}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } static uint8_t *encode_msg(const void *self, ProtoWriteBuffer &buffer PROTO_ENCODE_DEBUG_PARAM); uint8_t *encode(ProtoWriteBuffer &buffer PROTO_ENCODE_DEBUG_PARAM) const { return encode_msg(this, buffer PROTO_ENCODE_DEBUG_ARG); @@ -2809,7 +2917,7 @@ class VoiceAssistantAudio final : public ProtoDecodableMessage { #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class VoiceAssistantTimerEventResponse final : public ProtoDecodableMessage { public: @@ -2824,12 +2932,15 @@ class VoiceAssistantTimerEventResponse final : public ProtoDecodableMessage { uint32_t total_seconds{0}; uint32_t seconds_left{0}; bool is_active{false}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class VoiceAssistantAnnounceRequest final : public ProtoDecodableMessage { public: @@ -2842,12 +2953,15 @@ class VoiceAssistantAnnounceRequest final : public ProtoDecodableMessage { StringRef text{}; StringRef preannounce_media_id{}; bool start_conversation{false}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class VoiceAssistantAnnounceFinished final : public ProtoMessage { public: @@ -2895,12 +3009,15 @@ class VoiceAssistantExternalWakeWord final : public ProtoDecodableMessage { uint32_t model_size{0}; StringRef model_hash{}; StringRef url{}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class VoiceAssistantConfigurationRequest final : public ProtoDecodableMessage { public: @@ -2910,12 +3027,15 @@ class VoiceAssistantConfigurationRequest final : public ProtoDecodableMessage { const LogString *message_name() const override { return LOG_STR("voice_assistant_configuration_request"); } #endif std::vector external_wake_words{}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class VoiceAssistantConfigurationResponse final : public ProtoMessage { public: @@ -2947,12 +3067,15 @@ class VoiceAssistantSetConfiguration final : public ProtoDecodableMessage { const LogString *message_name() const override { return LOG_STR("voice_assistant_set_configuration"); } #endif std::vector active_wake_words{}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_ALARM_CONTROL_PANEL @@ -3007,12 +3130,15 @@ class AlarmControlPanelCommandRequest final : public CommandProtoMessage { #endif enums::AlarmControlPanelStateCommand command{}; StringRef code{}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_TEXT @@ -3068,12 +3194,15 @@ class TextCommandRequest final : public CommandProtoMessage { const LogString *message_name() const override { return LOG_STR("text_command_request"); } #endif StringRef state{}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_DATETIME_DATE @@ -3129,12 +3258,15 @@ class DateCommandRequest final : public CommandProtoMessage { uint32_t year{0}; uint32_t month{0}; uint32_t day{0}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_DATETIME_TIME @@ -3190,12 +3322,15 @@ class TimeCommandRequest final : public CommandProtoMessage { uint32_t hour{0}; uint32_t minute{0}; uint32_t second{0}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_EVENT @@ -3296,12 +3431,15 @@ class ValveCommandRequest final : public CommandProtoMessage { bool has_position{false}; float position{0.0f}; bool stop{false}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_DATETIME_DATETIME @@ -3353,12 +3491,15 @@ class DateTimeCommandRequest final : public CommandProtoMessage { const LogString *message_name() const override { return LOG_STR("date_time_command_request"); } #endif uint32_t epoch_seconds{0}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_UPDATE @@ -3418,12 +3559,15 @@ class UpdateCommandRequest final : public CommandProtoMessage { const LogString *message_name() const override { return LOG_STR("update_command_request"); } #endif enums::UpdateCommand command{}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; #endif #ifdef USE_ZWAVE_PROXY @@ -3436,6 +3580,9 @@ class ZWaveProxyFrame final : public ProtoDecodableMessage { #endif const uint8_t *data{nullptr}; uint16_t data_len{0}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } static uint8_t *encode_msg(const void *self, ProtoWriteBuffer &buffer PROTO_ENCODE_DEBUG_PARAM); uint8_t *encode(ProtoWriteBuffer &buffer PROTO_ENCODE_DEBUG_PARAM) const { return encode_msg(this, buffer PROTO_ENCODE_DEBUG_ARG); @@ -3447,7 +3594,7 @@ class ZWaveProxyFrame final : public ProtoDecodableMessage { #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class ZWaveProxyRequest final : public ProtoDecodableMessage { public: @@ -3459,6 +3606,9 @@ class ZWaveProxyRequest final : public ProtoDecodableMessage { enums::ZWaveProxyRequestType type{}; const uint8_t *data{nullptr}; uint16_t data_len{0}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } static uint8_t *encode_msg(const void *self, ProtoWriteBuffer &buffer PROTO_ENCODE_DEBUG_PARAM); uint8_t *encode(ProtoWriteBuffer &buffer PROTO_ENCODE_DEBUG_PARAM) const { return encode_msg(this, buffer PROTO_ENCODE_DEBUG_ARG); @@ -3470,7 +3620,7 @@ class ZWaveProxyRequest final : public ProtoDecodableMessage { #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class ZWaveProxyRequestResponse final : public ProtoMessage { public: @@ -3535,12 +3685,15 @@ class InfraredRFTransmitRawTimingsRequest final : public ProtoDecodableMessage { uint16_t timings_length_{0}; uint16_t timings_count_{0}; uint32_t modulation{0}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class InfraredRFReceiveEvent final : public ProtoMessage { public: @@ -3606,12 +3759,15 @@ class SerialProxyConfigureRequest final : public ProtoDecodableMessage { enums::SerialProxyParity parity{}; uint32_t stop_bits{0}; uint32_t data_size{0}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class SerialProxyDataReceived final : public ProtoMessage { public: @@ -3649,12 +3805,15 @@ class SerialProxyWriteRequest final : public ProtoDecodableMessage { uint32_t instance{0}; const uint8_t *data{nullptr}; uint16_t data_len{0}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class SerialProxySetModemPinsRequest final : public ProtoDecodableMessage { public: @@ -3665,12 +3824,15 @@ class SerialProxySetModemPinsRequest final : public ProtoDecodableMessage { #endif uint32_t instance{0}; uint32_t line_states{0}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class SerialProxyGetModemPinsRequest final : public ProtoDecodableMessage { public: @@ -3680,12 +3842,15 @@ class SerialProxyGetModemPinsRequest final : public ProtoDecodableMessage { const LogString *message_name() const override { return LOG_STR("serial_proxy_get_modem_pins_request"); } #endif uint32_t instance{0}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class SerialProxyGetModemPinsResponse final : public ProtoMessage { public: @@ -3718,12 +3883,15 @@ class SerialProxyRequest final : public ProtoDecodableMessage { #endif uint32_t instance{0}; enums::SerialProxyRequestType type{}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class SerialProxyRequestResponse final : public ProtoMessage { public: @@ -3762,12 +3930,15 @@ class BluetoothSetConnectionParamsRequest final : public ProtoDecodableMessage { uint32_t max_interval{0}; uint32_t latency{0}; uint32_t timeout{0}; + void decode(const uint8_t *buffer, size_t length) { + ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field); + } #ifdef HAS_PROTO_MESSAGE_DUMP const char *dump_to(DumpBuffer &out) const override; #endif protected: - void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override; + static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); }; class BluetoothSetConnectionParamsResponse final : public ProtoMessage { public: diff --git a/esphome/components/api/proto.cpp b/esphome/components/api/proto.cpp index 7a638680be..59719b8cee 100644 --- a/esphome/components/api/proto.cpp +++ b/esphome/components/api/proto.cpp @@ -210,7 +210,7 @@ void ProtoWriteBuffer::debug_check_encode_size_(uint32_t field_id, uint32_t expe #endif -void ProtoDecodableMessage::decode(const uint8_t *buffer, size_t length) { +void ProtoDecodableMessage::decode_fields(void *msg, const uint8_t *buffer, size_t length, DecodeFieldFn field) { const uint8_t *ptr = buffer; const uint8_t *end = buffer + length; @@ -281,7 +281,7 @@ void ProtoDecodableMessage::decode(const uint8_t *buffer, size_t length) { return; } } - this->decode_field(tag, data, scalar); + field(msg, tag, data, scalar); } } diff --git a/esphome/components/api/proto.h b/esphome/components/api/proto.h index 081affbaae..4e19e5016a 100644 --- a/esphome/components/api/proto.h +++ b/esphome/components/api/proto.h @@ -720,7 +720,15 @@ class ProtoMessage { // Base class for messages that support decoding class ProtoDecodableMessage : public ProtoMessage { public: - void decode(const uint8_t *buffer, size_t length); + /// Stores one decoded field into \p msg; generated per message type. \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. + using DecodeFieldFn = void (*)(void *msg, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar); + /// Walk \p buffer and hand every field to \p field. The generated decode() passes the message's + /// own decode_field, so decodable messages carry no vtable. + static void decode_fields(void *msg, const uint8_t *buffer, size_t length, DecodeFieldFn field); + /// A decodable message without fields has nothing to read + void decode(const uint8_t *buffer, size_t length) {} /** * Count occurrences of a repeated field in a protobuf buffer. @@ -732,13 +740,6 @@ class ProtoDecodableMessage : public ProtoMessage { * @return Number of times the field appears in the buffer */ static uint32_t count_repeated_field(const uint8_t *buffer, size_t length, uint32_t target_field_id); - - protected: - ~ProtoDecodableMessage() = default; - /// 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. - virtual void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) {} }; class ProtoSize { diff --git a/script/api_protobuf/api_protobuf.py b/script/api_protobuf/api_protobuf.py index bdfa58a3b3..d0b763cb37 100755 --- a/script/api_protobuf/api_protobuf.py +++ b/script/api_protobuf/api_protobuf.py @@ -2661,15 +2661,22 @@ def build_message_type( cpp = "" if decode: - o = f"void {desc.name}::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) {{\n" + o = f"void {desc.name}::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) {{\n" + o += f" auto &msg = *static_cast<{desc.name} *>(self);\n" o += " const ProtoFieldValue value(data, scalar);\n" o += " switch (tag) {\n" - o += indent("\n".join(decode), " ") + "\n" + o += indent("\n".join(decode), " ").replace("this->", "msg.") + "\n" o += " }\n" o += "}\n" cpp += o - prot = "void decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) override;" + prot = "static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar);" protected_content.insert(0, prot) + if not fixed_vector_fields: + public_content.append( + "void decode(const uint8_t *buffer, size_t length) {\n" + " ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field);\n" + "}" + ) # Generate custom decode() override for messages with FixedVector fields if fixed_vector_fields: @@ -2679,8 +2686,8 @@ def build_message_type( for field_name, field_number in fixed_vector_fields: o += f" uint32_t count_{field_name} = ProtoDecodableMessage::count_repeated_field(buffer, length, {field_number});\n" o += f" this->{field_name}.init(count_{field_name});\n" - # Call parent decode to populate the fields - o += " ProtoDecodableMessage::decode(buffer, length);\n" + # Then the shared loop fills them + o += " ProtoDecodableMessage::decode_fields(this, buffer, length, &decode_field);\n" o += "}\n" cpp += o # Generate the decode() declaration in header (public method) diff --git a/tests/unit_tests/components/api/test_api_protobuf_generator.py b/tests/unit_tests/components/api/test_api_protobuf_generator.py index d3b3adb3b9..094305dfe3 100644 --- a/tests/unit_tests/components/api/test_api_protobuf_generator.py +++ b/tests/unit_tests/components/api/test_api_protobuf_generator.py @@ -292,11 +292,11 @@ def test_message_gets_a_single_decode_field_override() -> None: desc.field.add(name="count", number=2, type=UINT32) desc.field.add(name="level", number=3, type=FLOAT) 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;" + decl = "static void decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar);" assert header.count(decl) == 1 assert ( cpp.count( - "void Mixed::decode_field(uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) {" + "void Mixed::decode_field(void *self, uint32_t tag, const uint8_t *data, proto_varint_value_t scalar) {" ) == 1 )