Skip to content

Commit 8d8aae6

Browse files
rustyconoverclaude
andcommitted
cpp_records: include the secret protocol's results
SecretLookupResponse is emitted as SecretLookupResult, named after its method like every other result and matching its vgi_secret_protocol_schemas factory. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
1 parent 3f76054 commit 8d8aae6

1 file changed

Lines changed: 41 additions & 5 deletions

File tree

‎vgi/codegen/cpp_records.py‎

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,17 @@
8484
# Model
8585
# ---------------------------------------------------------------------------
8686

87+
#: C++ names beyond csharp_types.CSHARP_NAMES: method results are named after their
88+
#: method, matching their vgi_protocol_schemas / vgi_secret_protocol_schemas factory.
89+
CPP_NAMES: dict[str, str] = {
90+
"SecretLookupResponse": "SecretLookupResult",
91+
}
92+
93+
94+
def cpp_name(py_name: str) -> str:
95+
"""The C++ type name for a protocol type's Python name."""
96+
return CPP_NAMES.get(py_name) or cs.csharp_name(py_name)
97+
8798

8899
class Presence(enum.Enum):
89100
"""How a column's absence or null is decoded."""
@@ -171,7 +182,7 @@ def _ident(name: str) -> str:
171182

172183

173184
def _register_enum(cls: type[enum.Enum], model: _Model) -> str:
174-
name = cs.csharp_name(cls.__name__)
185+
name = cpp_name(cls.__name__)
175186
existing = model.enums.get(name)
176187
if existing is not None:
177188
if existing.origin != cls.__qualname__:
@@ -223,7 +234,7 @@ def _map(dtype: pa.DataType, annotation: object, *, model: _Model, origin: str)
223234
if not isinstance(base, type):
224235
raise GeneratorError(f"{origin}: a struct needs an annotated class to name its C++ type.")
225236
model.pending.append((base, [dtype.field(i) for i in range(dtype.num_fields)], origin))
226-
return cs.csharp_name(base.__name__)
237+
return cpp_name(base.__name__)
227238

228239
raise GeneratorError(
229240
f"vgi.codegen.cpp_records: unsupported Arrow type {dtype} at {origin}.\n"
@@ -253,7 +264,7 @@ def _literal(value: object, cpp_type: str, model: _Model, origin: str) -> str |
253264

254265

255266
def _layout(cls: type, arrow_fields: list[pa.Field[Any]], origin: str, model: _Model) -> _Record:
256-
name = cs.csharp_name(cls.__name__)
267+
name = cpp_name(cls.__name__)
257268
hints = cs._hints(cls)
258269
dc_fields = cs._dataclass_fields(cls)
259270
summary, attr_docs = cs._parse_docstring(cls)
@@ -280,10 +291,28 @@ def _layout(cls: type, arrow_fields: list[pa.Field[Any]], origin: str, model: _M
280291
return _Record(name, [origin], pa.schema(arrow_fields), members, cs._MERGED_DOCS.get(name, summary))
281292

282293

294+
def _secret_protocol_roots() -> list[tuple[type, str]]:
295+
"""Unary results of :class:`vgi.secret_protocol.VgiSecretProtocol` (the C++ client reads them too)."""
296+
from vgi_rpc.rpc._types import MethodType, rpc_methods # type: ignore[attr-defined]
297+
298+
from vgi.secret_protocol import VgiSecretProtocol
299+
300+
roots: list[tuple[type, str]] = []
301+
methods = rpc_methods(VgiSecretProtocol)
302+
for method_name in sorted(methods):
303+
info = methods[method_name]
304+
if info.method_type != MethodType.UNARY or not info.has_return:
305+
continue
306+
result, _ = cs._base(info.result_type)
307+
if isinstance(getattr(result, "ARROW_SCHEMA", None), pa.Schema):
308+
roots.append((result, f"secret method '{method_name}' result")) # type: ignore[arg-type]
309+
return roots
310+
311+
283312
def build_model() -> _Model:
284313
"""Lay out every record and enum the protocol defines, as C++ sees them."""
285314
model = _Model()
286-
for cls, origin in cs._root_types():
315+
for cls, origin in (*cs._root_types(), *_secret_protocol_roots()):
287316
model.pending.append((cls, list(cls.ARROW_SCHEMA), origin)) # type: ignore[attr-defined]
288317
while model.pending:
289318
cls, arrow_fields, origin = model.pending.pop(0)
@@ -429,6 +458,7 @@ def _render_source(model: _Model, namespace: list[str]) -> str:
429458
out = io.StringIO()
430459
out.write(f'#include "{HEADER_NAME}"\n\n')
431460
out.write('#include "vgi_protocol_schemas.hpp"\n')
461+
out.write('#include "vgi_secret_protocol_schemas.hpp"\n')
432462
out.write('#include "vgi_wire_codec.hpp"\n\n')
433463
out.write("#include <arrow/api.h>\n\n")
434464
out.write(open_namespace(namespace))
@@ -527,7 +557,13 @@ def _factory_names() -> set[str]:
527557
"""Stems of the schema factories vgi_protocol_schemas.hpp emits (see cpp_schemas.emit)."""
528558
from vgi.codegen._common import EXTRA_RESPONSE_TYPES, REQUEST_TYPES, collect_schemas
529559

530-
return {s.name for s in collect_schemas(extra_response_types=(*EXTRA_RESPONSE_TYPES, *REQUEST_TYPES))}
560+
from vgi.secret_protocol import VgiSecretProtocol
561+
562+
names = {s.name for s in collect_schemas(extra_response_types=(*EXTRA_RESPONSE_TYPES, *REQUEST_TYPES))}
563+
secret = collect_schemas(
564+
VgiSecretProtocol, info_types=(), extra_response_types=(), check_info_subclasses=False
565+
)
566+
return names | {s.name for s in secret}
531567

532568

533569
_REGEN = ["uv run --project ~/Development/vgi-python python scripts/regen_generated.py"]

0 commit comments

Comments
 (0)