001package gudusoft.gsqlparser.pp2; 002 003import gudusoft.gsqlparser.TSyntaxError; 004 005/** 006 * A single diagnostic event produced by the pp2 engine — a recovered parse 007 * failure, a tokenizer gap, a guard fall-through, etc. 008 * 009 * <p>Immutable. Carries the byte-span on the original input that the 010 * diagnostic refers to, a {@link Severity}, a human-readable message, and 011 * (optionally) the underlying {@link TSyntaxError} from the parser when the 012 * diagnostic was triggered by a parse failure. 013 * 014 * <p>Severity policy follows plan §12. Briefly: {@code INFO} for routine 015 * notes (e.g., region too large to parse), {@code WARNING} for recovered 016 * conditions (e.g., AST delegate guard fell through), {@code ERROR} for 017 * parse failures and renderer fall-throughs, {@code FATAL} for invariant 018 * violations that should never occur in practice. 019 */ 020public final class FormatDiagnostic { 021 022 /** Severity level. See class Javadoc and plan §12 for the policy. */ 023 public enum Severity { 024 INFO, 025 WARNING, 026 ERROR, 027 FATAL 028 } 029 030 private final Severity severity; 031 private final int startOffset; 032 private final int endOffset; 033 private final String message; 034 private final TSyntaxError parserError; // nullable 035 036 public FormatDiagnostic(Severity severity, int startOffset, int endOffset, 037 String message) { 038 this(severity, startOffset, endOffset, message, null); 039 } 040 041 public FormatDiagnostic(Severity severity, int startOffset, int endOffset, 042 String message, TSyntaxError parserError) { 043 if (severity == null) throw new NullPointerException("severity"); 044 if (message == null) throw new NullPointerException("message"); 045 if (startOffset < 0) { 046 throw new IllegalArgumentException("startOffset < 0: " + startOffset); 047 } 048 if (endOffset < startOffset) { 049 throw new IllegalArgumentException( 050 "endOffset < startOffset: " + endOffset + " < " + startOffset); 051 } 052 this.severity = severity; 053 this.startOffset = startOffset; 054 this.endOffset = endOffset; 055 this.message = message; 056 this.parserError = parserError; 057 } 058 059 public Severity getSeverity() { return severity; } 060 public int getStartOffset() { return startOffset; } 061 public int getEndOffset() { return endOffset; } 062 public String getMessage() { return message; } 063 064 /** May be {@code null} if the diagnostic did not originate from a parser failure. */ 065 public TSyntaxError getParserError() { return parserError; } 066 067 @Override 068 public String toString() { 069 return "FormatDiagnostic{" + severity + " @" + startOffset + ".." + endOffset 070 + " " + message + (parserError != null ? " (parser)" : "") + "}"; 071 } 072}