EncodingId as a sealed interface; ArrayNode carries the typed id#193
Merged
Conversation
Move the ExtensionDecoder interface from the reader root into reader.extension next to its four implementations, mirroring EncodingDecoder in reader.decode. Also sync stale docs: ReadRegistry no longer manages extension decoders (no register(ExtensionDecoder), no ServiceLoader discovery) — the spec set is closed and dispatched in Chunk.as(). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
MaskedEncodingDecoder and PatchedEncodingDecoder are implemented and ServiceLoader-registered; the enum constants still claimed otherwise. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
sealed interface EncodingId permits WellKnown, Custom: the spec constants move verbatim into the nested WellKnown enum and every wire string now has a typed representation — parse() is total, returning the WellKnown match or a Custom wrapping the raw id. Custom's compact constructor rejects null, blank, and ids that collide with a WellKnown wire string, so the two variants never alias as map keys. All constants are re-exported as WellKnown-typed interface fields, keeping the existing EncodingId.VORTEX_FOO call sites source compatible. KnownArrayNode narrows its component to WellKnown (a known node can no longer hold a custom id); ArrayNode.of dispatches WellKnown/Custom to Known/UnknownArrayNode. EncodingDecoder and EncodingEncoder keep the interface in their signatures, which for the first time lets third-party codecs declare ids outside the spec set. EncodingId extends Serializable to preserve the enum's implicit serializability for the VortexException field. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Collapse the KnownArrayNode/UnknownArrayNode sealed pair into a single ArrayNode record: with EncodingId sealed, the Known/Unknown bit lives in the id type (WellKnown vs Custom), so the parallel node hierarchy and its switch dances at every dispatch site encode nothing. ReadRegistry returns to the single string-keyed map hit; the allowUnknown passthrough and error messages are unchanged for both former variants. The redundant ArrayNode.of factory is gone — the canonical constructor takes the typed id. Hardening from review: a crafted file with a blank encoding id in the spec table now fails as VortexException in FlatSegmentDecoder (EncodingId.parse rejects blank with IllegalArgumentException, which must not escape the untrusted read path — previously "" flowed to the unknown-id path and could pass through allowUnknown); WriteRegistry's builder TreeMap orders by wire string instead of natural ordering, which a Custom-keyed registration would break. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The EncodingId javadoc examples used "vortex.flat", which lives in the footer's layoutSpecs table (Layout.FLAT), never in arraySpecs; the canonical flat encoding id is "vortex.primitive". Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.
What
Two-step refactor making encoding identity typed at the core while staying string-faithful at the wire edge:
ea88a91b—core.model.EncodingIdbecomessealed interface EncodingId permits WellKnown, Custom. The 33 spec constants move verbatim into the nestedWellKnownenum and are re-exported asWellKnown-typed interface fields, so all ~579 existingEncodingId.VORTEX_FOOcall sites compile unchanged.Custom(String)wraps any other wire string; its compact constructor rejects null/blank/well-known collisions, so the two variants can never alias as map keys.parseis total over non-blank ids — an unknown id yields a typedCustominstead of an emptyOptional.21810d7e— with the Known/Unknown bit living in the id type, theKnownArrayNode/UnknownArrayNodesealed pair encodes nothing:ArrayNodecollapses to a single record carryingEncodingId.ReadRegistryreturns to one string-keyed map hit;allowUnknownpassthrough and error messages byte-identical.Why
StringinArrayNode) and without the sealed node pair's switch dances — the sum type lives in the id, the one place it's consumed.EncodingDecoder/EncodingEncoderkeepEncodingIdin their signatures, so third-party codecs can now declare ids outside the spec set — previously impossible with the closed enum despite the registry's pluggability promise.Review hardening (adversarial review pass, findings fixed in
21810d7e)EncodingId.parseunguarded and escaped asIllegalArgumentException;FlatSegmentDecodernow rejects blank spec entries withVortexException(previously""could even slide throughallowUnknownas a passthrough). Pinned by tests on both layers.WriteRegistry.Builder'sTreeMapnow orders by wire string — natural ordering wouldClassCastExceptionon the firstCustom-keyed registration.Verification
./mvnw verifygreen — all 15 modules including the failsafe interop suite, after each step and after the hardening fixes../mvnw javadoc:javadoc -pl core— zero output.Follow-up candidates (not in this PR)
Footer.arraySpecs/layoutSpecscould carry typed ids now that parse is total.ReadRegistrydispatch forCustom-id decoders (currently registrable but unknown-node passthrough still governs flat-segment decode).🤖 Generated with Claude Code