| 6dd74de | | | 1 | import type { LangiumParser, ParseResult } from 'langium'; |
| 6dd74de | | | 2 | |
| 6dd74de | | | 3 | import type { Info, Packet, Pie, Architecture, GitGraph, Radar, Treemap } from './index.js'; |
| 6dd74de | | | 4 | |
| 6dd74de | | | 5 | export type DiagramAST = Info | Packet | Pie | Architecture | GitGraph | Radar; |
| 6dd74de | | | 6 | |
| 6dd74de | | | 7 | const parsers: Record<string, LangiumParser> = {}; |
| 6dd74de | | | 8 | const initializers = { |
| 6dd74de | | | 9 | info: async () => { |
| 6dd74de | | | 10 | const { createInfoServices } = await import('./language/info/index.js'); |
| 6dd74de | | | 11 | const parser = createInfoServices().Info.parser.LangiumParser; |
| 6dd74de | | | 12 | parsers.info = parser; |
| 6dd74de | | | 13 | }, |
| 6dd74de | | | 14 | packet: async () => { |
| 6dd74de | | | 15 | const { createPacketServices } = await import('./language/packet/index.js'); |
| 6dd74de | | | 16 | const parser = createPacketServices().Packet.parser.LangiumParser; |
| 6dd74de | | | 17 | parsers.packet = parser; |
| 6dd74de | | | 18 | }, |
| 6dd74de | | | 19 | pie: async () => { |
| 6dd74de | | | 20 | const { createPieServices } = await import('./language/pie/index.js'); |
| 6dd74de | | | 21 | const parser = createPieServices().Pie.parser.LangiumParser; |
| 6dd74de | | | 22 | parsers.pie = parser; |
| 6dd74de | | | 23 | }, |
| 6dd74de | | | 24 | architecture: async () => { |
| 6dd74de | | | 25 | const { createArchitectureServices } = await import('./language/architecture/index.js'); |
| 6dd74de | | | 26 | const parser = createArchitectureServices().Architecture.parser.LangiumParser; |
| 6dd74de | | | 27 | parsers.architecture = parser; |
| 6dd74de | | | 28 | }, |
| 6dd74de | | | 29 | gitGraph: async () => { |
| 6dd74de | | | 30 | const { createGitGraphServices } = await import('./language/gitGraph/index.js'); |
| 6dd74de | | | 31 | const parser = createGitGraphServices().GitGraph.parser.LangiumParser; |
| 6dd74de | | | 32 | parsers.gitGraph = parser; |
| 6dd74de | | | 33 | }, |
| 6dd74de | | | 34 | radar: async () => { |
| 6dd74de | | | 35 | const { createRadarServices } = await import('./language/radar/index.js'); |
| 6dd74de | | | 36 | const parser = createRadarServices().Radar.parser.LangiumParser; |
| 6dd74de | | | 37 | parsers.radar = parser; |
| 6dd74de | | | 38 | }, |
| 6dd74de | | | 39 | treemap: async () => { |
| 6dd74de | | | 40 | const { createTreemapServices } = await import('./language/treemap/index.js'); |
| 6dd74de | | | 41 | const parser = createTreemapServices().Treemap.parser.LangiumParser; |
| 6dd74de | | | 42 | parsers.treemap = parser; |
| 6dd74de | | | 43 | }, |
| 6dd74de | | | 44 | } as const; |
| 6dd74de | | | 45 | |
| 6dd74de | | | 46 | export async function parse(diagramType: 'info', text: string): Promise<Info>; |
| 6dd74de | | | 47 | export async function parse(diagramType: 'packet', text: string): Promise<Packet>; |
| 6dd74de | | | 48 | export async function parse(diagramType: 'pie', text: string): Promise<Pie>; |
| 6dd74de | | | 49 | export async function parse(diagramType: 'architecture', text: string): Promise<Architecture>; |
| 6dd74de | | | 50 | export async function parse(diagramType: 'gitGraph', text: string): Promise<GitGraph>; |
| 6dd74de | | | 51 | export async function parse(diagramType: 'radar', text: string): Promise<Radar>; |
| 6dd74de | | | 52 | export async function parse(diagramType: 'treemap', text: string): Promise<Treemap>; |
| 6dd74de | | | 53 | |
| 6dd74de | | | 54 | export async function parse<T extends DiagramAST>( |
| 6dd74de | | | 55 | diagramType: keyof typeof initializers, |
| 6dd74de | | | 56 | text: string |
| 6dd74de | | | 57 | ): Promise<T> { |
| 6dd74de | | | 58 | const initializer = initializers[diagramType]; |
| 6dd74de | | | 59 | if (!initializer) { |
| 6dd74de | | | 60 | throw new Error(`Unknown diagram type: ${diagramType}`); |
| 6dd74de | | | 61 | } |
| 6dd74de | | | 62 | if (!parsers[diagramType]) { |
| 6dd74de | | | 63 | await initializer(); |
| 6dd74de | | | 64 | } |
| 6dd74de | | | 65 | const parser: LangiumParser = parsers[diagramType]; |
| 6dd74de | | | 66 | const result: ParseResult<T> = parser.parse<T>(text); |
| 6dd74de | | | 67 | if (result.lexerErrors.length > 0 || result.parserErrors.length > 0) { |
| 6dd74de | | | 68 | throw new MermaidParseError(result); |
| 6dd74de | | | 69 | } |
| 6dd74de | | | 70 | return result.value; |
| 6dd74de | | | 71 | } |
| 6dd74de | | | 72 | |
| 6dd74de | | | 73 | export class MermaidParseError extends Error { |
| 6dd74de | | | 74 | constructor(public result: ParseResult<DiagramAST>) { |
| 6dd74de | | | 75 | const lexerErrors: string = result.lexerErrors |
| 6dd74de | | | 76 | .map((err) => { |
| 6dd74de | | | 77 | const line = err.line !== undefined && !isNaN(err.line) ? err.line : '?'; |
| 6dd74de | | | 78 | const column = err.column !== undefined && !isNaN(err.column) ? err.column : '?'; |
| 6dd74de | | | 79 | return `Lexer error on line ${line}, column ${column}: ${err.message}`; |
| 6dd74de | | | 80 | }) |
| 6dd74de | | | 81 | .join('\n'); |
| 6dd74de | | | 82 | const parserErrors: string = result.parserErrors |
| 6dd74de | | | 83 | .map((err) => { |
| 6dd74de | | | 84 | const line = |
| 6dd74de | | | 85 | err.token.startLine !== undefined && !isNaN(err.token.startLine) |
| 6dd74de | | | 86 | ? err.token.startLine |
| 6dd74de | | | 87 | : '?'; |
| 6dd74de | | | 88 | const column = |
| 6dd74de | | | 89 | err.token.startColumn !== undefined && !isNaN(err.token.startColumn) |
| 6dd74de | | | 90 | ? err.token.startColumn |
| 6dd74de | | | 91 | : '?'; |
| 6dd74de | | | 92 | return `Parse error on line ${line}, column ${column}: ${err.message}`; |
| 6dd74de | | | 93 | }) |
| 6dd74de | | | 94 | .join('\n'); |
| 6dd74de | | | 95 | super(`Parsing failed: ${lexerErrors} ${parserErrors}`); |
| 6dd74de | | | 96 | } |
| 6dd74de | | | 97 | } |