55 ******************************************************************************/
66
77/* eslint-disable @typescript-eslint/no-explicit-any */
8- import type { DSLMethodOpts , ILexingError , IOrAlt , IParserErrorMessageProvider , IRecognitionException , IToken , TokenType , TokenVocabulary , IRuleConfig } from 'chevrotain' ;
9- import type { AbstractElement , Action , Assignment , InfixRule , ParserRule } from '../languages/generated/ast.js' ;
108import { isInfixRule } from '../languages/generated/ast.js' ;
9+ import type { AbstractElement , Action , Assignment , InfixRule , ParserRule } from '../languages/generated/ast.js' ;
10+ import type { DSLMethodOpts , ILexingError , IOrAlt , IParserErrorMessageProvider , IRecognitionException , IToken , ParserMethod , SubruleMethodOpts , TokenType , TokenVocabulary , IRuleConfig } from 'chevrotain' ;
1111import type { Linker } from '../references/linker.js' ;
1212import type { LangiumCoreServices } from '../services.js' ;
1313import type { AstNode , AstReflection , CompositeCstNode , CstNode } from '../syntax-tree.js' ;
@@ -21,6 +21,7 @@ import { getExplicitRuleType, isDataTypeRule } from '../utils/grammar-utils.js';
2121import { assignMandatoryProperties , getContainerOfType , linkContentToContainer } from '../utils/ast-utils.js' ;
2222import { CstNodeBuilder } from './cst-node-builder.js' ;
2323import type { LexingReport } from './token-builder.js' ;
24+ import type { ProfilingTask } from '../workspace/profiler.js' ;
2425
2526export type ParseResult < T = AstNode > = {
2627 value : T ,
@@ -140,11 +141,19 @@ export abstract class AbstractLangiumParser implements BaseParser {
140141 this . lexer = services . parser . Lexer ;
141142 const tokens = this . lexer . definition ;
142143 const production = services . LanguageMetaData . mode === 'production' ;
143- this . wrapper = new ChevrotainWrapper ( tokens , {
144- ...services . parser . ParserConfig ,
145- skipValidations : production ,
146- errorMessageProvider : services . parser . ParserErrorMessageProvider
147- } ) ;
144+ if ( services . shared . profilers . LangiumProfiler ?. isActive ( 'parsing' ) ) {
145+ this . wrapper = new ProfilerWrapper ( tokens , {
146+ ...services . parser . ParserConfig ,
147+ skipValidations : production ,
148+ errorMessageProvider : services . parser . ParserErrorMessageProvider
149+ } , services . shared . profilers . LangiumProfiler . createTask ( 'parsing' , services . LanguageMetaData . languageId ) ) ;
150+ } else {
151+ this . wrapper = new ChevrotainWrapper ( tokens , {
152+ ...services . parser . ParserConfig ,
153+ skipValidations : production ,
154+ errorMessageProvider : services . parser . ParserErrorMessageProvider
155+ } ) ;
156+ }
148157 }
149158
150159 alternatives ( idx : number , choices : Array < IOrAlt < any > > ) : void {
@@ -283,7 +292,7 @@ export class LangiumParser extends AbstractLangiumParser {
283292 }
284293
285294 private doParse ( rule : RuleResult ) : any {
286- let result = rule . call ( this . wrapper , { } ) ;
295+ let result = this . wrapper . rule ( rule ) ;
287296 if ( this . stack . length > 0 ) {
288297 // In case the parser throws on the entry rule, `construct` is not called
289298 // We need to call it manually here
@@ -846,4 +855,40 @@ class ChevrotainWrapper extends EmbeddedActionsParser {
846855 wrapAtLeastOne ( idx : number , callback : DSLMethodOpts < unknown > ) : void {
847856 this . atLeastOne ( idx , callback ) ;
848857 }
858+ rule ( rule : RuleResult ) : any {
859+ return rule . call ( this , { } ) ;
860+ }
861+ }
862+
863+ class ProfilerWrapper extends ChevrotainWrapper {
864+ private readonly task : ProfilingTask ;
865+ constructor ( tokens : TokenVocabulary , config : IParserConfig , task : ProfilingTask ) {
866+ super ( tokens , config ) ;
867+ this . task = task ;
868+ }
869+
870+ override rule ( rule : RuleResult ) : any {
871+ this . task . start ( ) ;
872+ this . task . startSubTask ( this . ruleName ( rule ) ) ;
873+ try {
874+ return super . rule ( rule ) ;
875+ }
876+ finally {
877+ this . task . stopSubTask ( this . ruleName ( rule ) ) ;
878+ this . task . stop ( ) ;
879+ }
880+ }
881+
882+ private ruleName ( rule : any ) : string {
883+ return rule . ruleName as string ;
884+ }
885+ protected override subrule < ARGS extends unknown [ ] , R > ( idx : number , ruleToCall : ParserMethod < ARGS , R > , options ?: SubruleMethodOpts < ARGS > ) : R {
886+ this . task . startSubTask ( this . ruleName ( ruleToCall ) ) ;
887+ try {
888+ return super . subrule < ARGS , R > ( idx , ruleToCall , options ) ;
889+ }
890+ finally {
891+ this . task . stopSubTask ( this . ruleName ( ruleToCall ) ) ;
892+ }
893+ }
849894}
0 commit comments