public class GuardedAstDelegate extends Object implements RegionRenderer
AST_OK region's parser to
the existing FormatterFactory.pp(parser, opt) machinery, then
runs a TokenEquivalence guard on the result to catch any drift
between input and output.
pp() throws — possible because pp's mediators /
processors traverse arbitrary AST shapes and may break on edge
cases the parser accepts but pp does not yet handle. The throwable
is logged via PPLogger.error(Throwable) and the delegate
returns null so the engine falls through to the next
renderer in the chain.pp() silently drifts — produces output that no
longer round-trips back to the original token sequence (a comment
dropped, a literal rewritten, etc.). The
TokenEquivalence.equalsModuloFormatting(java.lang.String, java.lang.String, gudusoft.gsqlparser.pp2.Pp2FormatOptions) guard from S10
detects this. Failures are logged via PPLogger.info(String)
and the delegate returns null.The guard is plan-mandated insurance against pp drift. Plan §13/R4 names this as the explicit mitigation; the guard converts silent bugs into a recoverable fall-through plus a log line.
The engine only dispatches AST_OK outcomes to this renderer,
so the delegate assumes:
RegionParseOutcome.getStatus() is
AST_OK —
defended by an explicit guard returning null otherwise.RegionParseOutcome.getParser() is non-null and holds
exactly one statement (the S12 contract — verified by
ParseRecoveryEngineTest.parseAll_outcomeParserRendersOnlyItsRegion).RegionParseOutcome.getParsedSql() is the source slice the
parser actually saw (with MSSQL/Sybase GO stripped) — the
guard compares pp's output against this slice, not the raw range
text.Plan reference: §5.2, §7.3/S13, §7.4/S13, §10.2, §13/R4.
| Constructor and Description |
|---|
GuardedAstDelegate(EDbVendor vendor)
Construct a delegate for the supplied vendor.
|
| Modifier and Type | Method and Description |
|---|---|
long |
getGuardFailureCount()
Count of regions where pp() returned text that failed the guard.
|
long |
getSuccessCount()
Count of regions that passed both the parse and the guard.
|
long |
getThrowableCount()
Count of regions where pp() threw.
|
EDbVendor |
getVendor() |
RendererId |
id()
Identifier mirrored on
RendererId so
Pp2FormatResult.Region.getRendererId() reflects which strategy
actually produced the text for the region. |
protected String |
invokePpFormatter(TGSqlParser parser,
GFmtOpt opt)
Indirect-call seam so tests can subclass and substitute a deterministic
stand-in for
FormatterFactory.pp(). |
String |
render(RegionParseOutcome outcome,
Pp2TokenStream stream,
Pp2FormatOptions opts)
Render the outcome's region to its final text.
|
protected String |
renderWith(TGSqlParser parser,
String inputSlice,
Pp2FormatOptions opts)
Render via the supplied parser.
|
public GuardedAstDelegate(EDbVendor vendor)
TokenEquivalence guard to tokenise both the input and the
output for the comparison.NullPointerException - if vendor is nullpublic long getSuccessCount()
public long getThrowableCount()
public long getGuardFailureCount()
public RendererId id()
RegionRendererRendererId so
Pp2FormatResult.Region.getRendererId() reflects which strategy
actually produced the text for the region.id in interface RegionRendererpublic String render(RegionParseOutcome outcome, Pp2TokenStream stream, Pp2FormatOptions opts)
RegionRendererrender in interface RegionRendereroutcome - non-null parse outcome for the region. Implementations
may assume RegionParseOutcome.getRange() and
RegionParseOutcome.getParsedSql() are non-null.
RegionParseOutcome.getParser() is non-null only
for AST_OK
outcomes.stream - the engine's full Pp2TokenStream for the whole
input script (token-based renderers slice into it via
the outcome's range token indices)opts - non-null pp2 optionsnull (the
only sentinel) to signal fall-through to the next renderer
in the chain. An empty string is a valid rendering, not a
fall-through.protected String renderWith(TGSqlParser parser, String inputSlice, Pp2FormatOptions opts)
protected so tests
(in a different package) can drive guard-failure scenarios via a
subclass with a stand-in invokePpFormatter(gudusoft.gsqlparser.TGSqlParser, gudusoft.gsqlparser.pp.para.GFmtOpt). Not part of the
public API; production callers go through render(gudusoft.gsqlparser.pp2.region.RegionParseOutcome, gudusoft.gsqlparser.pp2.token.Pp2TokenStream, gudusoft.gsqlparser.pp2.Pp2FormatOptions).protected String invokePpFormatter(TGSqlParser parser, GFmtOpt opt)
FormatterFactory.pp(). Production code always
goes through the real formatter. protected so the tests in
a different package can override.