Parsers
The parser stage takes the stubs produced by discovery and enriches each ModelNode with full property, enum, and structural data. All parsers use SwiftSyntax AST visitors.
Parser Overview
| Parser | File | Responsibility |
|---|---|---|
PropertyExtractor | PropertyExtractor.swift | Extract @ChimeraProperty annotations and types |
EnumExtractor | EnumExtractor.swift | Extract enum cases and raw values |
PolymorphicParser | PolymorphicParser.swift | Parse @PolymorphicMapping |
CodingKeysParser | CodingKeysParser.swift | Resolve custom CodingKeys names |
TypeAnalyzer | TypeAnalyzer.swift | Normalize Swift type strings to JSON types |
PropertyExtractor
File: Sources/Parser/PropertyExtractor.swift
The primary parser. For each ModelNode, PropertyExtractor opens its source file, parses it with SwiftSyntax, and visits all stored property declarations via PropertyExtractorVisitor.
PropertyExtractorVisitor
File: Sources/Parser/Syntax/PropertyExtractorVisitor.swift
Visits VariableDeclSyntax nodes (i.e., let and var declarations). For each property:
- Reads all attached attributes, looking for
@ChimeraProperty(...) - Extracts the
description, and any constraint arguments (minLength,max, etc.) - Reads the type annotation (e.g.,
String,Int?,[Product]) - Passes the type string to
TypeAnalyzerfor normalization - Checks
isOptionalby inspectingOptionalTypeSyntaxorImplicitlyUnwrappedOptionalTypeSyntax - Creates a
PropertyInfovalue
Constraint Extraction
@ChimeraProperty arguments are parsed from LabeledExprListSyntax. Each labeled argument maps to a field on PropertyConstraints:
struct PropertyConstraints {
var minLength: Int?
var maxLength: Int?
var pattern: String?
var minimum: Double?
var maximum: Double?
var exclusiveMinimum: Double?
var exclusiveMaximum: Double?
var minItems: Int?
var maxItems: Int?
var example: String?
}
TypeAnalyzer
File: Sources/Parser/TypeAnalyzer.swift
TypeAnalyzer converts Swift type strings to the internal type representation used for JSON Schema mapping:
| Input Swift type | Output |
|---|---|
"String" | .string |
"Int", "Int32", "Int64" | .integer |
"Double", "Float" | .number |
"Bool" | .boolean |
"Date" | .dateTime |
"URL" | .uri |
"[T]" | .array(element: T) |
"[String: T]" | .dictionary(value: T) |
"T?" | .optional(wrapped: T) |
| Custom type name | .reference(typeName: T) |
References (custom types) are resolved later during graph building, where SymbolProcessor maps type names to @ChimeraSchema keys.
EnumExtractor
File: Sources/Parser/EnumExtractor.swift
Handles Swift enums used as property types. When TypeAnalyzer returns .reference("Status") and Status is an enum, EnumExtractor parses the enum to collect its cases.
EnumExtractorVisitor (internal)
Visits EnumDeclSyntax and its EnumCaseDeclSyntax children. For string-backed enums (enum Status: String), it reads the raw value string if present, otherwise uses the case name.
Output:
struct EnumCaseInfo {
let name: String // Swift case name
let rawValue: String // String raw value (or case name if none)
}
PolymorphicParser
File: Sources/Parser/PolymorphicParser.swift
Reads @PolymorphicMapping annotations on protocols and class hierarchies.
PolymorphicVisitor
File: Sources/Parser/Syntax/PolymorphicVisitor.swift
Visits protocol and class declarations with @PolymorphicMapping. Extracts:
key: The discriminator property namemappings: The[String: Any.Type]dictionary literal, reading string keys and type name references
The parser cross-references the type names in mappings against the MacroRepository to confirm they have @ChimeraSchema annotations. Missing @ChimeraSchema on a concrete type triggers a warning.
Output:
struct PolymorphicInfo {
let discriminatorKey: String
let mappings: [String: String] // discriminator value → @ChimeraSchema key
}
CodingKeysParser
File: Sources/Parser/CodingKeysParser.swift
When a model defines a nested CodingKeys enum, the JSON property names should use those custom keys rather than the Swift property names.
CodingKeysVisitor
File: Sources/Parser/Syntax/CodingKeysVisitor.swift
Looks for enum CodingKeys: String, CodingKey nested inside a @ChimeraSchema type. Extracts the mapping from Swift property name → JSON key name using raw values:
enum CodingKeys: String, CodingKey {
case firstName = "first_name" // Swift "firstName" → JSON "first_name"
case lastName = "last_name"
}
CodingKeysParser returns a [String: String] dictionary that the property extraction stage uses to rename PropertyInfo.name in the output.
ChimeraPropertyParser / Visitors
Files: ChimeraPropertyParser.swift, ChimeraMetaDataVisitor.swift, ChimeraPropertyVisitor.swift
An alternative property parsing strategy supporting an earlier annotation format. Operates similarly to PropertyExtractor but looks for a different annotation syntax. This is used when MacroDiscovery is not applicable.
Parser Integration
After all parsers complete for a given ModelNode:
PropertyInfolist is attached to the nodeEnumCaseInfolist is attached for any enum-typed propertiesPolymorphicInfois set if applicable- CodingKey renames are applied
The fully-populated [ModelNode] is then passed to the Graph Building stage.