mirror of
https://github.com/esphome/esphome.git
synced 2025-07-25 20:56:38 +00:00
cleans to dump
This commit is contained in:
parent
a614a68f1a
commit
fbd3c051ec
File diff suppressed because it is too large
Load Diff
@ -224,12 +224,26 @@ class TypeInfo(ABC):
|
|||||||
|
|
||||||
encode_func = None
|
encode_func = None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def can_use_dump_field(cls) -> bool:
|
||||||
|
"""Whether this type can use the dump_field helper functions.
|
||||||
|
|
||||||
|
Returns True for simple types that have dump_field overloads.
|
||||||
|
Complex types like messages and bytes should return False.
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
def dump_field_value(self, value: str) -> str:
|
||||||
|
"""Get the value expression to pass to dump_field.
|
||||||
|
|
||||||
|
Most types just pass the value directly, but some (like enums) need a cast.
|
||||||
|
"""
|
||||||
|
return value
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dump_content(self) -> str:
|
def dump_content(self) -> str:
|
||||||
o = f'out.append(" {self.name}: ");\n'
|
# Default implementation - subclasses can override if they need special handling
|
||||||
o += self.dump(f"this->{self.field_name}") + "\n"
|
return f'dump_field(out, "{self.name}", {self.dump_field_value(f"this->{self.field_name}")});\n'
|
||||||
o += 'out.append("\\n");\n'
|
|
||||||
return o
|
|
||||||
|
|
||||||
@abstractmethod
|
@abstractmethod
|
||||||
def dump(self, name: str) -> str:
|
def dump(self, name: str) -> str:
|
||||||
@ -593,6 +607,22 @@ class StringType(TypeInfo):
|
|||||||
f"}}"
|
f"}}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def dump_content(self) -> str:
|
||||||
|
# For SOURCE_CLIENT only, use std::string
|
||||||
|
if not self._needs_encode:
|
||||||
|
return f'dump_field(out, "{self.name}", this->{self.field_name});'
|
||||||
|
|
||||||
|
# For SOURCE_SERVER, use StringRef with _ref_ suffix
|
||||||
|
if not self._needs_decode:
|
||||||
|
return f'dump_field(out, "{self.name}", this->{self.field_name}_ref_);'
|
||||||
|
|
||||||
|
# For SOURCE_BOTH, we need custom logic
|
||||||
|
o = f'out.append(" {self.name}: ");\n'
|
||||||
|
o += self.dump(f"this->{self.field_name}") + "\n"
|
||||||
|
o += 'out.append("\\n");\n'
|
||||||
|
return o
|
||||||
|
|
||||||
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
||||||
# For SOURCE_CLIENT only messages, use the string field directly
|
# For SOURCE_CLIENT only messages, use the string field directly
|
||||||
if not self._needs_encode:
|
if not self._needs_encode:
|
||||||
@ -615,6 +645,10 @@ class StringType(TypeInfo):
|
|||||||
|
|
||||||
@register_type(11)
|
@register_type(11)
|
||||||
class MessageType(TypeInfo):
|
class MessageType(TypeInfo):
|
||||||
|
@classmethod
|
||||||
|
def can_use_dump_field(cls) -> bool:
|
||||||
|
return False
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def cpp_type(self) -> str:
|
def cpp_type(self) -> str:
|
||||||
return self._field.type_name[1:]
|
return self._field.type_name[1:]
|
||||||
@ -651,6 +685,13 @@ class MessageType(TypeInfo):
|
|||||||
o = f"{name}.dump_to(out);"
|
o = f"{name}.dump_to(out);"
|
||||||
return o
|
return o
|
||||||
|
|
||||||
|
@property
|
||||||
|
def dump_content(self) -> str:
|
||||||
|
o = f'out.append(" {self.name}: ");\n'
|
||||||
|
o += f"this->{self.field_name}.dump_to(out);\n"
|
||||||
|
o += 'out.append("\\n");\n'
|
||||||
|
return o
|
||||||
|
|
||||||
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
||||||
return self._get_simple_size_calculation(name, force, "add_message_object")
|
return self._get_simple_size_calculation(name, force, "add_message_object")
|
||||||
|
|
||||||
@ -664,6 +705,10 @@ class MessageType(TypeInfo):
|
|||||||
|
|
||||||
@register_type(12)
|
@register_type(12)
|
||||||
class BytesType(TypeInfo):
|
class BytesType(TypeInfo):
|
||||||
|
@classmethod
|
||||||
|
def can_use_dump_field(cls) -> bool:
|
||||||
|
return False
|
||||||
|
|
||||||
cpp_type = "std::string"
|
cpp_type = "std::string"
|
||||||
default_value = ""
|
default_value = ""
|
||||||
reference_type = "std::string &"
|
reference_type = "std::string &"
|
||||||
@ -719,6 +764,13 @@ class BytesType(TypeInfo):
|
|||||||
f" }}"
|
f" }}"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def dump_content(self) -> str:
|
||||||
|
o = f'out.append(" {self.name}: ");\n'
|
||||||
|
o += self.dump(f"this->{self.field_name}") + "\n"
|
||||||
|
o += 'out.append("\\n");\n'
|
||||||
|
return o
|
||||||
|
|
||||||
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
||||||
return f"ProtoSize::add_bytes_field(total_size, {self.calculate_field_id_size()}, this->{self.field_name}_len_);"
|
return f"ProtoSize::add_bytes_field(total_size, {self.calculate_field_id_size()}, this->{self.field_name}_len_);"
|
||||||
|
|
||||||
@ -729,6 +781,10 @@ class BytesType(TypeInfo):
|
|||||||
class FixedArrayBytesType(TypeInfo):
|
class FixedArrayBytesType(TypeInfo):
|
||||||
"""Special type for fixed-size byte arrays."""
|
"""Special type for fixed-size byte arrays."""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def can_use_dump_field(cls) -> bool:
|
||||||
|
return False
|
||||||
|
|
||||||
def __init__(self, field: descriptor.FieldDescriptorProto, size: int) -> None:
|
def __init__(self, field: descriptor.FieldDescriptorProto, size: int) -> None:
|
||||||
super().__init__(field)
|
super().__init__(field)
|
||||||
self.array_size = size
|
self.array_size = size
|
||||||
@ -778,6 +834,13 @@ class FixedArrayBytesType(TypeInfo):
|
|||||||
o = f"out.append(format_hex_pretty({name}, {name}_len));"
|
o = f"out.append(format_hex_pretty({name}, {name}_len));"
|
||||||
return o
|
return o
|
||||||
|
|
||||||
|
@property
|
||||||
|
def dump_content(self) -> str:
|
||||||
|
o = f'out.append(" {self.name}: ");\n'
|
||||||
|
o += f"out.append(format_hex_pretty(this->{self.field_name}, this->{self.field_name}_len));\n"
|
||||||
|
o += 'out.append("\\n");\n'
|
||||||
|
return o
|
||||||
|
|
||||||
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
||||||
# Use the actual length stored in the _len field
|
# Use the actual length stored in the _len field
|
||||||
length_field = f"this->{self.field_name}_len"
|
length_field = f"this->{self.field_name}_len"
|
||||||
@ -850,6 +913,10 @@ class EnumType(TypeInfo):
|
|||||||
o = f"out.append(proto_enum_to_string<{self.cpp_type}>({name}));"
|
o = f"out.append(proto_enum_to_string<{self.cpp_type}>({name}));"
|
||||||
return o
|
return o
|
||||||
|
|
||||||
|
def dump_field_value(self, value: str) -> str:
|
||||||
|
# Enums need explicit cast for the template
|
||||||
|
return f"static_cast<{self.cpp_type}>({value})"
|
||||||
|
|
||||||
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
def get_size_calculation(self, name: str, force: bool = False) -> str:
|
||||||
return self._get_simple_size_calculation(
|
return self._get_simple_size_calculation(
|
||||||
name, force, "add_enum_field", f"static_cast<uint32_t>({name})"
|
name, force, "add_enum_field", f"static_cast<uint32_t>({name})"
|
||||||
@ -947,6 +1014,27 @@ class SInt64Type(TypeInfo):
|
|||||||
return self.calculate_field_id_size() + 3 # field ID + 3 bytes typical varint
|
return self.calculate_field_id_size() + 3 # field ID + 3 bytes typical varint
|
||||||
|
|
||||||
|
|
||||||
|
def _generate_array_dump_content(
|
||||||
|
ti, field_name: str, name: str, is_bool: bool = False
|
||||||
|
) -> str:
|
||||||
|
"""Generate dump content for array types (repeated or fixed array).
|
||||||
|
|
||||||
|
Shared helper to avoid code duplication between RepeatedTypeInfo and FixedArrayRepeatedType.
|
||||||
|
"""
|
||||||
|
o = f"for (const auto {'' if is_bool else '&'}it : {field_name}) {{\n"
|
||||||
|
# Check if underlying type can use dump_field
|
||||||
|
if type(ti).can_use_dump_field():
|
||||||
|
# For types that have dump_field overloads, use them with extra indent
|
||||||
|
o += f' dump_field(out, "{name}", {ti.dump_field_value("it")}, 4);\n'
|
||||||
|
else:
|
||||||
|
# For complex types (messages, bytes), use the old pattern
|
||||||
|
o += f' out.append(" {name}: ");\n'
|
||||||
|
o += indent(ti.dump("it")) + "\n"
|
||||||
|
o += ' out.append("\\n");\n'
|
||||||
|
o += "}\n"
|
||||||
|
return o
|
||||||
|
|
||||||
|
|
||||||
class FixedArrayRepeatedType(TypeInfo):
|
class FixedArrayRepeatedType(TypeInfo):
|
||||||
"""Special type for fixed-size repeated fields using std::array.
|
"""Special type for fixed-size repeated fields using std::array.
|
||||||
|
|
||||||
@ -1013,12 +1101,9 @@ class FixedArrayRepeatedType(TypeInfo):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def dump_content(self) -> str:
|
def dump_content(self) -> str:
|
||||||
o = f"for (const auto &it : this->{self.field_name}) {{\n"
|
return _generate_array_dump_content(
|
||||||
o += f' out.append(" {self.name}: ");\n'
|
self._ti, f"this->{self.field_name}", self.name, is_bool=False
|
||||||
o += indent(self._ti.dump("it")) + "\n"
|
)
|
||||||
o += ' out.append("\\n");\n'
|
|
||||||
o += "}\n"
|
|
||||||
return o
|
|
||||||
|
|
||||||
def dump(self, name: str) -> str:
|
def dump(self, name: str) -> str:
|
||||||
# This is used when dumping the array itself (not its elements)
|
# This is used when dumping the array itself (not its elements)
|
||||||
@ -1144,12 +1229,9 @@ class RepeatedTypeInfo(TypeInfo):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def dump_content(self) -> str:
|
def dump_content(self) -> str:
|
||||||
o = f"for (const auto {'' if self._ti_is_bool else '&'}it : this->{self.field_name}) {{\n"
|
return _generate_array_dump_content(
|
||||||
o += f' out.append(" {self.name}: ");\n'
|
self._ti, f"this->{self.field_name}", self.name, is_bool=self._ti_is_bool
|
||||||
o += indent(self._ti.dump("it")) + "\n"
|
)
|
||||||
o += ' out.append("\\n");\n'
|
|
||||||
o += "}\n"
|
|
||||||
return o
|
|
||||||
|
|
||||||
def dump(self, _: str):
|
def dump(self, _: str):
|
||||||
pass
|
pass
|
||||||
@ -1644,7 +1726,6 @@ def build_message_type(
|
|||||||
dump_impl += f" {dump[0]} "
|
dump_impl += f" {dump[0]} "
|
||||||
else:
|
else:
|
||||||
dump_impl += "\n"
|
dump_impl += "\n"
|
||||||
dump_impl += " __attribute__((unused)) char buffer[64];\n"
|
|
||||||
dump_impl += f' out.append("{desc.name} {{\\n");\n'
|
dump_impl += f' out.append("{desc.name} {{\\n");\n'
|
||||||
dump_impl += indent("\n".join(dump)) + "\n"
|
dump_impl += indent("\n".join(dump)) + "\n"
|
||||||
dump_impl += ' out.append("}");\n'
|
dump_impl += ' out.append("}");\n'
|
||||||
@ -2004,6 +2085,72 @@ static inline void append_quoted_string(std::string &out, const StringRef &ref)
|
|||||||
out.append("'");
|
out.append("'");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper functions to reduce code duplication in dump methods
|
||||||
|
static void dump_field(std::string &out, const char *field_name, int32_t value, int indent = 2) {
|
||||||
|
char buffer[64];
|
||||||
|
out.append(indent, ' ').append(field_name).append(": ");
|
||||||
|
snprintf(buffer, 64, "%" PRId32, value);
|
||||||
|
out.append(buffer);
|
||||||
|
out.append("\\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_field(std::string &out, const char *field_name, uint32_t value, int indent = 2) {
|
||||||
|
char buffer[64];
|
||||||
|
out.append(indent, ' ').append(field_name).append(": ");
|
||||||
|
snprintf(buffer, 64, "%" PRIu32, value);
|
||||||
|
out.append(buffer);
|
||||||
|
out.append("\\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_field(std::string &out, const char *field_name, float value, int indent = 2) {
|
||||||
|
char buffer[64];
|
||||||
|
out.append(indent, ' ').append(field_name).append(": ");
|
||||||
|
snprintf(buffer, 64, "%g", value);
|
||||||
|
out.append(buffer);
|
||||||
|
out.append("\\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_field(std::string &out, const char *field_name, double value, int indent = 2) {
|
||||||
|
char buffer[64];
|
||||||
|
out.append(indent, ' ').append(field_name).append(": ");
|
||||||
|
snprintf(buffer, 64, "%g", value);
|
||||||
|
out.append(buffer);
|
||||||
|
out.append("\\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_field(std::string &out, const char *field_name, uint64_t value, int indent = 2) {
|
||||||
|
char buffer[64];
|
||||||
|
out.append(indent, ' ').append(field_name).append(": ");
|
||||||
|
snprintf(buffer, 64, "%llu", value);
|
||||||
|
out.append(buffer);
|
||||||
|
out.append("\\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_field(std::string &out, const char *field_name, bool value, int indent = 2) {
|
||||||
|
out.append(indent, ' ').append(field_name).append(": ");
|
||||||
|
out.append(YESNO(value));
|
||||||
|
out.append("\\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_field(std::string &out, const char *field_name, const std::string &value, int indent = 2) {
|
||||||
|
out.append(indent, ' ').append(field_name).append(": ");
|
||||||
|
out.append("'").append(value).append("'");
|
||||||
|
out.append("\\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dump_field(std::string &out, const char *field_name, StringRef value, int indent = 2) {
|
||||||
|
out.append(indent, ' ').append(field_name).append(": ");
|
||||||
|
append_quoted_string(out, value);
|
||||||
|
out.append("\\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static void dump_field(std::string &out, const char *field_name, T value, int indent = 2) {
|
||||||
|
out.append(indent, ' ').append(field_name).append(": ");
|
||||||
|
out.append(proto_enum_to_string<T>(value));
|
||||||
|
out.append("\\n");
|
||||||
|
}
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
content += "namespace enums {\n\n"
|
content += "namespace enums {\n\n"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user