Skip to content

feat(generator): DiffTraverser/DiffVisitor for paired tree comparison (C36)#1139

Open
jsenko wants to merge 2 commits into
mainfrom
c36-diff-traverser
Open

feat(generator): DiffTraverser/DiffVisitor for paired tree comparison (C36)#1139
jsenko wants to merge 2 commits into
mainfrom
c36-diff-traverser

Conversation

@jsenko

@jsenko jsenko commented Jun 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

New infrastructure for paired tree traversal — walks two trees of the same spec version in parallel, dispatching field-level diffs to a pluggable DiffVisitor.

Base classes (visitors/diff/)

  • DiffVisitor — abstract visitor with methods for each field type: diffPrimitive, diffEntity, diffUnion, diffList, diffMap. Strategy selection via getPairingStrategy(propertyName).
  • AbstractDiffTraverser — shared diffMap/diffList/diffEntityField helpers with auto-recursion into matched pairs.
  • CollectionDiff<K,V> — diff result with added/removed/matched entries.
  • PairingStrategy<K,V> — pluggable collection pairing. Built-in: KeyPairingStrategy (maps), IndexPairingStrategy (lists).

Generated per spec version

  • CreateDiffTraversersStage — generates XxxDiffTraverser per spec version (e.g., JD7DiffTraverser), following the same entity-property iteration as CreateTraversersStage.
  • Each entity gets a traverseXxx(original, updated) method that dispatches to the visitor.
  • traverseNode(original, updated) dispatches by instanceof to the correct entity method.

Example generated output

public void traverseFullSchema(JD7FullSchema original, JD7FullSchema updated) {
    if (!visitor.visitEntityPair(original, updated)) return;
    visitor.diffPrimitive("title", original.getTitle(), updated.getTitle());
    this.diffMap("properties", original.getProperties(), updated.getProperties());
    this.diffList("allOf", original.getAllOf(), updated.getAllOf());
    this.diffUnionField("type", original.getType(), updated.getType());
    // ... all fields
}

Context

C36 Phase 1-2 in #1042. Phase 3 (compat checker migration) will be a follow-up.

Test plan

  • All 1129 data-models tests pass
  • Generated code compiles (FullGeneratorTest)
  • Synthetic snapshot tests pass

jsenko added 2 commits June 29, 2026 23:59
…36 Phase 1)

Base classes for paired tree traversal:
- CollectionDiff with Entry/MatchedPair for collection comparison results
- PairingStrategy interface with KeyPairingStrategy (maps) and
  IndexPairingStrategy (lists)
- DiffVisitor abstract base with field-level diff methods and
  strategy selection callback
- AbstractDiffTraverser with shared diffMap/diffList/diffEntityField
  helpers and auto-recursion into matched pairs
New CreateDiffTraversersStage generates per-spec-version diff traversers
that walk two trees in parallel, dispatching to DiffVisitor methods:
- diffPrimitive for primitive fields
- diffEntityField for entity fields (auto-recurses)
- diffUnionField for union fields
- diffMap for map fields (pairs by key, auto-recurses matches)
- diffList for list fields (pairs by index, auto-recurses matches)

Registered in pipeline after CreateTraversersStage.
Base classes registered in LoadBaseClassesStage.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant