Repository navigation
fix: preserve Kotlin untagged-union member payloads - #176
Merged
adamcavendish merged 1 commit intoNov 12, 2026
Merged
Conversation
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
- Select Kotlin OkHttp union members using retained finite scalar and structural facts so unconstrained Gson fields cannot swallow another member's payload. - Expose firstMatch, strict, and explicit raw policies while retaining typed sealed classes, data-class payloads, and existing root-null behavior by default. - Count original concrete members before opaque fallbacks and decode the selected member once, preserving nested strict errors and transparent type aliases. - Delegate serialization through each declared payload type so nested sealed unions do not leak their runtime Variant wrappers into the wire representation. - Compare exact significands and unbounded exponents without rounding, adding matcher scale limits, or hiding existing native scalar and byte decoder errors. - Cache successful and failed recursive predicates by JSON node identity with qualified Kotlin cache types that cannot collide with generated model names. - Preserve raw JSON trees, including null entries and large numbers, and restore the writer's null policy even when native tree serialization fails. - Emit adapters with structured declarations and semantic nested case types; share intersection wrapper keys between model emission and matching. - Retain ordinary and tagged codecs, wrapped intersections, and untouched generated dependencies without changing shared IR or other-language backends. - Exercise native model, recursive helper, and HTTP response/error consumers in isolated policy projects alongside exact render and Kotlin golden contracts.
adamcavendish
force-pushed
the
adamcavendish/kotlin-untagged-union-selection
branch
from
November 11, 2026 15:42
d63568c to
36cd171
Compare
adamcavendish
deleted the
adamcavendish/kotlin-untagged-union-selection
branch
November 12, 2026 01:48
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Preserve Kotlin OkHttp untagged-union member payloads with enum-aware structural
selection and configurable typed or raw adapters.
Problem
The existing Gson adapter chooses object members by required keys alone. Members
with identical required keys but disjoint numeric enums therefore select the first
variant and silently discard fields from the actual matching member. The same
failure affects containing fields, lists, and maps.
Kotlin sealed subclasses also need serialization through their declared member
type: reflecting a nested union's runtime variant emits a
value0wrapper insteadof that union's wire payload.
Behavior
firstMatchstrictrawVariantRaw(JsonElement)preserving known and unknown JSON.Matching retains finite scalar constraints, nested arrays/maps, null permissions,
and productive recursion. Exact decimal significands and unbounded exponents avoid
floating-point rounding and matcher-only scale limits. Recursive checks cache both
successful and failed predicates by JSON-node identity.
Typed adapters delegate once to the selected original member. Nested strict and
native decode errors propagate without retrying another member or raw fallback.
Serialization uses the declared payload type to preserve nested union boundaries.
Raw adapters preserve null object entries and large numbers while restoring the
writer's previous null policy, including on failure.
Compatibility
and existing root-null behavior (
nullor nullable-unionVariantNull).typealiasdeclarations remain transparent; intersections retain theirexisting wrapper fields rather than receiving a new
allOfwire codec.shared IR, and other-language generators are unchanged.
kotlin-okhttp.untagged_union_strategy; an enclosingVariantRawmodel usesVariantRawVariantfor its raw case.Boundaries
This is the Kotlin-only union repair following merged Java #175. Dictionary-only
models, additional-property preservation, and multi-member
allOfredesign remainseparate work. Structural selection is not full JSON Schema validation; format
bounds and existing native codec limits remain with the selected member's codec.