001package gudusoft.gsqlparser.parser;
002
003import gudusoft.gsqlparser.EDbVendor;
004
005/**
006 * Strategy interface for vendor-specific SQL parsing.
007 *
008 * <p>This interface defines the contract for all database vendor-specific parsers.
009 * Each vendor (Oracle, MySQL, PostgreSQL, etc.) provides its own implementation
010 * that handles the vendor-specific tokenization, parsing, and semantic analysis.
011 *
012 * <p><b>Design Pattern:</b> Strategy Pattern
013 * <ul>
014 *   <li>The strategy (SqlParser) is selected at runtime based on database vendor</li>
015 *   <li>All inputs come from {@link ParserContext} (immutable)</li>
016 *   <li>All outputs go to {@link SqlParseResult} (immutable)</li>
017 * </ul>
018 *
019 * <p><b>Usage Example:</b>
020 * <pre>
021 * // Get parser for specific vendor
022 * SqlParser parser = SqlParserFactory.get(EDbVendor.dbvoracle);
023 *
024 * // Build context with inputs
025 * ParserContext context = new ParserContext.Builder(EDbVendor.dbvoracle)
026 *     .sqlText("SELECT * FROM employees")
027 *     .build();
028 *
029 * // Parse and get result
030 * SqlParseResult result = parser.parse(context);
031 *
032 * // Access outputs
033 * TStatementList statements = result.getSqlStatements();
034 * </pre>
035 *
036 * @see ParserContext
037 * @see SqlParseResult
038 * @see AbstractSqlParser
039 * @since 3.2.0.0
040 */
041public interface SqlParser {
042
043    /**
044     * Get the database vendor this parser handles.
045     *
046     * @return the database vendor (e.g., dbvoracle, dbvmysql)
047     */
048    EDbVendor getVendor();
049
050    /**
051     * Parse SQL from the given context.
052     *
053     * <p>This method performs full parsing including:
054     * <ul>
055     *   <li>Tokenization (lexical analysis)</li>
056     *   <li>Syntax analysis (building parse tree)</li>
057     *   <li>Semantic analysis (resolving references)</li>
058     * </ul>
059     *
060     * <p>All inputs come from the context parameter, all outputs go to the result.
061     * This ensures clean separation of concerns and thread-safety.
062     *
063     * @param context immutable context containing all parser inputs
064     *                (SQL text, options, callbacks, etc.)
065     * @return immutable result containing all parser outputs
066     *         (statements, tokens, errors, etc.)
067     */
068    SqlParseResult parse(ParserContext context);
069
070    /**
071     * Tokenize SQL without parsing or statement extraction.
072     *
073     * <p>This method performs only tokenization (lexical analysis):
074     * <ul>
075     *   <li>Tokenization (lexical analysis)</li>
076     * </ul>
077     *
078     * <p>The result contains tokens but NO statements. Use this when you only
079     * need the token stream (e.g., for syntax highlighting, token analysis).
080     *
081     * <p>For statement boundaries without full parsing, use {@link #getrawsqlstatements(ParserContext)}.
082     *
083     * @param context immutable context containing all parser inputs
084     * @return immutable result containing tokens only (no statements)
085     */
086    SqlParseResult tokenize(ParserContext context);
087
088    /**
089     * Extract raw SQL statements without full parsing.
090     *
091     * <p>This method performs:
092     * <ul>
093     *   <li>Tokenization (lexical analysis)</li>
094     *   <li>Raw statement extraction (statement boundary detection)</li>
095     * </ul>
096     *
097     * <p>This is faster than {@link #parse(ParserContext)} because it skips
098     * detailed syntax checking and semantic analysis. The statements returned
099     * have their tokens grouped correctly but no AST (parse tree) is built.
100     *
101     * <p><b>Use cases:</b>
102     * <ul>
103     *   <li>Split a script into individual statements</li>
104     *   <li>Determine statement types without full parsing</li>
105     *   <li>Quick validation of statement boundaries</li>
106     *   <li>Pre-processing before selective parsing</li>
107     * </ul>
108     *
109     * <p><b>Equivalent to legacy API:</b> {@code TGSqlParser.getrawsqlstatements()}
110     *
111     * <p><b>Default implementation:</b> For parsers still in delegation phase,
112     * this default implementation falls back to {@link #tokenize(ParserContext)}.
113     * Parsers extending AbstractSqlParser override this with proper implementation.
114     *
115     * @param context immutable context containing all parser inputs
116     * @return immutable result containing tokens and raw statements (no AST)
117     */
118    default SqlParseResult getrawsqlstatements(ParserContext context) {
119        // Default implementation for parsers in delegation phase
120        // Just tokenize - subclasses should override with proper implementation
121        return tokenize(context);
122    }
123
124    /**
125     * Extract raw statements from already-tokenized source without re-tokenization.
126     *
127     * <p>This method is used when tokens are already available from a previous
128     * tokenization step (e.g., via {@code dosqltexttotokenlist()}). It performs
129     * only raw statement extraction without repeating tokenization.
130     *
131     * <p><b>Default implementation:</b> Falls back to tokenize() method for vendors
132     * that haven't implemented this optimization yet.
133     *
134     * @param context immutable context containing all parser inputs
135     * @param tokens already-tokenized source token list
136     * @return statement list containing extracted raw statements
137     * @since 3.2.0.0
138     * @deprecated As of 3.2.0.0, replaced by {@link #getrawsqlstatements(ParserContext)}
139     *             which returns a richer {@link SqlParseResult} object containing statements,
140     *             tokens, errors, timing information, and more. This method only returns
141     *             {@link gudusoft.gsqlparser.TStatementList} without error information.
142     *             <p>
143     *             <b>Migration:</b> Use {@code vendorParser.getrawsqlstatements(context)}
144     *             instead, which performs both tokenization and extraction in a single call
145     *             and returns complete result information via {@link SqlParseResult}.
146     *             <p>
147     *             This method will be removed in a future major version.
148     */
149    @Deprecated
150    default gudusoft.gsqlparser.TStatementList doExtractRawStatements(ParserContext context, gudusoft.gsqlparser.TSourceTokenList tokens) {
151        // Default implementation: fall back to tokenize() which does both tokenization and extraction
152        // Vendors that extend AbstractSqlParser will override this via the doExtractRawStatements() implementation
153//        SqlParseResult result = tokenize(context);
154//        return result.getSqlStatements();
155        return null; // To be implemented by vendors, this method must be orerridden
156    }
157}