From 7a66c0a62197a3017308fd4ea229726e45050932 Mon Sep 17 00:00:00 2001 From: "nathan.xu" Date: Wed, 23 Oct 2024 00:18:55 -0400 Subject: [PATCH] HHH-18754 improve HQLParser's error listener usage in StandardHqlTranslator --- .../hql/internal/StandardHqlTranslator.java | 60 +++++++------------ 1 file changed, 23 insertions(+), 37 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/StandardHqlTranslator.java b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/StandardHqlTranslator.java index ab0d411b77fc..7a1bba8add18 100644 --- a/hibernate-core/src/main/java/org/hibernate/query/hql/internal/StandardHqlTranslator.java +++ b/hibernate-core/src/main/java/org/hibernate/query/hql/internal/StandardHqlTranslator.java @@ -4,52 +4,57 @@ */ package org.hibernate.query.hql.internal; -import java.util.BitSet; - +import org.antlr.v4.runtime.ANTLRErrorListener; +import org.antlr.v4.runtime.BailErrorStrategy; +import org.antlr.v4.runtime.BaseErrorListener; import org.antlr.v4.runtime.CommonToken; +import org.antlr.v4.runtime.CommonTokenStream; +import org.antlr.v4.runtime.DefaultErrorStrategy; import org.antlr.v4.runtime.InputMismatchException; import org.antlr.v4.runtime.NoViableAltException; +import org.antlr.v4.runtime.RecognitionException; +import org.antlr.v4.runtime.Recognizer; +import org.antlr.v4.runtime.atn.PredictionMode; +import org.antlr.v4.runtime.misc.ParseCancellationException; import org.hibernate.QueryException; import org.hibernate.grammars.hql.HqlLexer; import org.hibernate.grammars.hql.HqlParser; -import org.hibernate.query.sqm.EntityTypeException; -import org.hibernate.query.sqm.PathElementException; import org.hibernate.query.SyntaxException; -import org.hibernate.query.sqm.TerminalPathException; import org.hibernate.query.hql.HqlLogging; import org.hibernate.query.hql.HqlTranslator; import org.hibernate.query.hql.spi.SqmCreationOptions; +import org.hibernate.query.sqm.EntityTypeException; import org.hibernate.query.sqm.InterpretationException; import org.hibernate.query.sqm.ParsingException; +import org.hibernate.query.sqm.PathElementException; +import org.hibernate.query.sqm.TerminalPathException; import org.hibernate.query.sqm.UnknownEntityException; import org.hibernate.query.sqm.UnknownPathException; import org.hibernate.query.sqm.internal.SqmTreePrinter; import org.hibernate.query.sqm.spi.SqmCreationContext; import org.hibernate.query.sqm.tree.SqmStatement; -import org.antlr.v4.runtime.ANTLRErrorListener; -import org.antlr.v4.runtime.BailErrorStrategy; -import org.antlr.v4.runtime.DefaultErrorStrategy; -import org.antlr.v4.runtime.Parser; -import org.antlr.v4.runtime.RecognitionException; -import org.antlr.v4.runtime.Recognizer; -import org.antlr.v4.runtime.atn.ATNConfigSet; -import org.antlr.v4.runtime.atn.PredictionMode; -import org.antlr.v4.runtime.dfa.DFA; -import org.antlr.v4.runtime.misc.ParseCancellationException; - import static java.util.stream.Collectors.toList; /** * Standard implementation of {@link HqlTranslator}. * * @author Steve Ebersole + * @author Nathan Xu */ public class StandardHqlTranslator implements HqlTranslator { private final SqmCreationContext sqmCreationContext; private final SqmCreationOptions sqmCreationOptions; + private static final ANTLRErrorListener PRETTIFY_ERROR_LISTENER = new BaseErrorListener() { + @Override + public void syntaxError(Recognizer recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) { + CommonTokenStream cts = (CommonTokenStream) recognizer.getInputStream(); + String hql = cts.getTokenSource().getInputStream().toString(); + throw new SyntaxException( prettifyAntlrError( offendingSymbol, line, charPositionInLine, msg, e, hql, true ), hql ); + } + }; public StandardHqlTranslator( SqmCreationContext sqmCreationContext, @@ -101,30 +106,9 @@ private HqlParser.StatementContext parseHql(String hql) { // Build the parse tree final HqlParser hqlParser = HqlParseTreeBuilder.INSTANCE.buildHqlParser( hql, hqlLexer ); - ANTLRErrorListener errorListener = new ANTLRErrorListener() { - @Override - public void syntaxError(Recognizer recognizer, Object offendingSymbol, int line, int charPositionInLine, String msg, RecognitionException e) { - throw new SyntaxException( prettifyAntlrError( offendingSymbol, line, charPositionInLine, msg, e, hql, true ), hql ); - } - - @Override - public void reportAmbiguity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, boolean exact, BitSet ambigAlts, ATNConfigSet configs) { - } - - @Override - public void reportAttemptingFullContext(Parser recognizer, DFA dfa, int startIndex, int stopIndex, BitSet conflictingAlts, ATNConfigSet configs) { - } - - @Override - public void reportContextSensitivity(Parser recognizer, DFA dfa, int startIndex, int stopIndex, int prediction, ATNConfigSet configs) { - } - }; - // try to use SLL(k)-based parsing first - its faster - hqlLexer.addErrorListener( errorListener ); hqlParser.getInterpreter().setPredictionMode( PredictionMode.SLL ); hqlParser.removeErrorListeners(); - hqlParser.addErrorListener( errorListener ); hqlParser.setErrorHandler( new BailErrorStrategy() ); try { @@ -139,6 +123,8 @@ public void reportContextSensitivity(Parser recognizer, DFA dfa, int startIndex, hqlParser.getInterpreter().setPredictionMode( PredictionMode.LL ); hqlParser.setErrorHandler( new DefaultErrorStrategy() ); + hqlParser.addErrorListener( PRETTIFY_ERROR_LISTENER ); + return hqlParser.statement(); } catch ( ParsingException ex ) {