11import { type Annotation , Editor } from 'brace' ;
22import type { ErrorObject } from 'ajv' ;
3- import { jsonPointerToPath } from '@/utility/pathUtils' ;
3+ import { jsonPointerToPath , pathToJsonPointer } from '@/utility/pathUtils' ;
44import { determineCursorPosition } from '@/components/panels/code-editor/aceUtility' ;
55import { computed } from 'vue' ;
6- import { useDataConverter } from '@/dataformats/formatRegistry' ;
6+ import { useDataConverter , usePathIndexLink } from '@/dataformats/formatRegistry' ;
77import { watchDebounced } from '@vueuse/core' ;
88import type { SessionMode } from '@/store/sessionMode' ;
99import { getValidationForMode } from '@/data/useDataLink' ;
@@ -12,6 +12,7 @@ import {useSettings} from '@/settings/useSettings';
1212/**
1313 * Sets up the editor to show validation errors.
1414 * @param editor the ace editor
15+ * @param mode
1516 */
1617export function setupAnnotationsFromValidationErrors ( editor : Editor , mode : SessionMode ) {
1718 const validationAnnotations = computed ( ( ) => {
@@ -22,11 +23,21 @@ export function setupAnnotationsFromValidationErrors(editor: Editor, mode: Sessi
2223 }
2324
2425 let { errors} = getValidationForMode ( mode ) . currentValidationResult . value ;
25- const maxErrorsToShow = useSettings ( ) . value . performance . maxErrorsToShow ;
26+
27+ const supportsBulkPathDetermination = usePathIndexLink ( ) . determineIndexesOfPaths !== undefined ;
28+
29+ const maxErrorsToShow = supportsBulkPathDetermination
30+ ? useSettings ( ) . value . performance . maxErrorsToShowBulkValidation
31+ : useSettings ( ) . value . performance . maxErrorsToShow ;
2632 if ( errors . length > maxErrorsToShow ) {
2733 errors = errors . slice ( 0 , maxErrorsToShow ) ;
2834 }
29- return errors . map ( error => validationErrorToAnnotation ( editor , error ) ) ;
35+
36+ if ( supportsBulkPathDetermination ) {
37+ return validationErrorsToAnnotations ( editor , errors ) ;
38+ } else {
39+ return errors . map ( error => validationErrorToAnnotation ( editor , error ) ) ;
40+ }
3041 } ) ;
3142
3243 watchDebounced (
@@ -46,3 +57,42 @@ function validationErrorToAnnotation(editor: Editor, error: ErrorObject): Annota
4657 type : 'error' ,
4758 } ;
4859}
60+
61+ // optimized version that uses bulk path index determination
62+ function validationErrorsToAnnotations ( editor : Editor , errors : ErrorObject [ ] ) : Annotation [ ] {
63+ const result : Annotation [ ] = [ ] ;
64+ const positions = usePathIndexLink ( ) . determineIndexesOfPaths ! (
65+ editor . getValue ( ) ,
66+ errors . map ( error => jsonPointerToPath ( error . instancePath ) )
67+ ) ;
68+
69+ const cachedPositionsForIndices : { [ index : number ] : { row : number ; column : number } } = { } ;
70+
71+ for ( const error of errors ) {
72+ const instancePathTranslated = jsonPointerToPath ( error . instancePath ) ;
73+ // note that we use our own pathToJsonPointer here, to ensure consistent serialization
74+ const instancePathKey = pathToJsonPointer ( instancePathTranslated ) ;
75+ if ( ! ( instancePathKey in positions ) ) {
76+ continue ;
77+ }
78+
79+ const index = positions [ instancePathKey ] ;
80+ let position ;
81+ if ( index in cachedPositionsForIndices ) {
82+ position = cachedPositionsForIndices [ index ] ;
83+ } else {
84+ position = editor . session . doc . indexToPosition ( index , 0 ) ;
85+ cachedPositionsForIndices [ index ] = position ;
86+ }
87+
88+ const annotation : Annotation = {
89+ row : position . row ,
90+ column : position . column ,
91+ text : error . message ?? 'Validation error' ,
92+ type : 'error' ,
93+ } ;
94+ result . push ( annotation ) ;
95+ }
96+
97+ return result ;
98+ }
0 commit comments