aboutsummaryrefslogtreecommitdiffstats
path: root/yql/essentials/sql/v1/complete/syntax/token.cpp
blob: b8aee3211c682d682af1f4776c044a0490db3450 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include "token.h"

#include <yql/essentials/core/issue/yql_issue.h>
#include <yql/essentials/sql/v1/lexer/lexer.h>

namespace NSQLComplete {

    bool GetStatement(NSQLTranslation::ILexer::TPtr& lexer, TCompletionInput input, TCompletionInput& output) {
        TVector<TString> statements;
        NYql::TIssues issues;
        if (!NSQLTranslationV1::SplitQueryToStatements(
                TString(input.Text) + ";", lexer,
                statements, issues, /* file = */ "",
                /* areBlankSkipped = */ false)) {
            return false;
        }

        size_t cursor = 0;
        for (const auto& statement : statements) {
            if (input.CursorPosition < cursor + statement.size()) {
                output = {
                    .Text = input.Text.SubStr(cursor, statement.size()),
                    .CursorPosition = input.CursorPosition - cursor,
                };
                return true;
            }
            cursor += statement.size();
        }

        output = input;
        return true;
    }

    TCaretTokenPosition CaretTokenPosition(const TParsedTokenList& tokens, size_t cursorPosition) {
        size_t cursor = 0;
        for (size_t i = 0; i < tokens.size(); ++i) {
            const auto& content = tokens[i].Content;
            cursor += content.size();
            if (cursorPosition < cursor) {
                return {i, i};
            } else if (cursorPosition == cursor && IsWordBoundary(content.back())) {
                return {i, i + 1};
            }
        }
        return {std::max(tokens.size(), static_cast<size_t>(1)) - 1, tokens.size()};
    }

    bool EndsWith(const TParsedTokenList& tokens, const TVector<TStringBuf>& pattern) {
        if (tokens.size() < pattern.size()) {
            return false;
        }
        for (yssize_t i = tokens.ysize() - 1, j = pattern.ysize() - 1; 0 <= j; --i, --j) {
            if (!pattern[j].empty() && tokens[i].Name != pattern[j]) {
                return false;
            }
        }
        return true;
    }

} // namespace NSQLComplete