class RSyntaxSQLParser extends AbstractParser {

    @Override
    public ParseResult parse(RSyntaxDocument doc, String style) {
        DefaultParseResult res = new DefaultParseResult(this);
        int docLength = doc.getLength();
        if (docLength==0) {
            return res;
        }
        DocumentSQLReader documentReader = new DocumentSQLReader(doc);
        long start = System.currentTimeMillis();
        try {
            try (Connection connection = dataSource.getConnection()) {
                while (documentReader.hasNext()) {
                    String statement = documentReader.next();
                    if (!documentReader.isInsideRemark()) {
                        try {
                            connection.prepareStatement(statement);
                        } catch (SQLException ex) {
                            // Find the beginning of the rightmost word in error
                            int syntaxErrorPosition = ex.getLocalizedMessage().indexOf("[*]");
                            int syntaxErrorLength;
                            if (syntaxErrorPosition == -1) {
                                // Could not find exact position, underline all the statement (remove preceding line break)
                                syntaxErrorPosition = statement.indexOf(statement.trim());
                                syntaxErrorLength = statement.length() - syntaxErrorPosition;
                            } else {
                                int[] syntaxWord = getLastWordPositionAndLength(ex.getLocalizedMessage(), syntaxErrorPosition);
                                String word = ex.getLocalizedMessage().substring(syntaxWord[WORD_POSITION], syntaxWord[WORD_POSITION] + syntaxWord[WORD_LENGTH]);
                                syntaxErrorPosition = statement.toLowerCase().indexOf(word.toLowerCase());
                                syntaxErrorLength = syntaxWord[WORD_LENGTH];
                            }
                            // Compute syntax error position from the beginning of the document, (-1 is length of ; char)
                            int syntaxErrorPositionOffset = Math.min(docLength,
                                    documentReader.getPosition() + syntaxErrorPosition);
                            DefaultParserNotice notice = new DefaultParserNotice(this, ex.getLocalizedMessage(),
                                    documentReader.getLineIndex(syntaxErrorPositionOffset), syntaxErrorPositionOffset,
                                    syntaxErrorLength);
                            notice.setLevel(ParserNotice.Level.ERROR);
                            res.addNotice(notice);
                        }
                    }
                }
            }
        } catch (SQLException ex) {
            log.trace(ex.getLocalizedMessage(), ex);
            // ignore
        }
        long time = System.currentTimeMillis() - start;
        res.setParseTime(time);
        return res;
    }

    public  RSyntaxSQLParser(DataSource dataSource);

}