mirror of
https://github.com/esphome/esphome.git
synced 2026-02-15 22:09:36 -07:00
[api] Skip class generation for empty SOURCE_CLIENT protobuf messages (#13880)
This commit is contained in:
@@ -440,19 +440,6 @@ class PingResponse final : public ProtoMessage {
|
||||
|
||||
protected:
|
||||
};
|
||||
class DeviceInfoRequest final : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 9;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 0;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *message_name() const override { return "device_info_request"; }
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
};
|
||||
#ifdef USE_AREAS
|
||||
class AreaInfo final : public ProtoMessage {
|
||||
public:
|
||||
@@ -546,19 +533,6 @@ class DeviceInfoResponse final : public ProtoMessage {
|
||||
|
||||
protected:
|
||||
};
|
||||
class ListEntitiesRequest final : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 11;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 0;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *message_name() const override { return "list_entities_request"; }
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
};
|
||||
class ListEntitiesDoneResponse final : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 19;
|
||||
@@ -572,19 +546,6 @@ class ListEntitiesDoneResponse final : public ProtoMessage {
|
||||
|
||||
protected:
|
||||
};
|
||||
class SubscribeStatesRequest final : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 20;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 0;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *message_name() const override { return "subscribe_states_request"; }
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
};
|
||||
#ifdef USE_BINARY_SENSOR
|
||||
class ListEntitiesBinarySensorResponse final : public InfoResponseProtoMessage {
|
||||
public:
|
||||
@@ -1037,19 +998,6 @@ class NoiseEncryptionSetKeyResponse final : public ProtoMessage {
|
||||
};
|
||||
#endif
|
||||
#ifdef USE_API_HOMEASSISTANT_SERVICES
|
||||
class SubscribeHomeassistantServicesRequest final : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 34;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 0;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *message_name() const override { return "subscribe_homeassistant_services_request"; }
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
};
|
||||
class HomeassistantServiceMap final : public ProtoMessage {
|
||||
public:
|
||||
StringRef key{};
|
||||
@@ -1117,19 +1065,6 @@ class HomeassistantActionResponse final : public ProtoDecodableMessage {
|
||||
};
|
||||
#endif
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
class SubscribeHomeAssistantStatesRequest final : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 38;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 0;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *message_name() const override { return "subscribe_home_assistant_states_request"; }
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
};
|
||||
class SubscribeHomeAssistantStateResponse final : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 39;
|
||||
@@ -2160,19 +2095,6 @@ class BluetoothGATTNotifyDataResponse final : public ProtoMessage {
|
||||
|
||||
protected:
|
||||
};
|
||||
class SubscribeBluetoothConnectionsFreeRequest final : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 80;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 0;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *message_name() const override { return "subscribe_bluetooth_connections_free_request"; }
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
};
|
||||
class BluetoothConnectionsFreeResponse final : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 81;
|
||||
@@ -2279,19 +2201,6 @@ class BluetoothDeviceUnpairingResponse final : public ProtoMessage {
|
||||
|
||||
protected:
|
||||
};
|
||||
class UnsubscribeBluetoothLEAdvertisementsRequest final : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 87;
|
||||
static constexpr uint8_t ESTIMATED_SIZE = 0;
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *message_name() const override { return "unsubscribe_bluetooth_le_advertisements_request"; }
|
||||
#endif
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
const char *dump_to(DumpBuffer &out) const override;
|
||||
#endif
|
||||
|
||||
protected:
|
||||
};
|
||||
class BluetoothDeviceClearCacheResponse final : public ProtoMessage {
|
||||
public:
|
||||
static constexpr uint8_t MESSAGE_TYPE = 88;
|
||||
|
||||
@@ -764,10 +764,6 @@ const char *PingResponse::dump_to(DumpBuffer &out) const {
|
||||
out.append("PingResponse {}");
|
||||
return out.c_str();
|
||||
}
|
||||
const char *DeviceInfoRequest::dump_to(DumpBuffer &out) const {
|
||||
out.append("DeviceInfoRequest {}");
|
||||
return out.c_str();
|
||||
}
|
||||
#ifdef USE_AREAS
|
||||
const char *AreaInfo::dump_to(DumpBuffer &out) const {
|
||||
MessageDumpHelper helper(out, "AreaInfo");
|
||||
@@ -848,18 +844,10 @@ const char *DeviceInfoResponse::dump_to(DumpBuffer &out) const {
|
||||
#endif
|
||||
return out.c_str();
|
||||
}
|
||||
const char *ListEntitiesRequest::dump_to(DumpBuffer &out) const {
|
||||
out.append("ListEntitiesRequest {}");
|
||||
return out.c_str();
|
||||
}
|
||||
const char *ListEntitiesDoneResponse::dump_to(DumpBuffer &out) const {
|
||||
out.append("ListEntitiesDoneResponse {}");
|
||||
return out.c_str();
|
||||
}
|
||||
const char *SubscribeStatesRequest::dump_to(DumpBuffer &out) const {
|
||||
out.append("SubscribeStatesRequest {}");
|
||||
return out.c_str();
|
||||
}
|
||||
#ifdef USE_BINARY_SENSOR
|
||||
const char *ListEntitiesBinarySensorResponse::dump_to(DumpBuffer &out) const {
|
||||
MessageDumpHelper helper(out, "ListEntitiesBinarySensorResponse");
|
||||
@@ -1191,10 +1179,6 @@ const char *NoiseEncryptionSetKeyResponse::dump_to(DumpBuffer &out) const {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_API_HOMEASSISTANT_SERVICES
|
||||
const char *SubscribeHomeassistantServicesRequest::dump_to(DumpBuffer &out) const {
|
||||
out.append("SubscribeHomeassistantServicesRequest {}");
|
||||
return out.c_str();
|
||||
}
|
||||
const char *HomeassistantServiceMap::dump_to(DumpBuffer &out) const {
|
||||
MessageDumpHelper helper(out, "HomeassistantServiceMap");
|
||||
dump_field(out, "key", this->key);
|
||||
@@ -1245,10 +1229,6 @@ const char *HomeassistantActionResponse::dump_to(DumpBuffer &out) const {
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
const char *SubscribeHomeAssistantStatesRequest::dump_to(DumpBuffer &out) const {
|
||||
out.append("SubscribeHomeAssistantStatesRequest {}");
|
||||
return out.c_str();
|
||||
}
|
||||
const char *SubscribeHomeAssistantStateResponse::dump_to(DumpBuffer &out) const {
|
||||
MessageDumpHelper helper(out, "SubscribeHomeAssistantStateResponse");
|
||||
dump_field(out, "entity_id", this->entity_id);
|
||||
@@ -1924,10 +1904,6 @@ const char *BluetoothGATTNotifyDataResponse::dump_to(DumpBuffer &out) const {
|
||||
dump_bytes_field(out, "data", this->data_ptr_, this->data_len_);
|
||||
return out.c_str();
|
||||
}
|
||||
const char *SubscribeBluetoothConnectionsFreeRequest::dump_to(DumpBuffer &out) const {
|
||||
out.append("SubscribeBluetoothConnectionsFreeRequest {}");
|
||||
return out.c_str();
|
||||
}
|
||||
const char *BluetoothConnectionsFreeResponse::dump_to(DumpBuffer &out) const {
|
||||
MessageDumpHelper helper(out, "BluetoothConnectionsFreeResponse");
|
||||
dump_field(out, "free", this->free);
|
||||
@@ -1970,10 +1946,6 @@ const char *BluetoothDeviceUnpairingResponse::dump_to(DumpBuffer &out) const {
|
||||
dump_field(out, "error", this->error);
|
||||
return out.c_str();
|
||||
}
|
||||
const char *UnsubscribeBluetoothLEAdvertisementsRequest::dump_to(DumpBuffer &out) const {
|
||||
out.append("UnsubscribeBluetoothLEAdvertisementsRequest {}");
|
||||
return out.c_str();
|
||||
}
|
||||
const char *BluetoothDeviceClearCacheResponse::dump_to(DumpBuffer &out) const {
|
||||
MessageDumpHelper helper(out, "BluetoothDeviceClearCacheResponse");
|
||||
dump_field(out, "address", this->address);
|
||||
|
||||
@@ -27,7 +27,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
||||
case DisconnectRequest::MESSAGE_TYPE: // No setup required
|
||||
case PingRequest::MESSAGE_TYPE: // No setup required
|
||||
break;
|
||||
case DeviceInfoRequest::MESSAGE_TYPE: // Connection setup only
|
||||
case 9 /* DeviceInfoRequest is empty */: // Connection setup only
|
||||
if (!this->check_connection_setup_()) {
|
||||
return;
|
||||
}
|
||||
@@ -76,21 +76,21 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
||||
this->on_ping_response();
|
||||
break;
|
||||
}
|
||||
case DeviceInfoRequest::MESSAGE_TYPE: {
|
||||
case 9 /* DeviceInfoRequest is empty */: {
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
this->log_receive_message_(LOG_STR("on_device_info_request"));
|
||||
#endif
|
||||
this->on_device_info_request();
|
||||
break;
|
||||
}
|
||||
case ListEntitiesRequest::MESSAGE_TYPE: {
|
||||
case 11 /* ListEntitiesRequest is empty */: {
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
this->log_receive_message_(LOG_STR("on_list_entities_request"));
|
||||
#endif
|
||||
this->on_list_entities_request();
|
||||
break;
|
||||
}
|
||||
case SubscribeStatesRequest::MESSAGE_TYPE: {
|
||||
case 20 /* SubscribeStatesRequest is empty */: {
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
this->log_receive_message_(LOG_STR("on_subscribe_states_request"));
|
||||
#endif
|
||||
@@ -151,7 +151,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_API_HOMEASSISTANT_SERVICES
|
||||
case SubscribeHomeassistantServicesRequest::MESSAGE_TYPE: {
|
||||
case 34 /* SubscribeHomeassistantServicesRequest is empty */: {
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
this->log_receive_message_(LOG_STR("on_subscribe_homeassistant_services_request"));
|
||||
#endif
|
||||
@@ -169,7 +169,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
||||
break;
|
||||
}
|
||||
#ifdef USE_API_HOMEASSISTANT_STATES
|
||||
case SubscribeHomeAssistantStatesRequest::MESSAGE_TYPE: {
|
||||
case 38 /* SubscribeHomeAssistantStatesRequest is empty */: {
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
this->log_receive_message_(LOG_STR("on_subscribe_home_assistant_states_request"));
|
||||
#endif
|
||||
@@ -376,7 +376,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_BLUETOOTH_PROXY
|
||||
case SubscribeBluetoothConnectionsFreeRequest::MESSAGE_TYPE: {
|
||||
case 80 /* SubscribeBluetoothConnectionsFreeRequest is empty */: {
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
this->log_receive_message_(LOG_STR("on_subscribe_bluetooth_connections_free_request"));
|
||||
#endif
|
||||
@@ -385,7 +385,7 @@ void APIServerConnectionBase::read_message(uint32_t msg_size, uint32_t msg_type,
|
||||
}
|
||||
#endif
|
||||
#ifdef USE_BLUETOOTH_PROXY
|
||||
case UnsubscribeBluetoothLEAdvertisementsRequest::MESSAGE_TYPE: {
|
||||
case 87 /* UnsubscribeBluetoothLEAdvertisementsRequest is empty */: {
|
||||
#ifdef HAS_PROTO_MESSAGE_DUMP
|
||||
this->log_receive_message_(LOG_STR("on_unsubscribe_bluetooth_le_advertisements_request"));
|
||||
#endif
|
||||
|
||||
@@ -2277,6 +2277,12 @@ ifdefs: dict[str, str] = {}
|
||||
# Track messages with no fields (empty messages) for parameter elision
|
||||
EMPTY_MESSAGES: set[str] = set()
|
||||
|
||||
# Track empty SOURCE_CLIENT messages that don't need class generation
|
||||
# These messages have no fields and are only received (never sent), so the
|
||||
# class definition (vtable, dump_to, message_name, ESTIMATED_SIZE) is dead code
|
||||
# that the compiler compiles but the linker strips away.
|
||||
SKIP_CLASS_GENERATION: set[str] = set()
|
||||
|
||||
|
||||
def get_opt(
|
||||
desc: descriptor.DescriptorProto,
|
||||
@@ -2527,7 +2533,11 @@ def build_service_message_type(
|
||||
case += "#endif\n"
|
||||
case += f"this->{func}({'msg' if not is_empty else ''});\n"
|
||||
case += "break;"
|
||||
RECEIVE_CASES[id_] = (case, ifdef, mt.name)
|
||||
if mt.name in SKIP_CLASS_GENERATION:
|
||||
case_label = f"{id_} /* {mt.name} is empty */"
|
||||
else:
|
||||
case_label = f"{mt.name}::MESSAGE_TYPE"
|
||||
RECEIVE_CASES[id_] = (case, ifdef, case_label)
|
||||
|
||||
# Only close ifdef if we opened it
|
||||
if ifdef is not None:
|
||||
@@ -2723,6 +2733,19 @@ static void dump_bytes_field(DumpBuffer &out, const char *field_name, const uint
|
||||
|
||||
mt = file.message_type
|
||||
|
||||
# Identify empty SOURCE_CLIENT messages that don't need class generation
|
||||
for m in mt:
|
||||
if m.options.deprecated:
|
||||
continue
|
||||
if not m.options.HasExtension(pb.id):
|
||||
continue
|
||||
source = message_source_map.get(m.name)
|
||||
if source != SOURCE_CLIENT:
|
||||
continue
|
||||
has_fields = any(not field.options.deprecated for field in m.field)
|
||||
if not has_fields:
|
||||
SKIP_CLASS_GENERATION.add(m.name)
|
||||
|
||||
# Collect messages by base class
|
||||
base_class_groups = collect_messages_by_base_class(mt)
|
||||
|
||||
@@ -2755,6 +2778,10 @@ static void dump_bytes_field(DumpBuffer &out, const char *field_name, const uint
|
||||
if m.name not in used_messages and not m.options.HasExtension(pb.id):
|
||||
continue
|
||||
|
||||
# Skip class generation for empty SOURCE_CLIENT messages
|
||||
if m.name in SKIP_CLASS_GENERATION:
|
||||
continue
|
||||
|
||||
s, c, dc = build_message_type(m, base_class_fields, message_source_map)
|
||||
msg_ifdef = message_ifdef_map.get(m.name)
|
||||
|
||||
@@ -2901,10 +2928,18 @@ static const char *const TAG = "api.service";
|
||||
no_conn_ids: set[int] = set()
|
||||
conn_only_ids: set[int] = set()
|
||||
|
||||
for id_, (_, _, case_msg_name) in cases:
|
||||
if case_msg_name in message_auth_map:
|
||||
needs_auth = message_auth_map[case_msg_name]
|
||||
needs_conn = message_conn_map[case_msg_name]
|
||||
# Build a reverse lookup from message id to message name for auth lookups
|
||||
id_to_msg_name: dict[int, str] = {}
|
||||
for mt in file.message_type:
|
||||
id_ = get_opt(mt, pb.id)
|
||||
if id_ is not None and not mt.options.deprecated:
|
||||
id_to_msg_name[id_] = mt.name
|
||||
|
||||
for id_, (_, _, case_label) in cases:
|
||||
msg_name = id_to_msg_name.get(id_, "")
|
||||
if msg_name in message_auth_map:
|
||||
needs_auth = message_auth_map[msg_name]
|
||||
needs_conn = message_conn_map[msg_name]
|
||||
|
||||
if not needs_conn:
|
||||
no_conn_ids.add(id_)
|
||||
@@ -2915,10 +2950,10 @@ static const char *const TAG = "api.service";
|
||||
def generate_cases(ids: set[int], comment: str) -> str:
|
||||
result = ""
|
||||
for id_ in sorted(ids):
|
||||
_, ifdef, msg_name = RECEIVE_CASES[id_]
|
||||
_, ifdef, case_label = RECEIVE_CASES[id_]
|
||||
if ifdef:
|
||||
result += f"#ifdef {ifdef}\n"
|
||||
result += f" case {msg_name}::MESSAGE_TYPE: {comment}\n"
|
||||
result += f" case {case_label}: {comment}\n"
|
||||
if ifdef:
|
||||
result += "#endif\n"
|
||||
return result
|
||||
@@ -2958,11 +2993,11 @@ static const char *const TAG = "api.service";
|
||||
|
||||
# Dispatch switch
|
||||
out += " switch (msg_type) {\n"
|
||||
for i, (case, ifdef, message_name) in cases:
|
||||
for i, (case, ifdef, case_label) in cases:
|
||||
if ifdef is not None:
|
||||
out += f"#ifdef {ifdef}\n"
|
||||
|
||||
c = f" case {message_name}::MESSAGE_TYPE: {{\n"
|
||||
c = f" case {case_label}: {{\n"
|
||||
c += indent(case, " ") + "\n"
|
||||
c += " }"
|
||||
out += c + "\n"
|
||||
|
||||
Reference in New Issue
Block a user