Skip to content

openapi: decide whether a scalar failing its own tag is refused or kept as text #245

Description

@OmarAlJarrah

Summary

annotation.RawFromNode keeps a !!timestamp or !!binary scalar as the text the
source wrote, but still refuses one whose text does not satisfy the tag it declares:

x-when: !!timestamp notadate   # dropped, warning "extension could not be serialized"
x-blob: !!binary "###"         # dropped, same warning

The whole extension is discarded and the caller gets a warning diagnostic
(ExtensionsFrom, annotation.go).

That refusal is inherited rather than chosen. It exists because the conversion used
to decode these scalars to produce its output, so a decode failure had nowhere to
go. Nothing consumes the decoded value any more — the decode survives only as a tag
check — so the refusal is now the one thing standing between a construct the source
wrote and the IR.

Why it may be wrong

RawFromNode's documented rule is that it refuses what JSON cannot name: a
non-string mapping key, a key written twice, .nan/.inf. Both scalars above are
perfectly nameable in JSON — they are strings. They are refused for failing YAML
type resolution, which is a different rule, and one the sibling arm already declines
to apply: a tag yaml.v3 resolves no type for (!acme/thing) keeps its text rather
than being dropped, on the stated grounds that refusing would lose an extension value
the source did write.

Against that: dropping with a warning is louder than preserving silently, and a
!!binary "###" is a genuinely malformed construct that an author probably wants to
hear about. The IR has no channel for "kept, but suspect" — RawFromNode returns
(value, error) and the error path is what produces the diagnostic — so keeping the
text and keeping the warning is not currently expressible without threading a
diagnostic through the walk.

Decision needed

Which of "refuse and warn" or "preserve as text" is right for a scalar whose tag
promises a type its text does not hold, and whether the IR wants a way to say both.

Whatever is chosen, RawFromNode's doc comment states the current rule and must move
with it.

Context

Split out of #242, which settled what these scalars preserve and deliberately left
what they accept unchanged so the two questions could be answered separately. The
!!timestamp / !!binary arm of scalar in
compilers/openapi/internal/annotation/rawjson.go points here.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions