Merge remote-tracking branch 'origin/api_varint_split_32_64' into integration

This commit is contained in:
J. Nick Koston
2026-02-19 20:25:25 -06:00
4 changed files with 37 additions and 15 deletions

View File

@@ -2,10 +2,6 @@
// See script/api_protobuf/api_protobuf.py
#pragma once
#include "esphome/core/defines.h"
#ifdef USE_BLUETOOTH_PROXY
#define USE_API_VARINT64
#endif
#include "esphome/core/string_ref.h"
#include "proto.h"

View File

@@ -0,0 +1,12 @@
// This file was automatically generated with a tool.
// See script/api_protobuf/api_protobuf.py
#pragma once
#include "esphome/core/defines.h"
#ifdef USE_BLUETOOTH_PROXY
#ifndef USE_API_VARINT64
#define USE_API_VARINT64
#endif
#endif
namespace esphome::api {} // namespace esphome::api

View File

@@ -1,5 +1,6 @@
#pragma once
#include "api_pb2_defines.h"
#include "esphome/core/component.h"
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
@@ -118,7 +119,7 @@ class ProtoVarInt {
}
// 32-bit phase: process remaining bytes with native 32-bit shifts.
// Without USE_API_VARINT64: cover bytes 1-4 (shifts 7, 14, 21, 28) — the uint32_t
// shift at byte 4 truncates upper bits but those are always zero for valid uint32 values.
// shift at byte 4 (shift by 28) may lose bits 32-34, but those are always zero for valid uint32 values.
// With USE_API_VARINT64: cover bytes 1-3 (shifts 7, 14, 21) so parse_wide handles
// byte 4+ with full 64-bit arithmetic (avoids truncating values > UINT32_MAX).
uint32_t result32 = buffer[0] & 0x7F;

View File

@@ -1937,6 +1937,9 @@ def get_varint64_ifdef(
}
if not ifdefs:
return False, None
if None in ifdefs:
# At least one 64-bit varint field is unconditional, so the guard must be unconditional.
return True, None
ifdefs.discard(None)
return True, ifdefs.pop() if len(ifdefs) == 1 else None
@@ -2601,22 +2604,32 @@ def main() -> None:
)
# Find the ifdef guard for 64-bit varint fields (int64/uint64/sint64).
# Emitted before proto.h so parse_wide_() and 64-bit accessors are available.
# Generated into api_pb2_defines.h so proto.h can include it, ensuring
# consistent ProtoVarInt layout across all translation units.
has_varint64, varint64_guard = get_varint64_ifdef(file, message_ifdef_map)
# Generate api_pb2_defines.h — included by proto.h to ensure all translation
# units see USE_API_VARINT64 consistently (avoids ODR violations in ProtoVarInt).
defines_content = FILE_HEADER
defines_content += "#pragma once\n\n"
defines_content += '#include "esphome/core/defines.h"\n'
if has_varint64:
lines = [
"#ifndef USE_API_VARINT64",
"#define USE_API_VARINT64",
"#endif",
]
defines_content += "\n".join(wrap_with_ifdef(lines, varint64_guard))
defines_content += "\n"
defines_content += "\nnamespace esphome::api {} // namespace esphome::api\n"
with open(root / "api_pb2_defines.h", "w", encoding="utf-8") as f:
f.write(defines_content)
content = FILE_HEADER
content += """\
#pragma once
#include "esphome/core/defines.h"
"""
if has_varint64:
content += "\n".join(
wrap_with_ifdef(["#define USE_API_VARINT64"], varint64_guard)
)
content += "\n"
content += """\
#include "esphome/core/string_ref.h"
#include "proto.h"