mirror of
https://github.com/esphome/esphome.git
synced 2026-09-17 18:18:43 +00:00
[api] Add max_data_length proto option and optimize entity name/object_id
Add max_data_length field option for string/bytes fields. When max_data_length < 128, the codegen emits constant-size length varint calculations and direct byte writes. Annotate all entity name and object_id fields with (max_data_length) = 120 and (force) = true across all 25 ListEntities*Response messages (50 fields). Generated code changes: - calculate_size: `calc_length(1, size)` -> `2 + size` (constant) - encode: `encode_string(N, ref)` -> `write_raw_byte(tag) + write_raw_byte(len) + encode_raw(data, len)` Eliminates 2 function calls per field per entity list response, removes zero-check branches, and removes varint size computation.
This commit is contained in:
@@ -161,6 +161,11 @@ class TypeInfo(ABC):
|
||||
"""Get the max_value option for this field, or None if not set."""
|
||||
return get_field_opt(self._field, pb.max_value, None)
|
||||
|
||||
@property
|
||||
def max_data_length(self) -> int | None:
|
||||
"""Get the max_data_length option for this field, or None if not set."""
|
||||
return get_field_opt(self._field, pb.max_data_length, None)
|
||||
|
||||
@property
|
||||
def wire_type(self) -> WireType:
|
||||
"""Get the wire type for the field."""
|
||||
@@ -1064,7 +1069,9 @@ class PointerToStringBufferType(PointerToBufferTypeBase):
|
||||
@property
|
||||
def encode_content(self) -> str:
|
||||
if result := self._encode_bytes_with_precomputed_tag(
|
||||
f"this->{self.field_name}.c_str()", f"this->{self.field_name}.size()"
|
||||
f"this->{self.field_name}.c_str()",
|
||||
f"this->{self.field_name}.size()",
|
||||
max_len=self.max_data_length,
|
||||
):
|
||||
return result
|
||||
if self.force:
|
||||
@@ -1089,7 +1096,13 @@ class PointerToStringBufferType(PointerToBufferTypeBase):
|
||||
return f'dump_field(out, ESPHOME_PSTR("{self.name}"), this->{self.field_name});'
|
||||
|
||||
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
||||
return f"size += ProtoSize::calc_length({self.calculate_field_id_size()}, this->{self.field_name}.size());"
|
||||
size_field = f"this->{self.field_name}.size()"
|
||||
max_len = self.max_data_length
|
||||
if max_len is not None and max_len < 128:
|
||||
return self._get_single_byte_varint_size(
|
||||
size_field, force, extra_expr=size_field
|
||||
)
|
||||
return self._get_simple_size_calculation(size_field, force, "length")
|
||||
|
||||
def get_estimated_size(self) -> int:
|
||||
return self.calculate_field_id_size() + 8 # field ID + 8 bytes typical string
|
||||
|
||||
Reference in New Issue
Block a user