Summary
annotation.RawChildNode searches a mapping's raw yaml.Node pairs. The parser
does not: marshaller reads a mapping through its << merge keys, so a key
merged in from an anchored mapping is part of the object the model was built
from while the raw tree holds no pair for it.
Every raw-node reader in compilers/openapi/internal/annotation therefore
disagrees with the model it sits beside, whenever a document merges. The gap is
invisible for the readers that look up a fixed keyword the document almost always
writes inline (links, servers, headers, content, allowReserved,
prefixEncoding), and visible for the undeclared-key census added in #356, which
is handed a key list by the parser and then cannot find some of them.
Reproduction
mergeChainSpec in compilers/openapi/cycles_test.go already builds one: each
level is {<<: *m<n-1>, p<n>: <n>}, so at level n the keys p1..p<n-1> are
merged in and only p<n> is a direct child. Compiling it reports one
openapi/unknown-key-unreachable per merged key — each of which is a key the
document writes and the IR does not carry in any form.
Minimal:
openapi: 3.1.0
info: {title: T, version: "1"}
x-anchors:
base: &base {bogusMerged: KEPT_NOWHERE}
paths: {}
components:
schemas:
S: {<<: *base, type: object}
Why it is filed rather than fixed in #356
The merge-expanded, alias-dereferenced, duplicate-resolved view of a mapping
already exists as compilers/openapi/internal/nodeview, with the precedence
rules and the MergeDepthLimit bound worked out. Re-deriving them inside
annotation would be the parallel mechanism that package exists to prevent.
Using it is not a local change: a nodeview.View is stateful, must not outlive
the node tree it memoizes, and annotation cannot import nodeview under the
current internal/archtest allowlist. So the fix is one of
- thread a
View (or a small read-only lookup over one) through the annotation
readers, and widen the allowlist entry with the reason; or
- move the raw-child lookup itself below
nodeview and have both read it.
Until then #356 announces the loss under openapi/unknown-key-unreachable
(warning: such a document is legal and still lowers) instead of dropping the key
in silence.
Scope
- Fix
RawChildNode — every caller benefits, not only the census.
- The other readers need a fixture each: today nothing in
testdata/ writes
links, servers or content through a merge key, so their share of this bug
is unwitnessed.
Summary
annotation.RawChildNodesearches a mapping's rawyaml.Nodepairs. The parserdoes not:
marshallerreads a mapping through its<<merge keys, so a keymerged in from an anchored mapping is part of the object the model was built
from while the raw tree holds no pair for it.
Every raw-node reader in
compilers/openapi/internal/annotationthereforedisagrees with the model it sits beside, whenever a document merges. The gap is
invisible for the readers that look up a fixed keyword the document almost always
writes inline (
links,servers,headers,content,allowReserved,prefixEncoding), and visible for the undeclared-key census added in #356, whichis handed a key list by the parser and then cannot find some of them.
Reproduction
mergeChainSpecincompilers/openapi/cycles_test.goalready builds one: eachlevel is
{<<: *m<n-1>, p<n>: <n>}, so at level n the keysp1..p<n-1>aremerged in and only
p<n>is a direct child. Compiling it reports oneopenapi/unknown-key-unreachableper merged key — each of which is a key thedocument writes and the IR does not carry in any form.
Minimal:
Why it is filed rather than fixed in #356
The merge-expanded, alias-dereferenced, duplicate-resolved view of a mapping
already exists as
compilers/openapi/internal/nodeview, with the precedencerules and the
MergeDepthLimitbound worked out. Re-deriving them insideannotationwould be the parallel mechanism that package exists to prevent.Using it is not a local change: a
nodeview.Viewis stateful, must not outlivethe node tree it memoizes, and
annotationcannot importnodeviewunder thecurrent
internal/archtestallowlist. So the fix is one ofView(or a small read-only lookup over one) through the annotationreaders, and widen the allowlist entry with the reason; or
nodeviewand have both read it.Until then #356 announces the loss under
openapi/unknown-key-unreachable(warning: such a document is legal and still lowers) instead of dropping the key
in silence.
Scope
RawChildNode— every caller benefits, not only the census.testdata/writeslinks,serversorcontentthrough a merge key, so their share of this bugis unwitnessed.