Repository navigation
openapi: split schema lowering into one file per construct #1060
Copy link
Copy link
Closed
Labels
priority:P4Refactors, tests, CI, hostile-input hardening, cosmetic diagnostics, other formatsRefactors, tests, CI, hostile-input hardening, cosmetic diagnostics, other formatstype:choreRefactor or cleanup, no behavior changeRefactor or cleanup, no behavior change
Description
Problem
In compilers/openapi/internal/schema:
compose.go(1,588 lines) holds four constructs in sequence:lowerAllOfat line 41,lowerOneOfAnyOfat 549,lowerDiscriminatorat 1136 andlowerEnumat 1382.schema.go(2,420 lines) holds dispatch beside the keyword census, models, scalars,$dynamicRefand nullability.resolve.golowers a$refsite, although resolving references isinternal/resolve's job.discriminated.goandenummember.gohold halves of constructs whose other halves sit incompose.go.- The naming hints for a hoisted node are split between
resolve.goandcompose.go, each calling the other.
allOf's tests are split too: 39 TestAllOf_* in compose_test.go, 16 in schema_test.go.
Direction
| File | Holds |
|---|---|
allof.go |
allOf composition, its required lists and false branches |
union.go |
oneOf/anyOf, null-only and distributed unions, siblings beside a union |
discriminator.go |
discriminators, mappings, a subtype's discriminator value (absorbs discriminated.go) |
enum.go |
enums and const unions (absorbs enummember.go) |
census.go |
which keywords a lowering homes and what it keeps verbatim |
model.go |
models, properties, additional and pattern properties, tuples, arrays (lowerArray leaves accumulate.go) |
scalar.go |
scalars, formats, content encoding |
dynamicref.go |
$dynamicRef expansion and the anchor index |
nullable.go |
whether a schema admits null |
refsite.go |
the $ref site (was resolve.go) |
hoist.go |
gains the naming hints for a hoisted node, the inline-hoisting rule's other half |
schema.go |
keeps the entry, dispatch, component declarations and shared readers |
- Tests follow their names.
foreign_test.go,mapping_raw_targets_test.go,unhomed_discriminator_test.go,reasons_internal_test.goand fix(compilers/openapi): flatten a nested inline allOf #998'scompose_equivalence_test.gomerge into the files of the constructs they test. - Comments that name a file:
FillPropertyDetail (schema.go)ininternal/annotation; thecompose.gopath incompilers/openapi/amplification_test.go; and the note inaccumulate.goabout whatoperationreaches inschema.go, which is re-derived, not just re-pointed.
Blocked by
- fix(compilers/openapi): flatten a nested inline allOf #998 and fix(compilers/openapi): judge redeclared allOf field types #1000 edit
compose.go,schema.goand their tests. - feat(compilers/openapi)!: validate against an OpenAPI rule table #1046 edits
schema.goandschema_test.go. - The change for openapi: decide how
nullablein an OpenAPI 3.1 document is treated #632 edits nullability inschema.go. - openapi: split annotation.go by construct #1056 owns
annotation.go, where one of the comments above lives.
Done when
- Every top-level declaration of the package, with its doc comment and any comment between declarations, is byte-identical before and after the move (compared with a throwaway go/ast script), and no golden changes.
- Comments that name a file name the file the code now lives in, changed in a commit of their own.
go test ./compilers/openapi/...passes without-update.
Priority: P4, rule 1 (housekeeping: moves code between files and changes no lowering, validation, IR or emit-contract behaviour). wc -l compilers/openapi/internal/schema/{compose,schema}.go → 1588, 2420 (morphic @a1f15b29).
Metadata
Metadata
Assignees
Labels
priority:P4Refactors, tests, CI, hostile-input hardening, cosmetic diagnostics, other formatsRefactors, tests, CI, hostile-input hardening, cosmetic diagnostics, other formatstype:choreRefactor or cleanup, no behavior changeRefactor or cleanup, no behavior change
Activity
nullablein an OpenAPI 3.1 document is treated #632OmarAlJarrah commentedon Oct 22, 2026
#1100 changes two things this plan names in
schema/accumulate.go:operationreaches inschema. It states which preservation functions belong inschemaat all: only one whose decision needs the lowering, and it namesPreserveUnknownKeywordsas that one. It names no file, so the move only has to keep it beside the code it describes rather than re-derive a list.PreserveUnknownKeywords,undefinedKeywordsandlowerArray.AppendExample,PreserveSchemaKeywordand the forwarders moved toannotationor were deleted, so they no longer need a file here.