Metamodel: stamp a schema in a block, or a chain - #106
Merged
jimador merged 2 commits intoSep 9, 2026
Merged
Conversation
jimador
force-pushed
the
feat/metamodel-fluent-stamping
branch
from
September 4, 2026 03:15
79d6e2c to
564a31d
Compare
jimador
force-pushed
the
feat/metamodel-fluent-stamping
branch
from
September 4, 2026 03:47
564a31d to
78b8e04
Compare
jimador
force-pushed
the
feat/metamodel-fluent-stamping
branch
from
September 4, 2026 04:31
78b8e04 to
81fdc87
Compare
jimador
force-pushed
the
feat/metamodel-fluent-stamping
branch
from
September 7, 2026 03:35
81fdc87 to
20a959f
Compare
jimador
force-pushed
the
feat/metamodel-fluent-stamping
branch
from
September 8, 2026 20:30
20a959f to
55a4358
Compare
jimador
force-pushed
the
feat/metamodel-fluent-stamping
branch
from
September 8, 2026 20:47
55a4358 to
4041f80
Compare
jimador
force-pushed
the
feat/metamodel-fluent-stamping
branch
from
September 8, 2026 20:59
4041f80 to
e67629b
Compare
MetamodelVersion.stamping(dictionary) starts an immutable MetamodelStamping that names each input as it is set and finishes as either a stamp or a declaration. Every step copies, so a partly built stamping can be held and finished more than once. The from overloads stay and the chain delegates to them, so both spellings produce the same stamp and no compiled caller moves. Java gets the same chain, tested, with the constructor arities pinned. Signed-off-by: James Dunnam <7660553+jimador@users.noreply.github.com>
MetamodelVersion(dictionary) { } and DeclaredSchema(dictionary) { } take a receiver block, so the Kotlin call site is statements with no prefix and no chain. The entry is invoke on the companion, the shape embabel-agent uses for its configured constructors, and is JvmSynthetic so Java sees only the chain. An aliases { } block declares renames inline and accumulates names, which is what a rename chain needs. The builders are scoped to the block by DslMarker and internal constructors; what comes back is immutable.
Signed-off-by: James Dunnam <7660553+jimador@users.noreply.github.com>
jimador
force-pushed
the
feat/metamodel-fluent-stamping
branch
from
September 9, 2026 00:08
e67629b to
72d46cf
Compare
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.
Answers the review note on #83:
MetamodelVersion.from(dictionary).governedBy(governed).Two entries off the class, one per language. Both take the same three inputs a stamp needs and both delegate to the existing
fromoverloads, so every spelling produces the same stamp.Kotlin
A receiver block, so the call site is a sequence of statements with no prefix and no chain:
The entry is
operator fun invokeon the companion, which is howembabel-agentshapes its own configured constructors (ActionContext,OperationContext,Tool.Definition) and the same shape asJson { }andHttpClient { }. It reads as a constructor with a trailing block and stays on the class.DeclaredSchema(dictionary) { }is the same block finishing as a declaration, so both halves of a declaration come from one set of arguments and cannot disagree about what is governed. An empty block is the whole-schema stamp.governedBytakes a selector, a set of names, or names written out.aliases { }declares renames inline throughtype(...)andproperty(...), sinceSchemaAliasesis two levels of map and writing those literals is the least readable part of declaring a rename. Names accumulate there, so a type renamedAtoBtoCdeclares both older names, which is what a comparison across non-adjacent stamps needs.@DslMarkerscopes the two builders, so reaching the outer one from insidealiases { }is a compile error. The builders are mutable, their constructors are internal, and their lifetime is the block. What comes back is immutable.Java
MetamodelStamping, an immutable value carrying the same three inputs, reached throughMetamodelVersion.stamping(dictionary). Every step returns a new value, so a partly built stamping can be held in a field and finished more than once, as a stamp or as a declaration.The block entries are
@JvmSynthetic, so Java sees only the chain. A receiver lambda from Java means returningUnit.INSTANCEby hand, which is why the two surfaces stay separate rather than one serving both.Why
fromstaysfrom(dictionary)already returns a stamp, so it cannot become the entry to either form without breaking every caller compiled against it. The threeMetamodelVersion.fromoverloads and bothDeclaredSchema.fromoverloads are untouched. They are the short forms.Compatibility
Additive. Two companion entries, one value type, two builders. Nothing existing moves.
MetamodelStampingcarries@JvmOverloadson its constructor, so Java keeps the one, two and three-argument arities; a test pins that.Nothing is validated while chaining or inside a block. The alias rules stay with the factories, so a bad declaration fails on the terminal call, or when the block returns, with the message the three-argument form gives.
Verification
./mvnw clean installat this branch, all modules green.dice-metamodelcarries 11 new tests on the block, 9 on the chain, and 16 in the Java compat suite, including one asserting the block and the chain reach the identical stamp.