mirror of
https://github.com/luxfi/zap.git
synced 2026-10-30 15:04:16 +00:00
The repeated-message wire shape: a list whose elements carry their own
variable-length tails (string/bytes/nested), which the fixed-stride inline
List cannot hold. Completes proto field-shape coverage in the runtime —
map<k,v> reduces to a repeated {key,value} entry, so this is its keystone too.
Composition, not a new wire concept: ListNested = List ∘ NestedAt. The list
slots are a contiguous stride-4 object-pointer array; each pointer is
followed exactly as a singular nested pointer to an out-of-line tailed View.
Runtime:
- builder.go: ListBuilder.AddObjectPtr(targetPos) — appends a signed 4-byte
relative object pointer (the repeated-message element kind).
- v1/list_nested.go: ListNested[N] (Len/At/All/IsZero), ListNestedAt[S,N]
(read), WriteListNested[S,N] + NestedElemSetter[N] (write). Same audited
bounds discipline as Object.Object / ListStride (RED-HIGH-1/2 inherited).
Codegen:
- elemIsTailed: a list element with a string/bytes/nested/list sub-field
auto-routes to ListNested/WriteListNested/ListNestedAt; scalar-only
elements stay in the tighter inline List/WriteList/ListAt. One Elem
declaration, the generator picks the correct encoding.
Proven end-to-end: runtime roundtrip (3 elements each with its OWN string
tail, via At and All, + empty), emit routing test (tailed->ListNested,
scalar-only->List), and a generated-code wire roundtrip (testpkg/repeatwire).
Root zap + full v1+codegen suite green; scalar listwire unchanged (no regression).
124 lines
3.3 KiB
Go
124 lines
3.3 KiB
Go
// Copyright (C) 2026, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
// Command gennest generates the nestwire test package: a singular nested
|
|
// object (Outer carrying an Inner that itself has a string tail). It is the
|
|
// nested-field peer of the one-off that produced testpkg/listwire, and
|
|
// proves the codegen's WriteNested/NestedAt emission round-trips on the
|
|
// wire (see testpkg/nestwire/roundtrip_test.go).
|
|
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
|
|
"github.com/luxfi/zap/v1/codegen"
|
|
)
|
|
|
|
func main() {
|
|
inner := codegen.Schema{
|
|
GoName: "InnerSchema",
|
|
WireName: "Inner",
|
|
Kind: 0x52,
|
|
Size: 16, // ID @0 (u64), Label @8 (string tail-ptr)
|
|
Package: "nestwire",
|
|
Element: true,
|
|
Fields: []codegen.Field{
|
|
{Name: "ID", Type: "uint64", Offset: 0},
|
|
{Name: "Label", Type: "string", Offset: 8},
|
|
},
|
|
}
|
|
outer := codegen.Schema{
|
|
GoName: "OuterSchema",
|
|
WireName: "Outer",
|
|
Kind: 0x51,
|
|
Size: 13, // kind@0, Seq@1 (u64), Inner@9 (object-ptr, 4 bytes)
|
|
Package: "nestwire",
|
|
Fields: []codegen.Field{
|
|
{Name: "Seq", Type: "uint64", Offset: 1},
|
|
{Name: "Inner", Offset: 9, Nested: &codegen.NestedMsg{
|
|
Schema: "InnerSchema",
|
|
Wire: "Inner",
|
|
Value: "Inner",
|
|
Fields: []codegen.Field{
|
|
{Name: "ID", Type: "uint64", Offset: 0},
|
|
{Name: "Label", Type: "string", Offset: 8},
|
|
},
|
|
}},
|
|
},
|
|
}
|
|
|
|
// repeatwire: a parent with a REPEATED tailed child (each child has a
|
|
// string), which the codegen must route to ListNested (not the inline
|
|
// List, whose fixed stride can't hold per-element tails).
|
|
childR := codegen.Schema{
|
|
GoName: "ChildSchema",
|
|
WireName: "Child",
|
|
Kind: 0x62,
|
|
Size: 16, // ID @0 (u64), Name @8 (string tail-ptr)
|
|
Package: "repeatwire",
|
|
Element: true,
|
|
Fields: []codegen.Field{
|
|
{Name: "ID", Type: "uint64", Offset: 0},
|
|
{Name: "Name", Type: "string", Offset: 8},
|
|
},
|
|
}
|
|
parentR := codegen.Schema{
|
|
GoName: "ParentSchema",
|
|
WireName: "Parent",
|
|
Kind: 0x61,
|
|
Size: 17, // kind@0, Count@1 (u64), Children@9 (list-ptr, 8 bytes)
|
|
Package: "repeatwire",
|
|
Fields: []codegen.Field{
|
|
{Name: "Count", Type: "uint64", Offset: 1},
|
|
{Name: "Children", Offset: 9, Elem: &codegen.ListElem{
|
|
Schema: "ChildSchema",
|
|
Wire: "Child",
|
|
Value: "Child",
|
|
Stride: 16,
|
|
Fields: []codegen.Field{
|
|
{Name: "ID", Type: "uint64", Offset: 0},
|
|
{Name: "Name", Type: "string", Offset: 8},
|
|
},
|
|
}},
|
|
},
|
|
}
|
|
|
|
for _, grp := range []struct {
|
|
pkg string
|
|
schemas []struct {
|
|
s codegen.Schema
|
|
out string
|
|
}
|
|
}{
|
|
{"nestwire", []struct {
|
|
s codegen.Schema
|
|
out string
|
|
}{{inner, "inner_zap.go"}, {outer, "outer_zap.go"}}},
|
|
{"repeatwire", []struct {
|
|
s codegen.Schema
|
|
out string
|
|
}{{childR, "child_zap.go"}, {parentR, "parent_zap.go"}}},
|
|
} {
|
|
dir := filepath.Join("v1", "codegen", "testpkg", grp.pkg)
|
|
if err := os.MkdirAll(dir, 0o755); err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
for _, sc := range grp.schemas {
|
|
f, err := os.Create(filepath.Join(dir, sc.out))
|
|
if err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
if err := codegen.Emit(f, sc.s); err != nil {
|
|
fmt.Fprintln(os.Stderr, err)
|
|
os.Exit(1)
|
|
}
|
|
f.Close()
|
|
fmt.Println("wrote", filepath.Join(dir, sc.out))
|
|
}
|
|
}
|
|
}
|