Repository navigation
Description
Problem
Deciding what kind of value a YAML scalar is happens in two parallel switches over the resolved tag:
value.scalarValue(compilers/openapi/internal/value/value.go) lowers a scalar to anir.Value.rawConv.scalar(compilers/openapi/internal/annotation/rawjson.go) renders a scalar as canonical JSON forUnmodeledand other raw payloads.
They have already diverged on one input (#783), and each re-derives rules that must agree: which tags are numbers, how a !!int base prefix and _ separators are read (value.NumericLiteral, which rawConv calls), what an unquoted !!str that is a decimal literal means, and what a !!timestamp or !!binary keeps. A rule added to one is invisible to the other, and nothing compares them.
Some differences are deliberate and must survive: a !!binary is decoded to bytes in ir.Value and kept as its source spelling in a raw payload (#242). The disagreement that matters is classification, not rendering.
Other sites read tags for narrower purposes (load/load.go, load/mappings.go, detect.go) and are in scope only where they classify a scalar rather than test for one tag.
Proposed direction
Split classification from rendering. One function in compilers/openapi/internal decides the kind of a scalar node (null, bool, number with its ir.BigVal, string, timestamp, binary, unresolved tag) and returns it. value and annotation each render from that, keeping their own output forms.
It stays inside compilers/openapi/internal. Promotion into compilers/compile needs evidence from all three compilers (docs/micro-compiler-design.md §3), and the GraphQL and Protobuf drafts parse SDL and .proto rather than YAML, so they offer none.
Acceptance
value.scalarValueandrawConv.scalarboth call the classifier; neither switches on the tag itself.- A table-driven test enumerates tag × style × spelling (plain, quoted, base-prefixed, separator, out-of-range, timestamp, binary, unknown tag) and asserts the two renderers agree on kind for every row.
- Fixing openapi: a number beyond float64 range is a JSON number in an enum and a string in a vendor extension #783 is a consequence of the change, or lands first; either order is fine.
- Goldens are unchanged apart from the rows openapi: a number beyond float64 range is a JSON number in an enum and a string in a vendor extension #783 moves.
Activity
OmarAlJarrah commentedon Oct 20, 2026
#1016 moves two of these tag tests. At 83ab508
load/mappings.gois deleted. ItsScalarNode && Tag == "!!bool"test is nowbind.schemaShaped, and the!!nulltest on a$ref's value moved frombind/bind.gotobind.docs.refOf, both incompilers/openapi/internal/bind/documents.go. No new classifier was added.