( document: SchemaRepresentation.MultiDocument )
| 218 | |
| 219 | /** @internal */ |
| 220 | export function toCodeDocument( |
| 221 | document: SchemaRepresentation.MultiDocument |
| 222 | ): SchemaRepresentation.CodeDocument { |
| 223 | const artifacts: Array<SchemaRepresentation.Artifact> = [] |
| 224 | const sorted = topologicalSort(document.references) |
| 225 | const sanitizedReferences = new Map<string, string>() |
| 226 | const uniqueIdentifiers = new Set<string>() |
| 227 | let compilingRecursiveDefinition = false |
| 228 | let explicitSuspendDepth = 0 |
| 229 | |
| 230 | for (const { $ref } of sorted.nonRecursives) ensureUniqueIdentifier($ref) |
| 231 | for (const $ref of Object.keys(sorted.recursives)) ensureUniqueIdentifier($ref) |
| 232 | |
| 233 | const nonRecursives = sorted.nonRecursives.map(({ $ref, representation }) => ({ |
| 234 | $ref: ensureUniqueIdentifier($ref), |
| 235 | code: recur(representation, ["references", $ref]) |
| 236 | })) |
| 237 | const recursives: Record<string, SchemaRepresentation.Code> = {} |
| 238 | for (const [$ref, representation] of Object.entries(sorted.recursives)) { |
| 239 | compilingRecursiveDefinition = true |
| 240 | InternalRecord.assignProperty(recursives, ensureUniqueIdentifier($ref), recur(representation, ["references", $ref])) |
| 241 | compilingRecursiveDefinition = false |
| 242 | } |
| 243 | const codes = document.representations.map((representation, index) => |
| 244 | recur(representation, ["representations", index]) |
| 245 | ) |
| 246 | |
| 247 | return { |
| 248 | codes, |
| 249 | references: { nonRecursives, recursives }, |
| 250 | artifacts |
| 251 | } |
| 252 | |
| 253 | function ensureUniqueIdentifier(original: string): string { |
| 254 | const existing = sanitizedReferences.get(original) |
| 255 | if (existing !== undefined) return existing |
| 256 | const candidate = freshIdentifier(original) |
| 257 | sanitizedReferences.set(original, candidate) |
| 258 | return candidate |
| 259 | } |
| 260 | |
| 261 | function freshIdentifier(seed: string): string { |
| 262 | const sanitized = sanitizeJavaScriptIdentifier(seed) |
| 263 | let candidate = sanitized |
| 264 | let suffix = 0 |
| 265 | while (uniqueIdentifiers.has(candidate)) candidate = `${sanitized}${++suffix}` |
| 266 | uniqueIdentifiers.add(candidate) |
| 267 | return candidate |
| 268 | } |
| 269 | |
| 270 | function addImport(importDeclaration: string): void { |
| 271 | if (!artifacts.some((artifact) => artifact._tag === "Import" && artifact.importDeclaration === importDeclaration)) { |
| 272 | artifacts.push({ _tag: "Import", importDeclaration }) |
| 273 | } |
| 274 | } |
| 275 | |
| 276 | function addSymbol(symbol: symbol): string { |
| 277 | const identifier = freshIdentifier("_symbol") |
nothing calls this directly
no test coverage detected