Skip to content

openapi: keyword and pointer lookups still rescan the nodes the index already walked #338

Description

@OmarAlJarrah

compilers/openapi/internal/sourceindex now walks a decoded source tree once and answers what
the pre-parse refusals used to walk it separately to ask. The other half of the same problem is
untouched: the lookups performed during lowering still rediscover, per call, structure the parse
already located.

Measured on testdata/golden/openapi/petstore.yaml (280 YAML nodes), by counting entries into each
function during one Compile:

  • annotation.RawChildNode — 442 calls, each a linear scan of a mapping node's Content for one
    on-wire key.
  • annotation.RawPropertyNode — 430 calls, the same scan reached through a schema's root node.
  • nodeview.PointerPath — 6 calls, each restarting from the document root, so resolving a pointer
    is O(depth) rather than a map hit. testdata/conformance/openapi/allof-oneof-cooccurrence.yaml
    is denser still: 948 child-scans over 113 nodes.

A per-node key map and a pointer → node map both belong in the index that already exists. What
makes this its own change rather than part of the one that built it: these are read from schema,
operation, auth and annotation itself, roughly thirty call sites, none of which can reach the
index today. Handing it down means carrying it on lowering.Ctx and widening the signatures
beneath it — including several inside annotation, which sits below lowering and so cannot take
it from there.

Two things to keep whichever way it is done:

  • RawChildNode reads the raw tree — first matching key wins, no alias dereference, no <<
    expansion — which is deliberately not what nodeview does. An index that answered it through the
    merge-aware view would change what the compiler preserves verbatim.
  • The index is a value threaded from the loader, never a package-level cache: a memo that outlived
    one Compile would break the pure-and-reentrant-stages invariant.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions