- `cmd/osgen` now honors the OpenAPI `discriminator`, which it previously ignored entirely. Eight schemas in the spec declare one and every branch of all eight resolves to a distinct value, so 146 subtypes whose branch the payload names outright were being decoded by a JSON token-class heuristic instead. The discriminator is how OpenAPI expresses polymorphism, and the spec encodes the hierarchy through `allOf` (a subtype is `allOf[Base, {type: enum[keyword]}]`), so resolving a discriminant walks `allOf` transitively: the constant sits on the narrowing member while the inherited fields come from the base. A union is only discriminated when every branch resolves distinctly, so a partially-understood schema falls back rather than emitting a decoder with an unreachable case. Six emitted unions gain a `Type()`, discriminant constants, and an `UnmarshalJSON` that reads one property and decodes exactly that branch: `CommonMappingProperty` (on `type`, honoring the spec's `x-default` for the implicit object mapping), `CommonAnalysis{Analyzer,CharFilterDefinition,TokenFilterDefinition,TokenizerDefinition,Normalizer}`, plus `ClusterRemoteInfoCluster` on `mode`. A value naming no branch is an error rather than a silent mis-decode, and `ClusterRemoteInfoResp.Entries` becomes `map[string]ClusterRemoteInfoCluster` instead of an untyped map, dropping it from the `json.RawMessage` allowlist. Internal vocabulary follows the spec rather than the decode mechanism: `IsLazy`/`LazyAccessors` conflated "the spec provides no discriminator" with "we never read the discriminator" and become `RequestSelected`, since the aggregation and suggester unions carry `x-supports-typed-keys` and genuinely cannot be discriminated (the branch is chosen by the request and echoed only in the response map key, `avg#my_agg`); `TypeLazyUnion` becomes `TypeAmbiguousWire`, `unionNeedsTryEach` becomes `branchesCollideOnTokenClass`, and the token-class heuristic is retained and documented as the fallback it is
0 commit comments