public final class AstOverlayAnnotator extends Object
Reads a parsed TCustomSqlStatement and stamps AST-derived
TokenRoles (AST_SELECT_LIST_ITEM, AST_TABLE_REF,
AST_WHERE_CONDITION) onto the matching Pp2Tokens in a
Pp2TokenStream. The wrapped TSourceToken is never mutated;
only the Pp2Token.roles side-channel is written (forbidden #6
explicitly permits designated annotator stages to write roles).
Feature flag. This annotator is off by default in v2
(Pp2FormatOptions.astOverlayEnabled == false). When the flag is on,
Pp2Engine invokes it for each cleanly-parsed (AST_OK) region. v2
does not yet render from these roles — that is v3's
AstOverlayRenderer. Landing the annotation infrastructure now means
v3 is a flag flip plus a renderer add, not a re-architecture.
The stream passed to annotate(gudusoft.gsqlparser.TCustomSqlStatement, gudusoft.gsqlparser.pp2.token.Pp2TokenStream) MUST be built from the
same parse (same TSourceTokenList) as stmt's AST, so
the AST node start/end token offsets line up with the stream tokens'
TSourceToken.offset. Pp2Engine guarantees this by building
the region stream from the region parser's own token list; the standalone
tests build the stream from the same TGSqlParser that produced the
statement.
UNION / INTERSECT / EXCEPT statements form a deep left-leaning
leftStmt/rightStmt tree from the left-recursive grammar. A
recursive descent would StackOverflowError on 2000-deep set
operations. This annotator walks that tree with an explicit
ArrayDeque. Within each leaf SELECT, the result-column list and
table list are bounded in width (not depth), so a flat iteration over them
is safe. The annotator never descends the WHERE expression tree — it marks
the flat token span of the TWhereClause node only, so deep AND/OR
expression trees cannot trigger recursion here either.
| Constructor and Description |
|---|
AstOverlayAnnotator() |
| Modifier and Type | Method and Description |
|---|---|
int |
annotate(TCustomSqlStatement stmt,
Pp2TokenStream stream)
Annotate
stream with AST-derived roles from stmt, where
the stream and the AST come from the same parse (offset adjustment 0). |
int |
annotate(TCustomSqlStatement stmt,
Pp2TokenStream stream,
long offsetAdjustment)
Annotate
stream with AST-derived roles from stmt, applying
a fixed offsetAdjustment to every AST node span before matching it
against the stream tokens' absolute offsets. |
public AstOverlayAnnotator()
public int annotate(TCustomSqlStatement stmt, Pp2TokenStream stream)
stream with AST-derived roles from stmt, where
the stream and the AST come from the same parse (offset adjustment 0).stmt - a parsed statement root; may be null (no-op, returns 0)stream - the token stream built from the same parse; may be null
(no-op, returns 0)(token, role) annotations applied (a token
touched by two roles counts twice). Useful for tests and for a
v3 caller to know whether the overlay produced anything.public int annotate(TCustomSqlStatement stmt, Pp2TokenStream stream, long offsetAdjustment)
stream with AST-derived roles from stmt, applying
a fixed offsetAdjustment to every AST node span before matching it
against the stream tokens' absolute offsets.
This is the engine wiring seam: Pp2Engine parses each region
from originalSql.substring(range.getStartOffset(), ...), so the
region AST's token offsets are relative to the region substring. Passing
offsetAdjustment = range.getStartOffset() translates them onto the
engine's whole-script stream so the roles land on the exact tokens the
renderers see. (The same-parse overload passes 0.)
stmt - parsed statement root; may be null (no-op)stream - target stream (absolute offsets); may be null (no-op)offsetAdjustment - added to each AST node's start/end offset before
matching against stream token offsets(token, role) annotations applied