Skip to main content

Core Concepts

ModelGraphGenerator works through a five-phase pipeline that transforms annotated Swift source code into a complete JSON Schema document. This section explains the fundamental ideas behind each phase so you can reason about what the tool does — and debug it when something unexpected happens.

The Big Picture

Five Phases at a Glance

PhaseComponentInputOutput
1 — DiscoveryDiscoveryCoordinatorSource root + index path[IndexedSymbol]
2 — ParsingPropertyExtractor + parsersSwift file paths[PropertyInfo]
3 — Graph BuildingGraphBuilder + SymbolProcessor[IndexedSymbol]ModelGraph
4 — ConversionJSONSchemaConverterModelGraphJSON Schema object
5 — SerializationMain.swiftJSON Schema objectFile on disk

Key Abstractions

IndexedSymbol

The lightweight handle returned by the Discovery phase. It carries just enough information to locate the Swift declaration:

struct IndexedSymbol {
let name: String // "Product"
let usr: String // Unique Symbol Resolution — "s:7MyApp7ProductV"
let path: String // "/path/to/Product.swift"
let line: Int // 14
let kind: Kind // .struct | .class | .enum
}

ModelNode

A fully resolved node in the graph. Every non-primitive Swift type referenced by a root model becomes a ModelNode:

struct ModelNode {
let name: String
let schemaId: String? // from @ChimeraSchema(key: "…")
let properties: [PropertyInfo]
let inheritedProperties: [InheritedPropertyInfo]
let children: [ModelNode]
let isCyclic: Bool // back-reference detected
let isPolymorphic: Bool
let polymorphicVariants: [ModelNode]
}

ModelGraph

The top-level container — a flat list of root ModelNode trees plus metadata:

struct ModelGraph {
let roots: [ModelNode]
let generatedAt: Date
let sourceRoot: String
}

Where to go next

TopicPage
How symbols are foundDiscovery System
How source is parsedAST Parsing
How the graph is assembledGraph Building
Cycles & shared typesCycle Detection
Polymorphism & discriminatorsPolymorphic Types