From 949249cac3a40859955304b64eb1ff9aa97661aa Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 10 Jul 2025 14:12:57 -1000 Subject: [PATCH] cleanup --- esphome/components/api/api_pb2.cpp | 36 +++++++++++----------- esphome/components/api/proto.h | 47 +++++++++-------------------- script/api_protobuf/api_protobuf.py | 12 +++++--- 3 files changed, 40 insertions(+), 55 deletions(-) diff --git a/esphome/components/api/api_pb2.cpp b/esphome/components/api/api_pb2.cpp index 0b6690dcb6..854c1b8cb5 100644 --- a/esphome/components/api/api_pb2.cpp +++ b/esphome/components/api/api_pb2.cpp @@ -104,18 +104,18 @@ const FieldMetaV3 DeviceInfoResponse::FIELDS_V3[20] = { 42, {.offset_low = static_cast(PROTO_FIELD_OFFSET(DeviceInfoResponse, area) & 0xFF), .message_type_id = - static_cast(9 | (((PROTO_FIELD_OFFSET(DeviceInfoResponse, area) >> 8) & 0x0F) << 4))}}}; + static_cast(((PROTO_FIELD_OFFSET(DeviceInfoResponse, area) >> 8) & 0x03) | (9 << 2))}}}; const RepeatedFieldMetaV3 DeviceInfoResponse::REPEATED_FIELDS_V3[2] = { {20, 42, {.offset_low = static_cast(PROTO_FIELD_OFFSET(DeviceInfoResponse, devices) & 0xFF), .message_type_id = - static_cast(0 | (((PROTO_FIELD_OFFSET(DeviceInfoResponse, devices) >> 8) & 0x0F) << 4))}}, + static_cast(((PROTO_FIELD_OFFSET(DeviceInfoResponse, devices) >> 8) & 0x03) | (0 << 2))}}, {21, 42, {.offset_low = static_cast(PROTO_FIELD_OFFSET(DeviceInfoResponse, areas) & 0xFF), .message_type_id = - static_cast(1 | (((PROTO_FIELD_OFFSET(DeviceInfoResponse, areas) >> 8) & 0x0F) << 4))}}}; + static_cast(((PROTO_FIELD_OFFSET(DeviceInfoResponse, areas) >> 8) & 0x03) | (1 << 2))}}}; #ifdef USE_BINARY_SENSOR const FieldMetaV3 ListEntitiesBinarySensorResponse::FIELDS_V3[10] = { {1, 8, {.offset = PROTO_FIELD_OFFSET(ListEntitiesBinarySensorResponse, object_id)}}, @@ -352,17 +352,17 @@ const RepeatedFieldMetaV3 HomeassistantServiceResponse::REPEATED_FIELDS_V3[3] = 10, {.offset_low = static_cast(PROTO_FIELD_OFFSET(HomeassistantServiceResponse, data) & 0xFF), .message_type_id = - static_cast(2 | (((PROTO_FIELD_OFFSET(HomeassistantServiceResponse, data) >> 8) & 0x0F) << 4))}}, + static_cast(((PROTO_FIELD_OFFSET(HomeassistantServiceResponse, data) >> 8) & 0x03) | (2 << 2))}}, {3, 10, {.offset_low = static_cast(PROTO_FIELD_OFFSET(HomeassistantServiceResponse, data_template) & 0xFF), .message_type_id = static_cast( - 2 | (((PROTO_FIELD_OFFSET(HomeassistantServiceResponse, data_template) >> 8) & 0x0F) << 4))}}, + ((PROTO_FIELD_OFFSET(HomeassistantServiceResponse, data_template) >> 8) & 0x03) | (2 << 2))}}, {4, 10, {.offset_low = static_cast(PROTO_FIELD_OFFSET(HomeassistantServiceResponse, variables) & 0xFF), .message_type_id = static_cast( - 2 | (((PROTO_FIELD_OFFSET(HomeassistantServiceResponse, variables) >> 8) & 0x0F) << 4))}}}; + ((PROTO_FIELD_OFFSET(HomeassistantServiceResponse, variables) >> 8) & 0x03) | (2 << 2))}}}; const FieldMetaV3 SubscribeHomeAssistantStateResponse::FIELDS_V3[3] = { {1, 8, {.offset = PROTO_FIELD_OFFSET(SubscribeHomeAssistantStateResponse, entity_id)}}, {2, 8, {.offset = PROTO_FIELD_OFFSET(SubscribeHomeAssistantStateResponse, attribute)}}, @@ -384,7 +384,7 @@ const RepeatedFieldMetaV3 ListEntitiesServicesResponse::REPEATED_FIELDS_V3[1] = 10, {.offset_low = static_cast(PROTO_FIELD_OFFSET(ListEntitiesServicesResponse, args) & 0xFF), .message_type_id = - static_cast(3 | (((PROTO_FIELD_OFFSET(ListEntitiesServicesResponse, args) >> 8) & 0x0F) << 4))}}}; + static_cast(((PROTO_FIELD_OFFSET(ListEntitiesServicesResponse, args) >> 8) & 0x03) | (3 << 2))}}}; const FieldMetaV3 ExecuteServiceArgument::FIELDS_V3[5] = { {1, 0, {.offset = PROTO_FIELD_OFFSET(ExecuteServiceArgument, bool_)}}, {2, 1, {.offset = PROTO_FIELD_OFFSET(ExecuteServiceArgument, legacy_int)}}, @@ -403,7 +403,7 @@ const RepeatedFieldMetaV3 ExecuteServiceRequest::REPEATED_FIELDS_V3[1] = { 10, {.offset_low = static_cast(PROTO_FIELD_OFFSET(ExecuteServiceRequest, args) & 0xFF), .message_type_id = - static_cast(4 | (((PROTO_FIELD_OFFSET(ExecuteServiceRequest, args) >> 8) & 0x0F) << 4))}}}; + static_cast(((PROTO_FIELD_OFFSET(ExecuteServiceRequest, args) >> 8) & 0x03) | (4 << 2))}}}; #ifdef USE_CAMERA const FieldMetaV3 ListEntitiesCameraResponse::FIELDS_V3[8] = { {1, 8, {.offset = PROTO_FIELD_OFFSET(ListEntitiesCameraResponse, object_id)}}, @@ -628,7 +628,7 @@ const RepeatedFieldMetaV3 ListEntitiesMediaPlayerResponse::REPEATED_FIELDS_V3[1] 10, {.offset_low = static_cast(PROTO_FIELD_OFFSET(ListEntitiesMediaPlayerResponse, supported_formats) & 0xFF), .message_type_id = static_cast( - 5 | (((PROTO_FIELD_OFFSET(ListEntitiesMediaPlayerResponse, supported_formats) >> 8) & 0x0F) << 4))}}}; + ((PROTO_FIELD_OFFSET(ListEntitiesMediaPlayerResponse, supported_formats) >> 8) & 0x03) | (5 << 2))}}}; const FieldMetaV3 MediaPlayerStateResponse::FIELDS_V3[5] = { {1, 12, {.offset = PROTO_FIELD_OFFSET(MediaPlayerStateResponse, key)}}, {2, 7, {.offset = PROTO_FIELD_OFFSET(MediaPlayerStateResponse, state)}}, @@ -665,13 +665,13 @@ const RepeatedFieldMetaV3 BluetoothLEAdvertisementResponse::REPEATED_FIELDS_V3[3 10, {.offset_low = static_cast(PROTO_FIELD_OFFSET(BluetoothLEAdvertisementResponse, service_data) & 0xFF), .message_type_id = static_cast( - 6 | (((PROTO_FIELD_OFFSET(BluetoothLEAdvertisementResponse, service_data) >> 8) & 0x0F) << 4))}}, + ((PROTO_FIELD_OFFSET(BluetoothLEAdvertisementResponse, service_data) >> 8) & 0x03) | (6 << 2))}}, {6, 10, {.offset_low = static_cast(PROTO_FIELD_OFFSET(BluetoothLEAdvertisementResponse, manufacturer_data) & 0xFF), .message_type_id = static_cast( - 6 | (((PROTO_FIELD_OFFSET(BluetoothLEAdvertisementResponse, manufacturer_data) >> 8) & 0x0F) << 4))}}}; + ((PROTO_FIELD_OFFSET(BluetoothLEAdvertisementResponse, manufacturer_data) >> 8) & 0x03) | (6 << 2))}}}; const FieldMetaV3 BluetoothLERawAdvertisement::FIELDS_V3[4] = { {1, 4, {.offset = PROTO_FIELD_OFFSET(BluetoothLERawAdvertisement, address)}}, {2, 5, {.offset = PROTO_FIELD_OFFSET(BluetoothLERawAdvertisement, rssi)}}, @@ -683,7 +683,7 @@ const RepeatedFieldMetaV3 BluetoothLERawAdvertisementsResponse::REPEATED_FIELDS_ {.offset_low = static_cast(PROTO_FIELD_OFFSET(BluetoothLERawAdvertisementsResponse, advertisements) & 0xFF), .message_type_id = static_cast( - 7 | (((PROTO_FIELD_OFFSET(BluetoothLERawAdvertisementsResponse, advertisements) >> 8) & 0x0F) << 4))}}}; + ((PROTO_FIELD_OFFSET(BluetoothLERawAdvertisementsResponse, advertisements) >> 8) & 0x03) | (7 << 2))}}}; const FieldMetaV3 BluetoothDeviceRequest::FIELDS_V3[4] = { {1, 4, {.offset = PROTO_FIELD_OFFSET(BluetoothDeviceRequest, address)}}, {2, 7, {.offset = PROTO_FIELD_OFFSET(BluetoothDeviceRequest, request_type)}}, @@ -709,7 +709,7 @@ const RepeatedFieldMetaV3 BluetoothGATTCharacteristic::REPEATED_FIELDS_V3[2] = { 10, {.offset_low = static_cast(PROTO_FIELD_OFFSET(BluetoothGATTCharacteristic, descriptors) & 0xFF), .message_type_id = static_cast( - 8 | (((PROTO_FIELD_OFFSET(BluetoothGATTCharacteristic, descriptors) >> 8) & 0x0F) << 4))}}}; + ((PROTO_FIELD_OFFSET(BluetoothGATTCharacteristic, descriptors) >> 8) & 0x03) | (8 << 2))}}}; const FieldMetaV3 BluetoothGATTService::FIELDS_V3[1] = { {2, 2, {.offset = PROTO_FIELD_OFFSET(BluetoothGATTService, handle)}}}; const RepeatedFieldMetaV3 BluetoothGATTService::REPEATED_FIELDS_V3[2] = { @@ -718,7 +718,7 @@ const RepeatedFieldMetaV3 BluetoothGATTService::REPEATED_FIELDS_V3[2] = { 10, {.offset_low = static_cast(PROTO_FIELD_OFFSET(BluetoothGATTService, characteristics) & 0xFF), .message_type_id = - static_cast(9 | (((PROTO_FIELD_OFFSET(BluetoothGATTService, characteristics) >> 8) & 0x0F) << 4))}}}; + static_cast(((PROTO_FIELD_OFFSET(BluetoothGATTService, characteristics) >> 8) & 0x03) | (9 << 2))}}}; const FieldMetaV3 BluetoothGATTGetServicesResponse::FIELDS_V3[1] = { {1, 4, {.offset = PROTO_FIELD_OFFSET(BluetoothGATTGetServicesResponse, address)}}}; const RepeatedFieldMetaV3 BluetoothGATTGetServicesResponse::REPEATED_FIELDS_V3[1] = { @@ -726,7 +726,7 @@ const RepeatedFieldMetaV3 BluetoothGATTGetServicesResponse::REPEATED_FIELDS_V3[1 10, {.offset_low = static_cast(PROTO_FIELD_OFFSET(BluetoothGATTGetServicesResponse, services) & 0xFF), .message_type_id = static_cast( - 10 | (((PROTO_FIELD_OFFSET(BluetoothGATTGetServicesResponse, services) >> 8) & 0x0F) << 4))}}}; + ((PROTO_FIELD_OFFSET(BluetoothGATTGetServicesResponse, services) >> 8) & 0x03) | (10 << 2))}}}; const FieldMetaV3 BluetoothGATTGetServicesDoneResponse::FIELDS_V3[1] = { {1, 4, {.offset = PROTO_FIELD_OFFSET(BluetoothGATTGetServicesDoneResponse, address)}}}; const FieldMetaV3 BluetoothGATTReadRequest::FIELDS_V3[2] = { @@ -805,7 +805,7 @@ const FieldMetaV3 VoiceAssistantRequest::FIELDS_V3[5] = { 10, {.offset_low = static_cast(PROTO_FIELD_OFFSET(VoiceAssistantRequest, audio_settings) & 0xFF), .message_type_id = static_cast( - 105 | (((PROTO_FIELD_OFFSET(VoiceAssistantRequest, audio_settings) >> 8) & 0x0F) << 4))}}, + ((PROTO_FIELD_OFFSET(VoiceAssistantRequest, audio_settings) >> 8) & 0x03) | (105 << 2))}}, {5, 8, {.offset = PROTO_FIELD_OFFSET(VoiceAssistantRequest, wake_word_phrase)}}}; const FieldMetaV3 VoiceAssistantResponse::FIELDS_V3[2] = { {1, 2, {.offset = PROTO_FIELD_OFFSET(VoiceAssistantResponse, port)}}, @@ -820,7 +820,7 @@ const RepeatedFieldMetaV3 VoiceAssistantEventResponse::REPEATED_FIELDS_V3[1] = { 10, {.offset_low = static_cast(PROTO_FIELD_OFFSET(VoiceAssistantEventResponse, data) & 0xFF), .message_type_id = - static_cast(11 | (((PROTO_FIELD_OFFSET(VoiceAssistantEventResponse, data) >> 8) & 0x0F) << 4))}}}; + static_cast(((PROTO_FIELD_OFFSET(VoiceAssistantEventResponse, data) >> 8) & 0x03) | (11 << 2))}}}; const FieldMetaV3 VoiceAssistantAudio::FIELDS_V3[2] = { {1, 9, {.offset = PROTO_FIELD_OFFSET(VoiceAssistantAudio, data)}}, {2, 0, {.offset = PROTO_FIELD_OFFSET(VoiceAssistantAudio, end)}}}; @@ -851,7 +851,7 @@ const RepeatedFieldMetaV3 VoiceAssistantConfigurationResponse::REPEATED_FIELDS_V {.offset_low = static_cast(PROTO_FIELD_OFFSET(VoiceAssistantConfigurationResponse, available_wake_words) & 0xFF), .message_type_id = static_cast( - 12 | (((PROTO_FIELD_OFFSET(VoiceAssistantConfigurationResponse, available_wake_words) >> 8) & 0x0F) << 4))}}, + ((PROTO_FIELD_OFFSET(VoiceAssistantConfigurationResponse, available_wake_words) >> 8) & 0x03) | (12 << 2))}}, {2, 8, {.offset = PROTO_FIELD_OFFSET(VoiceAssistantConfigurationResponse, active_wake_words)}}}; const RepeatedFieldMetaV3 VoiceAssistantSetConfiguration::REPEATED_FIELDS_V3[1] = { {1, 8, {.offset = PROTO_FIELD_OFFSET(VoiceAssistantSetConfiguration, active_wake_words)}}}; diff --git a/esphome/components/api/proto.h b/esphome/components/api/proto.h index fe5507450b..b7d47dcd77 100644 --- a/esphome/components/api/proto.h +++ b/esphome/components/api/proto.h @@ -77,8 +77,9 @@ constexpr uint8_t get_wire_type(ProtoFieldType type) { // Macro to calculate field offset without triggering -Winvalid-offsetof // This uses the same approach as offsetof but with explicit reinterpret_cast -#define PROTO_FIELD_OFFSET(Type, Member) /* NOLINT(bugprone-macro-parentheses) */ \ - static_cast(reinterpret_cast(&reinterpret_cast(16)->Member) - 16) +#define PROTO_FIELD_OFFSET(Type, Member) \ + static_cast(reinterpret_cast(&reinterpret_cast(16)->Member) - \ + 16) /* NOLINT(bugprone-macro-parentheses) */ /// Representation of a VarInt - in ProtoBuf should be 64bit but we only use 32bit class ProtoVarInt { @@ -288,8 +289,8 @@ struct FieldMetaV3 { union { uint16_t offset; // For non-message types: offset in class (0-65535) struct { - uint8_t offset_low; // For TYPE_MESSAGE: low byte of offset - uint8_t message_type_id; // For TYPE_MESSAGE: index into MESSAGE_HANDLERS + uint8_t offset_low; // For TYPE_MESSAGE: low byte of offset (bits 0-7) + uint8_t message_type_id; // For TYPE_MESSAGE: bits 0-1: offset high (bits 8-9), bits 2-7: handler index (0-63) }; }; @@ -298,13 +299,13 @@ struct FieldMetaV3 { uint8_t get_precalced_size() const { return ((type_and_size >> 5) & 0x03) + 1; } uint16_t get_offset() const { if (get_type() == ProtoFieldType::TYPE_MESSAGE) { - // Reconstruct full offset from packed fields - // Bits 0-7 from offset_low, bits 8-11 from upper nibble of message_type_id - return static_cast(offset_low) | (static_cast(message_type_id & 0xF0) << 4); + // Reconstruct full offset from packed fields (10-bit offset) + // Bits 0-7 from offset_low, bits 8-9 from lower 2 bits of message_type_id + return static_cast(offset_low) | (static_cast(message_type_id & 0x03) << 8); } return offset; } - uint8_t get_message_type_id() const { return message_type_id & 0x0F; } + uint8_t get_message_type_id() const { return message_type_id >> 2; } // Upper 6 bits for type ID (0-63) }; // V2 structures removed - we only use V3 now @@ -476,8 +477,8 @@ struct RepeatedFieldMetaV3 { union { uint16_t offset; // For non-message types: offset in class (0-65535) struct { - uint8_t offset_low; // For TYPE_MESSAGE: low byte of offset - uint8_t message_type_id; // For TYPE_MESSAGE: index into REPEATED_MESSAGE_HANDLERS + uint8_t offset_low; // For TYPE_MESSAGE: low byte of offset (bits 0-7) + uint8_t message_type_id; // For TYPE_MESSAGE: bits 0-1: offset high (bits 8-9), bits 2-7: handler index (0-63) }; }; @@ -486,13 +487,13 @@ struct RepeatedFieldMetaV3 { uint8_t get_precalced_size() const { return ((type_and_size >> 5) & 0x03) + 1; } uint16_t get_offset() const { if (get_type() == ProtoFieldType::TYPE_MESSAGE) { - // Reconstruct full offset from packed fields - // Bits 0-7 from offset_low, bits 8-11 from upper nibble of message_type_id - return static_cast(offset_low) | (static_cast(message_type_id & 0xF0) << 4); + // Reconstruct full offset from packed fields (10-bit offset) + // Bits 0-7 from offset_low, bits 8-9 from lower 2 bits of message_type_id + return static_cast(offset_low) | (static_cast(message_type_id & 0x03) << 8); } return offset; } - uint8_t get_message_type_id() const { return message_type_id & 0x0F; } + uint8_t get_message_type_id() const { return message_type_id >> 2; } // Upper 6 bits for type ID (0-63) }; // V2 structures removed - we only use V3 now @@ -577,35 +578,17 @@ class ProtoService { return true; } }; - -// Type-specific functions removed - V3 inlines all operations directly - -// Template enum field functions removed - V3 inlines all operations directly - -// Repeated field handling functions removed - V3 inlines encoding directly - -// Note: The template encode_repeated_message_field is still used by the message handler registry template void encode_repeated_message_field(ProtoWriteBuffer &buffer, const void *field_ptr, uint8_t field_num); -// Size calculation for repeated fields removed - V3 inlines size calculation directly - -// Note: The template size_repeated_message_field is still used by the message handler registry template void size_repeated_message_field(uint32_t &total_size, const void *field_ptr, uint8_t precalced_field_id_size); -// Repeated field decode functions removed - V3 inlines decoding directly - -// Forward declarations for message field template functions template void encode_message_field(ProtoWriteBuffer &buffer, const void *field_ptr, uint8_t field_num); template void size_message_field(uint32_t &total_size, const void *field_ptr, uint8_t precalced_field_id_size, bool force); -// Template decode functions removed - V3 inlines decoding directly - -// Core shared functions removed - V2 metadata is used directly - } // namespace api } // namespace esphome diff --git a/script/api_protobuf/api_protobuf.py b/script/api_protobuf/api_protobuf.py index 781c8d4521..753fb6fa9e 100755 --- a/script/api_protobuf/api_protobuf.py +++ b/script/api_protobuf/api_protobuf.py @@ -1350,8 +1350,10 @@ def build_message_type( ti._ti.type_name ) offset = f"PROTO_FIELD_OFFSET({desc.name}, {ti.field_name})" + # Bits 0-1: bits 8-9 of offset (extends offset to 10 bits = 1023) + # Bits 2-7: actual message type ID (supports 64 types) repeated_fields_v3.append( - f"{{{field.number}, {type_and_size}, {{.offset_low = static_cast({offset} & 0xFF), .message_type_id = static_cast({message_type_id} | ((({offset} >> 8) & 0x0F) << 4))}}}}" + f"{{{field.number}, {type_and_size}, {{.offset_low = static_cast({offset} & 0xFF), .message_type_id = static_cast((({offset} >> 8) & 0x03) | ({message_type_id} << 2))}}}}" ) else: # Non-message types use full offset @@ -1376,11 +1378,11 @@ def build_message_type( offset = f"PROTO_FIELD_OFFSET({desc.name}, {ti.field_name})" # Since we have so few message types, we can use the upper bits of - # message_type_id to extend the offset range - # Bits 0-3: actual message type ID (supports 16 types) - # Bits 4-7: bits 8-11 of offset (extends offset to 12 bits = 4096) + # message_type_id to store the actual type ID + # Bits 0-1: bits 8-9 of offset (extends offset to 10 bits = 1023) + # Bits 2-7: actual message type ID (supports 64 types) regular_fields_v3.append( - f"{{{field.number}, {type_and_size}, {{.offset_low = static_cast({offset} & 0xFF), .message_type_id = static_cast({message_type_id} | ((({offset} >> 8) & 0x0F) << 4))}}}}" + f"{{{field.number}, {type_and_size}, {{.offset_low = static_cast({offset} & 0xFF), .message_type_id = static_cast((({offset} >> 8) & 0x03) | ({message_type_id} << 2))}}}}" ) else: # Non-message types use full offset