package engine import ( "bytes" "gitea.maximumdirect.net/eric/ConfigKit/internal/document" yamladapter "gitea.maximumdirect.net/eric/ConfigKit/internal/yaml" ) const ( maxDocumentDepth = 256 maxDocumentNodes = 1_000_000 ) type parseLimits struct { source sourceLimits document yamladapter.Limits } func defaultParseLimits() parseLimits { return parseLimits{ source: defaultSourceLimits(), document: yamladapter.Limits{ Depth: maxDocumentDepth, Nodes: maxDocumentNodes, }, } } type parsedSource struct { document *document.Node source *SourceInfo bytes int64 } // parserDiagnostics translates adapter issues into detached, ordered public records. func parserDiagnostics(sourceID string, issues []yamladapter.Issue) []Diagnostic { diagnostics := make([]Diagnostic, len(issues)) for index, issue := range issues { diagnostics[index] = Diagnostic{ Code: Code(issue.Code), Severity: SeverityError, Message: issue.Message, Primary: &Location{SourceID: sourceID, Line: issue.Line, Column: issue.Column}, } for _, related := range issue.Related { diagnostics[index].Related = append(diagnostics[index].Related, publicLocation(related)) } } return canonicalDiagnostics(diagnostics) } func parseSource(source Source, sourceID string, limits parseLimits) (parsedSource, []Diagnostic) { read, diagnostics := readSource(source, sourceID, limits.source) if len(diagnostics) != 0 || read.info == nil { return parsedSource{source: read.info}, diagnostics } if read.document != nil { return parsedSource{document: read.document, source: read.info, bytes: read.bytes}, nil } root, issues := yamladapter.Parse(bytes.NewReader(read.data), sourceID, limits.document) if len(issues) != 0 { return parsedSource{source: read.info, bytes: int64(len(read.data))}, parserDiagnostics(sourceID, issues) } return parsedSource{document: root, source: read.info, bytes: int64(len(read.data))}, nil }