- Combine tag byte + fixed32 value into single write_tag_and_fixed32()
method: pos[0] = tag, memcpy(pos+1, &value, 4), pos += 5
- Extract calculate_tag() from duplicated computation in
calculate_field_id_size() and encode_content
Instead of ALWAYS_INLINE on encode_field_raw (which bloated all
callers), have the code generator precompute the tag byte and emit
write_raw_byte(tag) + write_fixed32_raw(value) directly.
This gives the same tight codegen (single byte store + memcpy) for
key fields without inflating encode_bool/encode_uint32/etc.
+108 bytes flash vs baseline, -48 bytes vs the ALWAYS_INLINE approach.
- Update comments to reflect that ProtoService methods moved to
APIConnection, not APIServerConnectionBase
- Fix comment referring to read_message as "override"
- Wrap #include "api_connection.h" and read_message_ implementation
in #ifdef USE_API guards
The virtual destructor was unnecessary since APIConnection is only
stored as unique_ptr<APIConnection>, never via a base class pointer.
Removing it eliminates the vtable entirely.
Rename read_message to read_message_ per clang-tidy naming convention
for protected methods.
ProtoService was an abstract interface with 6 pure virtual methods,
but APIConnection was the only concrete implementation. Move all
functionality directly into APIConnection and remove the unnecessary
virtual dispatch and vtable overhead.
Move read_message() from APIServerConnectionBase into APIConnection
and drop the virtual keyword from all 64 on_* handler declarations.
Since APIConnection is final and the only subclass, the virtual
dispatch was unnecessary. With read_message and the on_* handlers
in the same class, the compiler can devirtualize the calls and
inline small handlers directly into the switch cases.
message_name() returned bare string literals that stayed in RAM on
ESP8266. Change return type to const LogString * and wrap with LOG_STR()
so they are stored in flash. Update log_send_message_ to use
LOG_STR_ARG() accordingly.
Also fix clang-tidy: rename append_p_esp8266_ to append_p_esp8266,
add NOLINTNEXTLINE for conditionally-unused dump_field overloads.
All string literals in api_pb2_dump.cpp (field names, message names,
enum value names) were stored in rodata which occupies RAM on ESP8266.
This meant every API protobuf change appeared as a RAM increase in CI
when using very_verbose logging.
Add append_p() to DumpBuffer for PROGMEM-safe string reading and update
the code generator to wrap all dump string literals with ESPHOME_PSTR().
On non-ESP8266 platforms, these are no-ops with zero overhead.
Co-authored-by: pre-commit-ci-lite[bot] <117423508+pre-commit-ci-lite[bot]@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
Co-authored-by: J. Nick Koston <nick@home-assistant.io>