From 9e1922fa126b6b7f79ddd9561ad42adda19ec6a7 Mon Sep 17 00:00:00 2001 From: ykiko Date: Fri, 19 Jun 2026 12:26:06 +0800 Subject: [PATCH 1/8] refactor: replace PositionMapper with free-function line_starts API Adopt kotatsu's decomposed position mapping API (build_line_starts, to_position, to_offset) to eliminate the PositionMapper class abstraction. - Store line_starts in Session, rebuilt on didOpen/didChange - Replace OpenFileIndex with lightweight FileOverlay view struct - Cache line_starts lazily in MergedIndexShard for index queries - Update all feature files, compiler, indexer, and agent client - Bump kotatsu to 980c178 (merged PR #171) --- cmake/package.cmake | 2 +- src/feature/code_completion.cpp | 6 +- src/feature/diagnostics.cpp | 15 +- src/feature/document_links.cpp | 4 +- src/feature/document_symbols.cpp | 19 +-- src/feature/feature.h | 13 +- src/feature/folding_ranges.cpp | 7 +- src/feature/formatting.cpp | 10 +- src/feature/hover.cpp | 5 +- src/feature/inlay_hints.cpp | 5 +- src/feature/semantic_tokens.cpp | 14 +- src/server/compiler/compiler.cpp | 32 ++--- src/server/compiler/indexer.cpp | 141 +++++++++++-------- src/server/compiler/indexer.h | 18 +-- src/server/service/agent_client.cpp | 74 ++++++---- src/server/service/lsp_client.cpp | 13 +- src/server/service/master_server.cpp | 8 +- src/server/service/session.h | 12 +- src/server/workspace/workspace.cpp | 21 +-- src/server/workspace/workspace.h | 103 +++++++------- tests/unit/feature/document_link_tests.cpp | 10 +- tests/unit/feature/document_symbol_tests.cpp | 28 ++-- tests/unit/feature/folding_range_tests.cpp | 20 ++- tests/unit/feature/inlay_hint_tests.cpp | 15 +- tests/unit/feature/semantic_tokens_tests.cpp | 7 +- tests/unit/index/tu_index_tests.cpp | 7 +- 26 files changed, 363 insertions(+), 246 deletions(-) diff --git a/cmake/package.cmake b/cmake/package.cmake index eddadea5..6049f284 100644 --- a/cmake/package.cmake +++ b/cmake/package.cmake @@ -41,7 +41,7 @@ set(FLATBUFFERS_BUILD_FLATHASH OFF CACHE BOOL "" FORCE) FetchContent_Declare( kotatsu GIT_REPOSITORY https://github.com/clice-io/kotatsu - GIT_TAG b4bcd3c7e011812a345b4c520ccc77a6ed09174b + GIT_TAG 980c178 ) set(KOTA_ENABLE_ZEST ON) diff --git a/src/feature/code_completion.cpp b/src/feature/code_completion.cpp index b883d5ab..21accd96 100644 --- a/src/feature/code_completion.cpp +++ b/src/feature/code_completion.cpp @@ -255,10 +255,10 @@ class CodeCompletionCollector final : public clang::CodeCompleteConsumer { auto prefix = CompletionPrefix::from(content, offset); FuzzyMatcher matcher(prefix.spelling); - PositionMapper converter(content, encoding); + auto line_starts = lsp::build_line_starts(content); auto replace_range = protocol::Range{ - .start = *converter.to_position(prefix.range.begin), - .end = *converter.to_position(prefix.range.end), + .start = *lsp::to_position(content, line_starts, encoding, prefix.range.begin), + .end = *lsp::to_position(content, line_starts, encoding, prefix.range.end), }; std::vector collected; diff --git a/src/feature/diagnostics.cpp b/src/feature/diagnostics.cpp index 7eb5cbf7..988e33ed 100644 --- a/src/feature/diagnostics.cpp +++ b/src/feature/diagnostics.cpp @@ -10,8 +10,6 @@ namespace clice::feature { namespace { -namespace lsp = kota::ipc::lsp; - auto to_uri(llvm::StringRef file) -> std::string { const auto file_view = std::string_view(file.data(), file.size()); @@ -49,13 +47,13 @@ void add_related(protocol::Diagnostic& diagnostic, } auto content = unit.file_content(raw.fid); - PositionMapper converter(content, encoding); + auto line_starts = lsp::build_line_starts(content); protocol::DiagnosticRelatedInformation related{ .location = protocol::Location{ .uri = to_uri(unit.file_path(raw.fid)), - .range = to_range(converter, raw.range), + .range = to_range(content, line_starts, encoding, raw.range), }, .message = raw.message, }; @@ -80,7 +78,8 @@ auto diagnostics(CompilationUnitRef unit, PositionEncoding encoding) } }; - PositionMapper main_converter(unit.interested_content(), encoding); + auto main_content = unit.interested_content(); + auto main_line_starts = lsp::build_line_starts(main_content); for(const auto& raw: unit.diagnostics()) { auto level = raw.id.level; @@ -136,7 +135,7 @@ auto diagnostics(CompilationUnitRef unit, PositionEncoding encoding) } if(raw.fid == unit.interested_file()) { - diagnostic.range = to_range(main_converter, raw.range); + diagnostic.range = to_range(main_content, main_line_starts, encoding, raw.range); current = std::move(diagnostic); continue; } @@ -154,8 +153,8 @@ auto diagnostics(CompilationUnitRef unit, PositionEncoding encoding) auto offset = unit.file_offset(include_location); auto end_offset = offset + unit.token_spelling(include_location).size(); diagnostic.range = protocol::Range{ - .start = *main_converter.to_position(offset), - .end = *main_converter.to_position(end_offset), + .start = *lsp::to_position(main_content, main_line_starts, encoding, offset), + .end = *lsp::to_position(main_content, main_line_starts, encoding, end_offset), }; current = std::move(diagnostic); diff --git a/src/feature/document_links.cpp b/src/feature/document_links.cpp index 56320ec8..1813bade 100644 --- a/src/feature/document_links.cpp +++ b/src/feature/document_links.cpp @@ -18,7 +18,7 @@ auto document_links(CompilationUnitRef unit, PositionEncoding encoding) } auto content = unit.interested_content(); - PositionMapper converter(content, encoding); + auto line_starts = lsp::build_line_starts(content); auto& directives = directives_it->second; auto* lang_opts = &unit.lang_options(); @@ -29,7 +29,7 @@ auto document_links(CompilationUnitRef unit, PositionEncoding encoding) auto range = find_directive_argument(content, offset, lang_opts); if(!range) return; - protocol::DocumentLink link{.range = to_range(converter, *range)}; + protocol::DocumentLink link{.range = to_range(content, line_starts, encoding, *range)}; link.target = target.str(); links.push_back(std::move(link)); }; diff --git a/src/feature/document_symbols.cpp b/src/feature/document_symbols.cpp index 70ddba71..7bc87ac9 100644 --- a/src/feature/document_symbols.cpp +++ b/src/feature/document_symbols.cpp @@ -178,13 +178,15 @@ void sort_symbols(std::vector& symbols) { } } -auto to_protocol_symbol(const DocumentSymbol& symbol, const PositionMapper& converter) - -> protocol::DocumentSymbol { +auto to_protocol_symbol(const DocumentSymbol& symbol, + std::string_view content, + std::span line_starts, + lsp::PositionEncoding encoding) -> protocol::DocumentSymbol { protocol::DocumentSymbol result{ .name = symbol.name, .kind = to_protocol_symbol_kind(symbol.kind), - .range = to_range(converter, symbol.range), - .selection_range = to_range(converter, symbol.selection_range), + .range = to_range(content, line_starts, encoding, symbol.range), + .selection_range = to_range(content, line_starts, encoding, symbol.selection_range), }; if(!symbol.detail.empty()) { @@ -195,8 +197,8 @@ auto to_protocol_symbol(const DocumentSymbol& symbol, const PositionMapper& conv std::vector> children; children.reserve(symbol.children.size()); for(const auto& child: symbol.children) { - children.push_back( - std::make_shared(to_protocol_symbol(child, converter))); + children.push_back(std::make_shared( + to_protocol_symbol(child, content, line_starts, encoding))); } result.children = std::move(children); } @@ -216,12 +218,13 @@ auto document_symbols(CompilationUnitRef unit, PositionEncoding encoding) -> std::vector { auto internal = document_symbols(unit); - PositionMapper converter(unit.interested_content(), encoding); + auto content = unit.interested_content(); + auto line_starts = lsp::build_line_starts(content); std::vector symbols; symbols.reserve(internal.size()); for(const auto& symbol: internal) { - symbols.push_back(to_protocol_symbol(symbol, converter)); + symbols.push_back(to_protocol_symbol(symbol, content, line_starts, encoding)); } return symbols; diff --git a/src/feature/feature.h b/src/feature/feature.h index 86eda11e..a9f2c65a 100644 --- a/src/feature/feature.h +++ b/src/feature/feature.h @@ -2,7 +2,9 @@ #include #include +#include #include +#include #include #include "compile/compilation.h" @@ -15,16 +17,19 @@ namespace clice::feature { +namespace lsp = kota::ipc::lsp; namespace protocol = kota::ipc::protocol; using kota::ipc::lsp::PositionEncoding; -using kota::ipc::lsp::PositionMapper; using kota::ipc::lsp::parse_position_encoding; -inline auto to_range(const PositionMapper& converter, LocalSourceRange range) -> protocol::Range { +inline auto to_range(std::string_view content, + std::span line_starts, + lsp::PositionEncoding encoding, + LocalSourceRange range) -> protocol::Range { return protocol::Range{ - .start = *converter.to_position(range.begin), - .end = *converter.to_position(range.end), + .start = *lsp::to_position(content, line_starts, encoding, range.begin), + .end = *lsp::to_position(content, line_starts, encoding, range.end), }; } diff --git a/src/feature/folding_ranges.cpp b/src/feature/folding_ranges.cpp index 6f53fb99..723b9283 100644 --- a/src/feature/folding_ranges.cpp +++ b/src/feature/folding_ranges.cpp @@ -349,14 +349,15 @@ auto folding_ranges(CompilationUnitRef unit) -> std::vector { auto folding_ranges(CompilationUnitRef unit, PositionEncoding encoding) -> std::vector { auto collected = folding_ranges(unit); - PositionMapper converter(unit.interested_content(), encoding); + auto content = unit.interested_content(); + auto line_starts = lsp::build_line_starts(content); std::vector result; result.reserve(collected.size()); for(const auto& item: collected) { - auto start = *converter.to_position(item.range.begin); - auto end = *converter.to_position(item.range.end); + auto start = *lsp::to_position(content, line_starts, encoding, item.range.begin); + auto end = *lsp::to_position(content, line_starts, encoding, item.range.end); protocol::FoldingRange range{ .start_line = start.line, diff --git a/src/feature/formatting.cpp b/src/feature/formatting.cpp index 0be63702..ad640b12 100644 --- a/src/feature/formatting.cpp +++ b/src/feature/formatting.cpp @@ -53,12 +53,16 @@ auto document_format(llvm::StringRef file, return edits; } - PositionMapper converter(content, encoding); + auto line_starts = lsp::build_line_starts(content); for(const auto& replacement: *replacements) { protocol::TextEdit edit; - edit.range.start = *converter.to_position(replacement.getOffset()); - edit.range.end = *converter.to_position(replacement.getOffset() + replacement.getLength()); + edit.range.start = + *lsp::to_position(content, line_starts, encoding, replacement.getOffset()); + edit.range.end = *lsp::to_position(content, + line_starts, + encoding, + replacement.getOffset() + replacement.getLength()); edit.new_text = replacement.getReplacementText().str(); edits.push_back(std::move(edit)); } diff --git a/src/feature/hover.cpp b/src/feature/hover.cpp index b602fe6a..5d8beaee 100644 --- a/src/feature/hover.cpp +++ b/src/feature/hover.cpp @@ -1310,8 +1310,9 @@ auto to_protocol_hover(CompilationUnitRef unit, }; if(info.symbol_range) { - PositionMapper converter(unit.interested_content(), encoding); - result.range = to_range(converter, *info.symbol_range); + auto content = unit.interested_content(); + auto line_starts = lsp::build_line_starts(content); + result.range = to_range(content, line_starts, encoding, *info.symbol_range); } return result; diff --git a/src/feature/inlay_hints.cpp b/src/feature/inlay_hints.cpp index 2e21901b..bd3d1504 100644 --- a/src/feature/inlay_hints.cpp +++ b/src/feature/inlay_hints.cpp @@ -929,13 +929,14 @@ auto inlay_hints(CompilationUnitRef unit, PositionEncoding encoding) -> std::vector { auto collected = inlay_hints(unit, target, options); - PositionMapper converter(unit.interested_content(), encoding); + auto content = unit.interested_content(); + auto line_starts = lsp::build_line_starts(content); std::vector hints; hints.reserve(collected.size()); for(const auto& hint: collected) { protocol::InlayHint out{ - .position = *converter.to_position(hint.offset), + .position = *lsp::to_position(content, line_starts, encoding, hint.offset), .label = hint.label, }; diff --git a/src/feature/semantic_tokens.cpp b/src/feature/semantic_tokens.cpp index 9c4db1e0..a1d54efa 100644 --- a/src/feature/semantic_tokens.cpp +++ b/src/feature/semantic_tokens.cpp @@ -482,7 +482,8 @@ class SemanticTokenEncoder { SemanticTokenEncoder(llvm::StringRef content, PositionEncoding encoding, protocol::SemanticTokens& output) : - content(content), converter(content, encoding), output(output) {} + content(content), line_starts(lsp::build_line_starts(content)), encoding(encoding), + output(output) {} void append(const SemanticToken& token) { if(!token.range.valid() || token.range.end <= token.range.begin || @@ -492,8 +493,8 @@ class SemanticTokenEncoder { auto begin = token.range.begin; auto end = token.range.end; - auto begin_position = *converter.to_position(begin); - auto end_position = *converter.to_position(end); + auto begin_position = *lsp::to_position(content, line_starts, encoding, begin); + auto end_position = *lsp::to_position(content, line_starts, encoding, end); auto begin_line = static_cast(begin_position.line); auto begin_char = static_cast(begin_position.character); auto end_line = static_cast(end_position.line); @@ -524,7 +525,7 @@ class SemanticTokenEncoder { first_piece = false; } - auto length = converter.measure(chunk.substr(chunk_offset, piece_size)); + auto length = lsp::encoded_length(chunk.substr(chunk_offset, piece_size), encoding); emit_relative(delta_line, delta_start, length, token.kind, token.modifiers); chunk_offset += piece_size; @@ -532,7 +533,7 @@ class SemanticTokenEncoder { } if(piece_size > 0) { - auto length = converter.measure(chunk.substr(chunk_offset)); + auto length = lsp::encoded_length(chunk.substr(chunk_offset), encoding); emit_relative(1, 0, length, token.kind, token.modifiers); } } @@ -560,7 +561,8 @@ class SemanticTokenEncoder { private: llvm::StringRef content; - PositionMapper converter; + std::vector line_starts; + PositionEncoding encoding; protocol::SemanticTokens& output; std::uint32_t last_line = 0; std::uint32_t last_start_character = 0; diff --git a/src/server/compiler/compiler.cpp b/src/server/compiler/compiler.cpp index 5f75fb86..e1f0db99 100644 --- a/src/server/compiler/compiler.cpp +++ b/src/server/compiler/compiler.cpp @@ -726,12 +726,8 @@ kota::task<> Compiler::run_compile(std::shared_ptr session) { if(!result.value().tu_index_data.empty()) { auto tu_index = index::TUIndex::from(result.value().tu_index_data.data()); - OpenFileIndex ofi; - ofi.file_index = std::move(tu_index.main_file_index); - ofi.symbols = std::move(tu_index.symbols); - ofi.content = params.text; - ofi.mapper.emplace(ofi.content, lsp::PositionEncoding::UTF16); - session->file_index = std::move(ofi); + session->file_index = std::move(tu_index.main_file_index); + session->symbols = std::move(tu_index.symbols); } auto version = session->version; @@ -839,6 +835,7 @@ Compiler::RawResult Compiler::forward_query(worker::QueryKind kind, auto path = std::string(workspace.path_pool.resolve(path_id)); auto gen = session->generation; auto text = session->text; + auto line_starts = session->line_starts; if(!co_await ensure_compiled(session)) { co_return serde_raw{"null"}; @@ -852,18 +849,16 @@ Compiler::RawResult Compiler::forward_query(worker::QueryKind kind, wp.kind = kind; wp.path = path; - lsp::PositionMapper mapper(text, lsp::PositionEncoding::UTF16); - if(position) { - auto offset = mapper.to_offset(*position); + auto offset = lsp::to_offset(text, line_starts, lsp::PositionEncoding::UTF16, *position); if(!offset) co_return serde_raw{"null"}; wp.offset = *offset; } if(range) { - auto start = mapper.to_offset(range->start); - auto end = mapper.to_offset(range->end); + auto start = lsp::to_offset(text, line_starts, lsp::PositionEncoding::UTF16, range->start); + auto end = lsp::to_offset(text, line_starts, lsp::PositionEncoding::UTF16, range->end); if(start && end) { wp.range = {*start, *end}; } @@ -882,6 +877,7 @@ Compiler::RawResult Compiler::forward_build(worker::BuildKind kind, auto path_id = session->path_id; auto path = std::string(workspace.path_pool.resolve(path_id)); auto gen = session->generation; + auto line_starts = session->line_starts; worker::BuildParams wp; wp.kind = kind; @@ -900,8 +896,7 @@ Compiler::RawResult Compiler::forward_build(worker::BuildKind kind, co_return serde_raw{}; } - lsp::PositionMapper mapper(wp.text, lsp::PositionEncoding::UTF16); - auto offset = mapper.to_offset(position); + auto offset = lsp::to_offset(wp.text, line_starts, lsp::PositionEncoding::UTF16, position); if(!offset) co_return serde_raw{"null"}; wp.offset = *offset; @@ -924,9 +919,10 @@ Compiler::RawResult Compiler::forward_format(std::shared_ptr session, wp.text = session->text; if(range) { - lsp::PositionMapper mapper(wp.text, lsp::PositionEncoding::UTF16); - auto begin = mapper.to_offset(range->start); - auto end = mapper.to_offset(range->end); + auto line_starts = lsp::build_line_starts(wp.text); + auto begin = + lsp::to_offset(wp.text, line_starts, lsp::PositionEncoding::UTF16, range->start); + auto end = lsp::to_offset(wp.text, line_starts, lsp::PositionEncoding::UTF16, range->end); if(!begin || !end) co_return serde_raw{"null"}; wp.format_range = {*begin, *end}; @@ -944,8 +940,8 @@ Compiler::RawResult Compiler::handle_completion(const protocol::Position& positi auto path_id = session->path_id; auto path = std::string(workspace.path_pool.resolve(path_id)); - lsp::PositionMapper mapper(session->text, lsp::PositionEncoding::UTF16); - auto offset = mapper.to_offset(position); + auto offset = + lsp::to_offset(session->text, session->line_starts, lsp::PositionEncoding::UTF16, position); if(offset) { auto pctx = detect_completion_context(session->text, *offset); if(pctx.kind == CompletionContext::IncludeQuoted || diff --git a/src/server/compiler/indexer.cpp b/src/server/compiler/indexer.cpp index 7a5911ca..75388ba0 100644 --- a/src/server/compiler/indexer.cpp +++ b/src/server/compiler/indexer.cpp @@ -81,7 +81,7 @@ void Indexer::merge(const void* tu_index_data, std::size_t size) { } shard.index.merge(global_path_id, *include_id, file_idx, header_content); } - shard.invalidate_mapper(); + shard.invalidate(); }; for(auto& [tu_path_id, file_idx]: tu_index.path_file_indices) { @@ -188,9 +188,9 @@ bool Indexer::need_update(llvm::StringRef file_path) { bool Indexer::find_symbol_info(index::SymbolHash hash, std::string& name, SymbolKind& kind) const { bool found = false; - for_each_overlay([&](std::uint32_t, const OpenFileIndex& ofi) -> bool { - auto it = ofi.symbols.find(hash); - if(it != ofi.symbols.end()) { + for_each_overlay([&](std::uint32_t, const FileOverlay& overlay) -> bool { + auto it = overlay.symbols.find(hash); + if(it != overlay.symbols.end()) { name = it->second.name; kind = it->second.kind; found = true; @@ -214,23 +214,23 @@ Indexer::CursorHit Indexer::resolve_cursor(llvm::StringRef path, Session* session) { // Try the session's open file index first. if(session && session->file_index) { - auto& index = *session->file_index; - if(!index.mapper) - return {}; - auto offset = index.mapper->to_offset(position); + auto offset = lsp::to_offset(session->text, + session->line_starts, + lsp::PositionEncoding::UTF16, + position); if(!offset) return {}; - if(auto found = index.find_occurrence(*offset)) + if(auto found = + find_occurrence(*session->file_index, session->text, session->line_starts, *offset)) return {found->first, found->second}; return {}; } - // Fallback to MergedIndex, using session text (or reading from disk) for position -> offset. - const std::string* doc_text = session ? &session->text : nullptr; - if(!doc_text) + // Fallback to MergedIndex, using session text for position -> offset. + if(!session) return {}; - lsp::PositionMapper doc_mapper(*doc_text, lsp::PositionEncoding::UTF16); - auto offset = doc_mapper.to_offset(position); + auto offset = + lsp::to_offset(session->text, session->line_starts, lsp::PositionEncoding::UTF16, position); if(!offset) return {}; @@ -276,14 +276,19 @@ std::vector Indexer::query_relations(llvm::StringRef path, } } - for_each_overlay([&](std::uint32_t id, const OpenFileIndex& ofi) -> bool { + for_each_overlay([&](std::uint32_t id, const FileOverlay& overlay) -> bool { auto uri = lsp::URI::from_file_path(std::string(workspace.path_pool.resolve(id))); if(!uri) return true; - ofi.find_relations(hit.hash, kind, [&](const auto&, protocol::Range range) { - locations.push_back({uri->str(), range}); - return true; - }); + find_relations(overlay.file_index, + overlay.content, + overlay.line_starts, + hit.hash, + kind, + [&](const auto&, protocol::Range range) { + locations.push_back({uri->str(), range}); + return true; + }); return true; }); @@ -308,14 +313,19 @@ std::optional Indexer::lookup_symbol(const std::string& uri, std::optional Indexer::find_definition_location(index::SymbolHash hash) { std::optional overlay_result; - for_each_overlay([&](std::uint32_t id, const OpenFileIndex& ofi) -> bool { + for_each_overlay([&](std::uint32_t id, const FileOverlay& overlay) -> bool { auto uri = lsp::URI::from_file_path(std::string(workspace.path_pool.resolve(id))); if(!uri) return true; - ofi.find_relations(hash, RelationKind::Definition, [&](const auto&, protocol::Range range) { - overlay_result = protocol::Location{uri->str(), range}; - return false; - }); + find_relations(overlay.file_index, + overlay.content, + overlay.line_starts, + hash, + RelationKind::Definition, + [&](const auto&, protocol::Range range) { + overlay_result = protocol::Location{uri->str(), range}; + return false; + }); return !overlay_result.has_value(); }); if(overlay_result) @@ -386,11 +396,16 @@ void Indexer::collect_grouped_relations( }); } } - for_each_overlay([&](std::uint32_t, const OpenFileIndex& ofi) -> bool { - ofi.find_relations(hash, kind, [&](const auto& r, protocol::Range range) { - target_ranges[r.target_symbol].push_back(range); - return true; - }); + for_each_overlay([&](std::uint32_t, const FileOverlay& overlay) -> bool { + find_relations(overlay.file_index, + overlay.content, + overlay.line_starts, + hash, + kind, + [&](const auto& r, protocol::Range range) { + target_ranges[r.target_symbol].push_back(range); + return true; + }); return true; }); } @@ -416,9 +431,9 @@ void Indexer::collect_unique_targets(index::SymbolHash hash, }); } } - for_each_overlay([&](std::uint32_t, const OpenFileIndex& ofi) -> bool { - auto rel_it = ofi.file_index.relations.find(hash); - if(rel_it == ofi.file_index.relations.end()) + for_each_overlay([&](std::uint32_t, const FileOverlay& overlay) -> bool { + auto rel_it = overlay.file_index.relations.find(hash); + if(rel_it == overlay.file_index.relations.end()) return true; for(auto& r: rel_it->second) { if(r.kind & kind) { @@ -461,11 +476,9 @@ static std::string extract_line(llvm::StringRef content, std::uint32_t offset) { std::optional Indexer::get_definition_text(index::SymbolHash hash) { std::optional overlay_result; - for_each_overlay([&](std::uint32_t id, const OpenFileIndex& ofi) -> bool { - if(!ofi.mapper) - return true; - auto it = ofi.file_index.relations.find(hash); - if(it == ofi.file_index.relations.end()) + for_each_overlay([&](std::uint32_t id, const FileOverlay& overlay) -> bool { + auto it = overlay.file_index.relations.find(hash); + if(it == overlay.file_index.relations.end()) return true; for(auto& rel: it->second) { if(rel.kind.value() != RelationKind::Definition) @@ -473,19 +486,24 @@ std::optional Indexer::get_definition_text(index::Symbo auto def_range = std::bit_cast(rel.target_symbol); if(def_range.begin >= def_range.end) continue; - llvm::StringRef content = ofi.content; - if(def_range.end > content.size()) + if(def_range.end > overlay.content.size()) continue; - auto start = ofi.mapper->to_position(def_range.begin); - auto end = ofi.mapper->to_position(def_range.end); + auto start = lsp::to_position(overlay.content, + overlay.line_starts, + lsp::PositionEncoding::UTF16, + def_range.begin); + auto end = lsp::to_position(overlay.content, + overlay.line_starts, + lsp::PositionEncoding::UTF16, + def_range.end); if(!start || !end) continue; overlay_result = DefinitionText{ .file = std::string(workspace.path_pool.resolve(id)), .start_line = static_cast(start->line) + 1, .end_line = static_cast(end->line) + 1, - .text = - std::string(content.substr(def_range.begin, def_range.end - def_range.begin)), + .text = std::string( + overlay.content.substr(def_range.begin, def_range.end - def_range.begin)), }; return false; } @@ -504,8 +522,8 @@ std::optional Indexer::get_definition_text(index::Symbo auto shard_it = workspace.merged_indices.find(file_id); if(shard_it == workspace.merged_indices.end()) continue; - auto* m = shard_it->second.mapper(); - if(!m) + auto ls = shard_it->second.line_starts(); + if(ls.empty()) continue; auto content = shard_it->second.index.content(); @@ -517,8 +535,10 @@ std::optional Indexer::get_definition_text(index::Symbo auto def_range = std::bit_cast(r.target_symbol); if(def_range.begin >= def_range.end || def_range.end > content.size()) return true; - auto start = m->to_position(def_range.begin); - auto end = m->to_position(def_range.end); + auto start = + lsp::to_position(content, ls, lsp::PositionEncoding::UTF16, def_range.begin); + auto end = + lsp::to_position(content, ls, lsp::PositionEncoding::UTF16, def_range.end); if(!start || !end) return true; result = DefinitionText{ @@ -549,14 +569,15 @@ std::vector Indexer::collect_references(index::Sy auto shard_it = workspace.merged_indices.find(file_id); if(shard_it == workspace.merged_indices.end()) continue; - auto* m = shard_it->second.mapper(); - if(!m) + auto ls = shard_it->second.line_starts(); + if(ls.empty()) continue; auto content = shard_it->second.index.content(); auto file_path = workspace.project_index.path_pool.path(file_id); shard_it->second.index.lookup(hash, kind, [&](const index::Relation& r) { - auto start = m->to_position(r.range.begin); + auto start = + lsp::to_position(content, ls, lsp::PositionEncoding::UTF16, r.range.begin); if(!start) return true; results.push_back(ReferenceWithContext{ @@ -569,25 +590,25 @@ std::vector Indexer::collect_references(index::Sy } } - for_each_overlay([&](std::uint32_t id, const OpenFileIndex& ofi) -> bool { - if(!ofi.mapper) - return true; - auto it = ofi.file_index.relations.find(hash); - if(it == ofi.file_index.relations.end()) + for_each_overlay([&](std::uint32_t id, const FileOverlay& overlay) -> bool { + auto it = overlay.file_index.relations.find(hash); + if(it == overlay.file_index.relations.end()) return true; auto file_path = workspace.path_pool.resolve(id); - llvm::StringRef content = ofi.content; for(auto& rel: it->second) { if(rel.kind != kind) continue; - auto start = ofi.mapper->to_position(rel.range.begin); + auto start = lsp::to_position(overlay.content, + overlay.line_starts, + lsp::PositionEncoding::UTF16, + rel.range.begin); if(!start) continue; results.push_back(ReferenceWithContext{ .file = file_path.str(), .line = static_cast(start->line) + 1, - .context = extract_line(content, rel.range.begin), + .context = extract_line(overlay.content, rel.range.begin), }); } return true; @@ -697,10 +718,10 @@ std::vector Indexer::search_symbols(llvm::StringRef seen.insert(hash); } - for_each_overlay([&](std::uint32_t, const OpenFileIndex& ofi) -> bool { + for_each_overlay([&](std::uint32_t, const FileOverlay& overlay) -> bool { if(results.size() >= max_results) return false; - for(auto& [hash, symbol]: ofi.symbols) { + for(auto& [hash, symbol]: overlay.symbols) { if(results.size() >= max_results) return false; if(seen.contains(hash)) diff --git a/src/server/compiler/indexer.h b/src/server/compiler/indexer.h index d2994d1e..08b8ae7b 100644 --- a/src/server/compiler/indexer.h +++ b/src/server/compiler/indexer.h @@ -42,7 +42,7 @@ struct SymbolInfo { /// /// Indexer holds no index data of its own. All persistent data lives in /// Workspace (disk-derived ProjectIndex + MergedIndex shards) and per-file -/// data lives in Session (OpenFileIndex from unsaved buffers). +/// data lives in Session (FileOverlay views from unsaved buffers). /// /// Responsibilities: /// - Cross-file navigation queries (definition, references, hierarchy) @@ -57,7 +57,7 @@ class Indexer { public: /// Visitor for iterating open-file overlays. Returns false to stop early. using OverlayVisitor = - std::function; + std::function; Indexer(kota::event_loop& loop, Workspace& workspace, @@ -199,17 +199,17 @@ class Indexer { each_overlay(std::move(visitor)); } - /// Get the overlay for a specific server-level path_id (nullptr if not open). - const OpenFileIndex* get_overlay(std::uint32_t server_path_id) const { - const OpenFileIndex* result = nullptr; - for_each_overlay([&](std::uint32_t id, const OpenFileIndex& ofi) -> bool { + /// Invoke a callback with the overlay for a specific server-level path_id. + /// The callback is not invoked if no overlay exists for that path_id. + template + void with_overlay(std::uint32_t server_path_id, Fn&& fn) const { + for_each_overlay([&](std::uint32_t id, const FileOverlay& overlay) -> bool { if(id == server_path_id) { - result = &ofi; + fn(overlay); return false; } return true; }); - return result; } /// Whether background indexing is currently idle (no active or queued work). @@ -282,7 +282,7 @@ class Indexer { /// Checks if a server-level path_id has an open Session. std::function is_open; - /// Iterates all open-file overlays (OpenFileIndex from live compilations). + /// Iterates all open-file overlays (FileOverlay views from live compilations). std::function each_overlay; /// LSP peer for progress reporting (optional, not owned). diff --git a/src/server/service/agent_client.cpp b/src/server/service/agent_client.cpp index 0ddaf1fb..f85f03cd 100644 --- a/src/server/service/agent_client.cpp +++ b/src/server/service/agent_client.cpp @@ -101,8 +101,8 @@ static std::vector resolve_locator(const agentic::ReadSymbolPara for(auto& [hash, symbol]: workspace.project_index.symbols) try_symbol(hash, symbol); - indexer.for_each_overlay([&](std::uint32_t, const OpenFileIndex& ofi) -> bool { - for(auto& [hash, symbol]: ofi.symbols) + indexer.for_each_overlay([&](std::uint32_t, const FileOverlay& overlay) -> bool { + for(auto& [hash, symbol]: overlay.symbols) try_symbol(hash, symbol); return true; }); @@ -119,24 +119,31 @@ static std::vector resolve_locator(const agentic::ReadSymbolPara auto pool_it = workspace.path_pool.cache.find(path_str); auto server_id = pool_it != workspace.path_pool.cache.end() ? pool_it->second : ~0u; if(server_id != ~0u) { - auto* ofi = indexer.get_overlay(server_id); - if(ofi && ofi->mapper) { - for(auto& [hash, rels]: ofi->file_index.relations) { + std::vector overlay_result; + indexer.with_overlay(server_id, [&](const FileOverlay& overlay) { + for(auto& [hash, rels]: overlay.file_index.relations) { for(auto& rel: rels) { if(rel.kind.value() != RelationKind::Definition) continue; - auto start = ofi->mapper->to_position(rel.range.begin); + auto start = lsp::to_position(overlay.content, + overlay.line_starts, + lsp::PositionEncoding::UTF16, + rel.range.begin); if(start && start->line == target_line) { std::string name; SymbolKind kind; - if(indexer.find_symbol_info(hash, name, kind)) - return { - {hash, std::move(name), kind, path_str, *loc.line} - }; + if(!indexer.find_symbol_info(hash, name, kind)) + continue; + if(kind == SymbolKind::Parameter || kind == SymbolKind::Label) + continue; + overlay_result.push_back( + {hash, std::move(name), kind, path_str, *loc.line}); } } } - } + }); + if(!overlay_result.empty()) + return overlay_result; } auto it = workspace.project_index.path_pool.find(path_str); @@ -429,8 +436,8 @@ AgentClient::AgentClient(MasterServer& server, kota::ipc::JsonPeer& peer) : for(auto& [hash, symbol]: srv.workspace.project_index.symbols) try_symbol(hash, symbol); - srv.indexer.for_each_overlay([&](std::uint32_t, const OpenFileIndex& ofi) -> bool { - for(auto& [hash, symbol]: ofi.symbols) + srv.indexer.for_each_overlay([&](std::uint32_t, const FileOverlay& overlay) -> bool { + for(auto& [hash, symbol]: overlay.symbols) try_symbol(hash, symbol); return true; }); @@ -485,10 +492,10 @@ AgentClient::AgentClient(MasterServer& server, kota::ipc::JsonPeer& peer) : if(pool_it == srv.workspace.path_pool.cache.end()) co_return result; auto server_id = pool_it->second; - auto* ofi = srv.indexer.get_overlay(server_id); - if(ofi) { - auto& fi = *ofi; - for(auto& [hash, rels]: fi.file_index.relations) { + bool found_overlay = false; + srv.indexer.with_overlay(server_id, [&](const FileOverlay& overlay) { + found_overlay = true; + for(auto& [hash, rels]: overlay.file_index.relations) { for(auto& rel: rels) { if(rel.kind.value() != RelationKind::Definition) continue; @@ -498,24 +505,29 @@ AgentClient::AgentClient(MasterServer& server, kota::ipc::JsonPeer& peer) : continue; if(!is_document_level(kind)) continue; - if(fi.mapper) { - auto start = fi.mapper->to_position(rel.range.begin); - auto end = fi.mapper->to_position(rel.range.end); - if(start && end) { - result.symbols.push_back(DocumentSymbolEntry{ - .name = std::move(name), - .kind = std::string(symbol_kind_name(kind)), - .start_line = static_cast(start->line) + 1, - .end_line = static_cast(end->line) + 1, - .symbol_id = hash, - }); - break; - } + auto start = lsp::to_position(overlay.content, + overlay.line_starts, + lsp::PositionEncoding::UTF16, + rel.range.begin); + auto end = lsp::to_position(overlay.content, + overlay.line_starts, + lsp::PositionEncoding::UTF16, + rel.range.end); + if(start && end) { + result.symbols.push_back(DocumentSymbolEntry{ + .name = std::move(name), + .kind = std::string(symbol_kind_name(kind)), + .start_line = static_cast(start->line) + 1, + .end_line = static_cast(end->line) + 1, + .symbol_id = hash, + }); + break; } } } + }); + if(found_overlay) co_return result; - } auto it = srv.workspace.project_index.path_pool.find(params.path); if(it == srv.workspace.project_index.path_pool.cache.end()) diff --git a/src/server/service/lsp_client.cpp b/src/server/service/lsp_client.cpp index b5ca8b64..ce544c73 100644 --- a/src/server/service/lsp_client.cpp +++ b/src/server/service/lsp_client.cpp @@ -169,6 +169,7 @@ LSPClient::LSPClient(MasterServer& server, kota::ipc::JsonPeer& peer) : server(s auto session = srv.open_session(path_id); session->version = params.text_document.version; session->text = params.text_document.text; + session->line_starts = lsp::build_line_starts(session->text); session->generation++; LOG_DEBUG("didOpen: {} (v{})", path, params.text_document.version); @@ -197,13 +198,19 @@ LSPClient::LSPClient(MasterServer& server, kota::ipc::JsonPeer& peer) : server(s session->text = c.text; } else { auto& range = c.range; - lsp::PositionMapper mapper(session->text, lsp::PositionEncoding::UTF16); - auto start = mapper.to_offset(range.start); - auto end = mapper.to_offset(range.end); + auto start = lsp::to_offset(session->text, + session->line_starts, + lsp::PositionEncoding::UTF16, + range.start); + auto end = lsp::to_offset(session->text, + session->line_starts, + lsp::PositionEncoding::UTF16, + range.end); if(start && end && *start <= *end) { session->text.replace(*start, *end - *start, c.text); } } + session->line_starts = lsp::build_line_starts(session->text); }, change); } diff --git a/src/server/service/master_server.cpp b/src/server/service/master_server.cpp index 80c451d8..a3c40ffc 100644 --- a/src/server/service/master_server.cpp +++ b/src/server/service/master_server.cpp @@ -46,8 +46,12 @@ MasterServer::MasterServer(kota::event_loop& loop, std::string self_path) : [this](uint32_t server_path_id) { return sessions.contains(server_path_id); }, [this](Indexer::OverlayVisitor visitor) { for(auto& [path_id, session]: sessions) { - if(session && session->file_index) { - if(!visitor(path_id, *session->file_index)) + if(session && session->file_index && session->symbols) { + FileOverlay overlay{*session->file_index, + *session->symbols, + session->text, + session->line_starts}; + if(!visitor(path_id, overlay)) break; } } diff --git a/src/server/service/session.h b/src/server/service/session.h index eb95aab0..0a11aba1 100644 --- a/src/server/service/session.h +++ b/src/server/service/session.h @@ -4,7 +4,9 @@ #include #include #include +#include +#include "index/tu_index.h" #include "server/workspace/workspace.h" #include "kota/async/async.h" @@ -32,6 +34,10 @@ struct Session { /// Current buffer content (may differ from disk until saved). std::string text; + /// Byte offsets of each line start in `text`, built by `build_line_starts`. + /// Updated on didOpen and after every didChange. + std::vector line_starts; + /// Monotonic generation counter, incremented on every didChange and on close. /// Used to detect stale compilation results (ABA prevention). std::uint64_t generation = 0; @@ -89,7 +95,11 @@ struct Session { /// Used for queries (hover, goto, references) on this file. /// NOT merged into Workspace.project_index — that only gets disk-derived /// data from background indexing. - std::optional file_index; + std::optional file_index; + + /// Symbol table from the latest compilation, mapping symbol hashes to + /// names and kinds. + std::optional symbols; }; } // namespace clice diff --git a/src/server/workspace/workspace.cpp b/src/server/workspace/workspace.cpp index 5a964059..2f88309d 100644 --- a/src/server/workspace/workspace.cpp +++ b/src/server/workspace/workspace.cpp @@ -37,14 +37,16 @@ const static index::Occurrence* lookup_occurrence(const std::vector> - OpenFileIndex::find_occurrence(std::uint32_t offset) const { - if(!mapper) - return std::nullopt; + find_occurrence(const index::FileIndex& file_index, + std::string_view content, + std::span line_starts, + std::uint32_t offset) { auto* occ = lookup_occurrence(file_index.occurrences, offset); if(!occ) return std::nullopt; - auto start = mapper->to_position(occ->range.begin); - auto end = mapper->to_position(occ->range.end); + auto start = + lsp::to_position(content, line_starts, lsp::PositionEncoding::UTF16, occ->range.begin); + auto end = lsp::to_position(content, line_starts, lsp::PositionEncoding::UTF16, occ->range.end); if(!start || !end) return std::nullopt; return std::pair{ @@ -55,13 +57,14 @@ std::optional> std::optional> MergedIndexShard::find_occurrence(std::uint32_t offset) const { - auto* m = mapper(); - if(!m) + auto ls = line_starts(); + auto c = index.content(); + if(ls.empty()) return std::nullopt; std::optional> result; index.lookup(offset, [&](const index::Occurrence& o) { - auto start = m->to_position(o.range.begin); - auto end = m->to_position(o.range.end); + auto start = lsp::to_position(c, ls, lsp::PositionEncoding::UTF16, o.range.begin); + auto end = lsp::to_position(c, ls, lsp::PositionEncoding::UTF16, o.range.end); if(start && end) { result = { o.target, diff --git a/src/server/workspace/workspace.h b/src/server/workspace/workspace.h index 32bba802..cf7595b4 100644 --- a/src/server/workspace/workspace.h +++ b/src/server/workspace/workspace.h @@ -3,9 +3,12 @@ #include #include #include +#include #include +#include #include #include +#include #include "command/command.h" #include "command/toolchain.h" @@ -50,64 +53,67 @@ struct HeaderFileContext { std::uint64_t preamble_hash; ///< Hash of preamble content for staleness. }; -/// In-memory index for an open file. Kept separate from MergedIndex because -/// open files change frequently, are based on unsaved buffer content, and only -/// need to track the main file (headers are covered by PCH/PCM indexing). -struct OpenFileIndex { - index::FileIndex file_index; - index::SymbolTable symbols; - std::string content; ///< Buffer text at index time (for position mapping). - - /// Cached PositionMapper built from `content`. Avoids re-scanning line - /// offsets on every query. Initialized by Indexer::set_open_file(). - std::optional mapper; - - /// Find the tightest occurrence containing `offset`. - /// Returns (symbol_hash, LSP range) with positions already converted. - std::optional> - find_occurrence(std::uint32_t offset) const; +/// Non-owning view of an open file's index data for overlay queries. +/// Constructed by MasterServer from Session fields and passed to Indexer. +struct FileOverlay { + const index::FileIndex& file_index; + const index::SymbolTable& symbols; + std::string_view content; + std::span line_starts; +}; - /// Iterate relations matching `kind`, calling back with pre-converted ranges. - /// Callback: (const index::Relation&, protocol::Range) -> bool (true = continue). - template - void find_relations(index::SymbolHash hash, RelationKind kind, Fn&& fn) const { - if(!mapper) - return; - auto it = file_index.relations.find(hash); - if(it == file_index.relations.end()) - return; - for(auto& r: it->second) { - if(r.kind & kind) { - auto start = mapper->to_position(r.range.begin); - auto end = mapper->to_position(r.range.end); - if(start && end) { - if(!fn(r, protocol::Range{*start, *end})) - return; - } +/// Find the tightest occurrence at `offset` using `line_starts` for conversion. +std::optional> + find_occurrence(const index::FileIndex& file_index, + std::string_view content, + std::span line_starts, + std::uint32_t offset); + +/// Iterate relations matching `kind`, calling back with pre-converted ranges. +/// Callback: (const index::Relation&, protocol::Range) -> bool (true = continue). +template +void find_relations(const index::FileIndex& file_index, + std::string_view content, + std::span line_starts, + index::SymbolHash hash, + RelationKind kind, + Fn&& fn) { + auto it = file_index.relations.find(hash); + if(it == file_index.relations.end()) + return; + for(auto& r: it->second) { + if(r.kind & kind) { + auto start = + lsp::to_position(content, line_starts, lsp::PositionEncoding::UTF16, r.range.begin); + auto end = + lsp::to_position(content, line_starts, lsp::PositionEncoding::UTF16, r.range.end); + if(start && end) { + if(!fn(r, protocol::Range{*start, *end})) + return; } } } -}; +} -/// Wraps index::MergedIndex with a lazily-cached PositionMapper. +/// Wraps index::MergedIndex with lazily-cached line starts for position mapping. struct MergedIndexShard { index::MergedIndex index; - mutable std::optional cached_mapper; + mutable std::vector cached_line_starts; - /// Get or lazily build a PositionMapper from the index's stored content. - const lsp::PositionMapper* mapper() const { - if(!cached_mapper) { + /// Get or lazily build line starts from the index's stored content. + std::span line_starts() const { + if(cached_line_starts.empty()) { auto c = index.content(); if(!c.empty()) { - cached_mapper.emplace(c, lsp::PositionEncoding::UTF16); + cached_line_starts = lsp::build_line_starts(c); } } - return cached_mapper ? &*cached_mapper : nullptr; + return cached_line_starts; } - /// Invalidate the cached mapper (call after merge changes content). - void invalidate_mapper() { - cached_mapper.reset(); + /// Invalidate cached line starts (call after merge changes content). + void invalidate() { + cached_line_starts.clear(); } /// Find occurrence at byte offset. @@ -119,12 +125,13 @@ struct MergedIndexShard { /// Callback: (const index::Relation&, protocol::Range) -> bool (true = continue). template void find_relations(index::SymbolHash hash, RelationKind kind, Fn&& fn) const { - auto* m = mapper(); - if(!m) + auto ls = line_starts(); + auto c = index.content(); + if(ls.empty()) return; index.lookup(hash, kind, [&](const index::Relation& r) { - auto start = m->to_position(r.range.begin); - auto end = m->to_position(r.range.end); + auto start = lsp::to_position(c, ls, lsp::PositionEncoding::UTF16, r.range.begin); + auto end = lsp::to_position(c, ls, lsp::PositionEncoding::UTF16, r.range.end); if(start && end) { return fn(r, protocol::Range{*start, *end}); } diff --git a/tests/unit/feature/document_link_tests.cpp b/tests/unit/feature/document_link_tests.cpp index 9da70053..ea6f6bd8 100644 --- a/tests/unit/feature/document_link_tests.cpp +++ b/tests/unit/feature/document_link_tests.cpp @@ -22,8 +22,14 @@ void run(llvm::StringRef source, llvm::StringRef standard = "-std=c++17") { } auto to_local_range(const protocol::Range& range) -> LocalSourceRange { - feature::PositionMapper converter(unit->interested_content(), feature::PositionEncoding::UTF8); - return LocalSourceRange(*converter.to_offset(range.start), *converter.to_offset(range.end)); + auto content = unit->interested_content(); + auto line_starts = feature::lsp::build_line_starts(content); + return LocalSourceRange( + *feature::lsp::to_offset(content, + line_starts, + feature::PositionEncoding::UTF8, + range.start), + *feature::lsp::to_offset(content, line_starts, feature::PositionEncoding::UTF8, range.end)); } void EXPECT_LINK(std::size_t index, llvm::StringRef name, llvm::StringRef path) { diff --git a/tests/unit/feature/document_symbol_tests.cpp b/tests/unit/feature/document_symbol_tests.cpp index 603edc1f..31a43795 100644 --- a/tests/unit/feature/document_symbol_tests.cpp +++ b/tests/unit/feature/document_symbol_tests.cpp @@ -1,7 +1,10 @@ #include +#include #include #include #include +#include +#include #include #include "test/test.h" @@ -184,18 +187,22 @@ VAR(test) } void format_document_symbols(std::string& out, - const feature::PositionMapper& mapper, + std::string_view content, + std::span line_starts, + feature::PositionEncoding encoding, llvm::ArrayRef nodes, int depth) { auto pad = std::string(depth * 2, ' '); for(auto& node: nodes) { auto kind = kota::meta::enum_name(static_cast(node.kind), "Unknown"); - auto start = mapper.to_position(node.range.begin); - auto end = mapper.to_position(node.range.end); + auto start = feature::lsp::to_position(content, line_starts, encoding, node.range.begin); + auto end = feature::lsp::to_position(content, line_starts, encoding, node.range.end); if(!start || !end) continue; - auto sel_start = mapper.to_position(node.selection_range.begin); - auto sel_end = mapper.to_position(node.selection_range.end); + auto sel_start = + feature::lsp::to_position(content, line_starts, encoding, node.selection_range.begin); + auto sel_end = + feature::lsp::to_position(content, line_starts, encoding, node.selection_range.end); out += std::format("- {}{{ name: {}, kind: {}, range: \"{}:{}-{}:{}\"", pad, yaml_str(node.name), @@ -216,7 +223,7 @@ void format_document_symbols(std::string& out, } out += " }\n"; if(!node.children.empty()) { - format_document_symbols(out, mapper, node.children, depth + 1); + format_document_symbols(out, content, line_starts, encoding, node.children, depth + 1); } } } @@ -226,9 +233,14 @@ TEST_CASE(snapshot) { if(!compile_file(path)) return "COMPILE_ERROR"; auto content = unit->interested_content(); - feature::PositionMapper mapper(content, feature::PositionEncoding::UTF8); + auto line_starts = feature::lsp::build_line_starts(content); std::string result; - format_document_symbols(result, mapper, feature::document_symbols(*unit), 0); + format_document_symbols(result, + content, + line_starts, + feature::PositionEncoding::UTF8, + feature::document_symbols(*unit), + 0); return result; }); } diff --git a/tests/unit/feature/folding_range_tests.cpp b/tests/unit/feature/folding_range_tests.cpp index b7a75a55..cb91f801 100644 --- a/tests/unit/feature/folding_range_tests.cpp +++ b/tests/unit/feature/folding_range_tests.cpp @@ -37,7 +37,8 @@ void run(llvm::StringRef code) { } auto to_local_range(const protocol::FoldingRange& range) -> LocalSourceRange { - feature::PositionMapper converter(unit->interested_content(), feature::PositionEncoding::UTF8); + auto content = unit->interested_content(); + auto line_starts = feature::lsp::build_line_starts(content); auto start = protocol::Position{ .line = range.start_line, @@ -49,7 +50,9 @@ auto to_local_range(const protocol::FoldingRange& range) -> LocalSourceRange { .character = range.end_character.value_or(0), }; - return LocalSourceRange(*converter.to_offset(start), *converter.to_offset(end)); + return LocalSourceRange( + *feature::lsp::to_offset(content, line_starts, feature::PositionEncoding::UTF8, start), + *feature::lsp::to_offset(content, line_starts, feature::PositionEncoding::UTF8, end)); } void EXPECT_FOLDING(std::uint32_t index, @@ -434,11 +437,18 @@ TEST_CASE(snapshot) { if(!compile_file(path)) return "COMPILE_ERROR"; auto ranges = feature::folding_ranges(*unit); - feature::PositionMapper mapper(unit->interested_content(), feature::PositionEncoding::UTF8); + auto content = unit->interested_content(); + auto line_starts = feature::lsp::build_line_starts(content); std::string result; for(auto& r: ranges) { - auto start = mapper.to_position(r.range.begin); - auto end = mapper.to_position(r.range.end); + auto start = feature::lsp::to_position(content, + line_starts, + feature::PositionEncoding::UTF8, + r.range.begin); + auto end = feature::lsp::to_position(content, + line_starts, + feature::PositionEncoding::UTF8, + r.range.end); if(!start || !end) continue; result += std::format("- {{ range: \"{}:{}-{}:{}\"", diff --git a/tests/unit/feature/inlay_hint_tests.cpp b/tests/unit/feature/inlay_hint_tests.cpp index f6eb89df..aa1645f5 100644 --- a/tests/unit/feature/inlay_hint_tests.cpp +++ b/tests/unit/feature/inlay_hint_tests.cpp @@ -26,9 +26,13 @@ void run(llvm::StringRef code, std::source_location location = std::source_locat hints = feature::inlay_hints(*unit, range, {}, feature::PositionEncoding::UTF8); hints_map.clear(); - feature::PositionMapper converter(unit->interested_content(), feature::PositionEncoding::UTF8); + auto content = unit->interested_content(); + auto line_starts = feature::lsp::build_line_starts(content); for(auto& hint: hints) { - hints_map[*converter.to_offset(hint.position)] = hint; + hints_map[*feature::lsp::to_offset(content, + line_starts, + feature::PositionEncoding::UTF8, + hint.position)] = hint; } if(!unit->diagnostics().empty()) { @@ -1539,10 +1543,13 @@ TEST_CASE(snapshot) { auto content = unit->interested_content(); LocalSourceRange range(0, content.size()); auto hints = feature::inlay_hints(*unit, range); - feature::PositionMapper mapper(content, feature::PositionEncoding::UTF8); + auto line_starts = feature::lsp::build_line_starts(content); std::string result; for(auto& hint: hints) { - auto pos = mapper.to_position(hint.offset); + auto pos = feature::lsp::to_position(content, + line_starts, + feature::PositionEncoding::UTF8, + hint.offset); if(!pos) continue; auto kind = kota::meta::enum_name(hint.kind, "Unknown"); diff --git a/tests/unit/feature/semantic_tokens_tests.cpp b/tests/unit/feature/semantic_tokens_tests.cpp index e5e61399..0289ca68 100644 --- a/tests/unit/feature/semantic_tokens_tests.cpp +++ b/tests/unit/feature/semantic_tokens_tests.cpp @@ -589,14 +589,17 @@ TEST_CASE(snapshot) { return "COMPILE_ERROR"; auto content = unit->interested_content(); auto tokens = feature::semantic_tokens(*unit); - feature::PositionMapper mapper(content, feature::PositionEncoding::UTF8); + auto line_starts = feature::lsp::build_line_starts(content); std::string result; for(auto& token: tokens) { if(!token.range.valid() || token.range.end <= token.range.begin || token.range.end > content.size()) continue; - auto pos = mapper.to_position(token.range.begin); + auto pos = feature::lsp::to_position(content, + line_starts, + feature::PositionEncoding::UTF8, + token.range.begin); if(!pos) continue; diff --git a/tests/unit/index/tu_index_tests.cpp b/tests/unit/index/tu_index_tests.cpp index 01b624d4..babbf0c2 100644 --- a/tests/unit/index/tu_index_tests.cpp +++ b/tests/unit/index/tu_index_tests.cpp @@ -511,7 +511,7 @@ TEST_CASE(snapshot) { return "COMPILE_ERROR"; auto idx = index::TUIndex::build(*unit); auto content = unit->interested_content(); - feature::PositionMapper mapper(content, feature::PositionEncoding::UTF8); + auto line_starts = feature::lsp::build_line_starts(content); std::string result; auto sorted = idx.main_file_index.occurrences; @@ -522,7 +522,10 @@ TEST_CASE(snapshot) { for(auto& occ: sorted) { auto text = content.substr(occ.range.begin, occ.range.end - occ.range.begin); - auto pos = mapper.to_position(occ.range.begin); + auto pos = feature::lsp::to_position(content, + line_starts, + feature::PositionEncoding::UTF8, + occ.range.begin); if(!pos) continue; From b5ff1bc333a7773c0ec4c0de6cb47a7df53851ba Mon Sep 17 00:00:00 2001 From: ykiko Date: Fri, 19 Jun 2026 17:12:34 +0800 Subject: [PATCH 2/8] refactor: cache line_starts in CompilationUnit Lazily compute and cache line start offsets in CompilationUnitRef, avoiding repeated scans of interested_content() across feature calls. --- src/compile/compilation_unit.cpp | 13 +++++++++++++ src/compile/compilation_unit.h | 5 +++++ src/compile/implement.h | 3 +++ src/feature/diagnostics.cpp | 2 +- src/feature/document_links.cpp | 2 +- src/feature/document_symbols.cpp | 2 +- src/feature/folding_ranges.cpp | 2 +- src/feature/hover.cpp | 3 +-- src/feature/inlay_hints.cpp | 2 +- src/feature/semantic_tokens.cpp | 8 ++++---- tests/unit/feature/document_link_tests.cpp | 2 +- tests/unit/feature/document_symbol_tests.cpp | 2 +- tests/unit/feature/folding_range_tests.cpp | 4 ++-- tests/unit/feature/inlay_hint_tests.cpp | 4 ++-- tests/unit/feature/semantic_tokens_tests.cpp | 2 +- tests/unit/index/tu_index_tests.cpp | 2 +- 16 files changed, 39 insertions(+), 19 deletions(-) diff --git a/src/compile/compilation_unit.cpp b/src/compile/compilation_unit.cpp index 03d56576..fc3ba0a2 100644 --- a/src/compile/compilation_unit.cpp +++ b/src/compile/compilation_unit.cpp @@ -125,6 +125,19 @@ auto CompilationUnitRef::interested_content() -> llvm::StringRef { return file_content(interested_file()); } +auto CompilationUnitRef::line_starts() -> std::span { + if(self->line_starts_cache.empty()) { + auto content = interested_content(); + self->line_starts_cache.push_back(0); + for(std::uint32_t i = 0; i < content.size(); ++i) { + if(content[i] == '\n') { + self->line_starts_cache.push_back(i + 1); + } + } + } + return self->line_starts_cache; +} + bool CompilationUnitRef::is_builtin_file(clang::FileID fid) { // No FileEntryRef => built-in/command line/scratch. if(!self->SM().getFileEntryRefForID(fid)) { diff --git a/src/compile/compilation_unit.h b/src/compile/compilation_unit.h index 5a36722f..2f1828dc 100644 --- a/src/compile/compilation_unit.h +++ b/src/compile/compilation_unit.h @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -138,6 +139,10 @@ class CompilationUnitRef { /// Get the content of interested file. auto interested_content() -> llvm::StringRef; + /// Get the byte offsets of each line start in the interested file. + /// Lazily computed and cached. + auto line_starts() -> std::span; + /// Check if a file is a builtin file. bool is_builtin_file(clang::FileID fid); diff --git a/src/compile/implement.h b/src/compile/implement.h index 72b346a3..7f1a3d09 100644 --- a/src/compile/implement.h +++ b/src/compile/implement.h @@ -85,6 +85,9 @@ struct CompilationUnitRef::Self { /// Cache for symbol id. llvm::DenseMap symbol_hash_cache; + /// Cache for line starts of the interested file. + std::vector line_starts_cache; + llvm::BumpPtrAllocator path_storage; std::vector diagnostics; diff --git a/src/feature/diagnostics.cpp b/src/feature/diagnostics.cpp index 988e33ed..d7a68862 100644 --- a/src/feature/diagnostics.cpp +++ b/src/feature/diagnostics.cpp @@ -79,7 +79,7 @@ auto diagnostics(CompilationUnitRef unit, PositionEncoding encoding) }; auto main_content = unit.interested_content(); - auto main_line_starts = lsp::build_line_starts(main_content); + auto main_line_starts = unit.line_starts(); for(const auto& raw: unit.diagnostics()) { auto level = raw.id.level; diff --git a/src/feature/document_links.cpp b/src/feature/document_links.cpp index 1813bade..1dd84163 100644 --- a/src/feature/document_links.cpp +++ b/src/feature/document_links.cpp @@ -18,7 +18,7 @@ auto document_links(CompilationUnitRef unit, PositionEncoding encoding) } auto content = unit.interested_content(); - auto line_starts = lsp::build_line_starts(content); + auto line_starts = unit.line_starts(); auto& directives = directives_it->second; auto* lang_opts = &unit.lang_options(); diff --git a/src/feature/document_symbols.cpp b/src/feature/document_symbols.cpp index 7bc87ac9..727c6fb6 100644 --- a/src/feature/document_symbols.cpp +++ b/src/feature/document_symbols.cpp @@ -219,7 +219,7 @@ auto document_symbols(CompilationUnitRef unit, PositionEncoding encoding) auto internal = document_symbols(unit); auto content = unit.interested_content(); - auto line_starts = lsp::build_line_starts(content); + auto line_starts = unit.line_starts(); std::vector symbols; symbols.reserve(internal.size()); diff --git a/src/feature/folding_ranges.cpp b/src/feature/folding_ranges.cpp index 723b9283..aee2d708 100644 --- a/src/feature/folding_ranges.cpp +++ b/src/feature/folding_ranges.cpp @@ -350,7 +350,7 @@ auto folding_ranges(CompilationUnitRef unit, PositionEncoding encoding) -> std::vector { auto collected = folding_ranges(unit); auto content = unit.interested_content(); - auto line_starts = lsp::build_line_starts(content); + auto line_starts = unit.line_starts(); std::vector result; result.reserve(collected.size()); diff --git a/src/feature/hover.cpp b/src/feature/hover.cpp index 5d8beaee..282414a5 100644 --- a/src/feature/hover.cpp +++ b/src/feature/hover.cpp @@ -1311,8 +1311,7 @@ auto to_protocol_hover(CompilationUnitRef unit, if(info.symbol_range) { auto content = unit.interested_content(); - auto line_starts = lsp::build_line_starts(content); - result.range = to_range(content, line_starts, encoding, *info.symbol_range); + result.range = to_range(content, unit.line_starts(), encoding, *info.symbol_range); } return result; diff --git a/src/feature/inlay_hints.cpp b/src/feature/inlay_hints.cpp index bd3d1504..026bd9ac 100644 --- a/src/feature/inlay_hints.cpp +++ b/src/feature/inlay_hints.cpp @@ -930,7 +930,7 @@ auto inlay_hints(CompilationUnitRef unit, auto collected = inlay_hints(unit, target, options); auto content = unit.interested_content(); - auto line_starts = lsp::build_line_starts(content); + auto line_starts = unit.line_starts(); std::vector hints; hints.reserve(collected.size()); diff --git a/src/feature/semantic_tokens.cpp b/src/feature/semantic_tokens.cpp index a1d54efa..37cb635f 100644 --- a/src/feature/semantic_tokens.cpp +++ b/src/feature/semantic_tokens.cpp @@ -480,10 +480,10 @@ class SemanticTokensCollector : public SemanticVisitor class SemanticTokenEncoder { public: SemanticTokenEncoder(llvm::StringRef content, + std::span line_starts, PositionEncoding encoding, protocol::SemanticTokens& output) : - content(content), line_starts(lsp::build_line_starts(content)), encoding(encoding), - output(output) {} + content(content), line_starts(line_starts), encoding(encoding), output(output) {} void append(const SemanticToken& token) { if(!token.range.valid() || token.range.end <= token.range.begin || @@ -561,7 +561,7 @@ class SemanticTokenEncoder { private: llvm::StringRef content; - std::vector line_starts; + std::span line_starts; PositionEncoding encoding; protocol::SemanticTokens& output; std::uint32_t last_line = 0; @@ -582,7 +582,7 @@ auto semantic_tokens(CompilationUnitRef unit, PositionEncoding encoding) protocol::SemanticTokens result; result.data.reserve(tokens.size() * 5); - SemanticTokenEncoder encoder(unit.interested_content(), encoding, result); + SemanticTokenEncoder encoder(unit.interested_content(), unit.line_starts(), encoding, result); for(const auto& token: tokens) { encoder.append(token); } diff --git a/tests/unit/feature/document_link_tests.cpp b/tests/unit/feature/document_link_tests.cpp index ea6f6bd8..5f965069 100644 --- a/tests/unit/feature/document_link_tests.cpp +++ b/tests/unit/feature/document_link_tests.cpp @@ -23,7 +23,7 @@ void run(llvm::StringRef source, llvm::StringRef standard = "-std=c++17") { auto to_local_range(const protocol::Range& range) -> LocalSourceRange { auto content = unit->interested_content(); - auto line_starts = feature::lsp::build_line_starts(content); + auto line_starts = unit->line_starts(); return LocalSourceRange( *feature::lsp::to_offset(content, line_starts, diff --git a/tests/unit/feature/document_symbol_tests.cpp b/tests/unit/feature/document_symbol_tests.cpp index 31a43795..8e68a76d 100644 --- a/tests/unit/feature/document_symbol_tests.cpp +++ b/tests/unit/feature/document_symbol_tests.cpp @@ -233,7 +233,7 @@ TEST_CASE(snapshot) { if(!compile_file(path)) return "COMPILE_ERROR"; auto content = unit->interested_content(); - auto line_starts = feature::lsp::build_line_starts(content); + auto line_starts = unit->line_starts(); std::string result; format_document_symbols(result, content, diff --git a/tests/unit/feature/folding_range_tests.cpp b/tests/unit/feature/folding_range_tests.cpp index cb91f801..fb30a265 100644 --- a/tests/unit/feature/folding_range_tests.cpp +++ b/tests/unit/feature/folding_range_tests.cpp @@ -38,7 +38,7 @@ void run(llvm::StringRef code) { auto to_local_range(const protocol::FoldingRange& range) -> LocalSourceRange { auto content = unit->interested_content(); - auto line_starts = feature::lsp::build_line_starts(content); + auto line_starts = unit->line_starts(); auto start = protocol::Position{ .line = range.start_line, @@ -438,7 +438,7 @@ TEST_CASE(snapshot) { return "COMPILE_ERROR"; auto ranges = feature::folding_ranges(*unit); auto content = unit->interested_content(); - auto line_starts = feature::lsp::build_line_starts(content); + auto line_starts = unit->line_starts(); std::string result; for(auto& r: ranges) { auto start = feature::lsp::to_position(content, diff --git a/tests/unit/feature/inlay_hint_tests.cpp b/tests/unit/feature/inlay_hint_tests.cpp index aa1645f5..bd7fb460 100644 --- a/tests/unit/feature/inlay_hint_tests.cpp +++ b/tests/unit/feature/inlay_hint_tests.cpp @@ -27,7 +27,7 @@ void run(llvm::StringRef code, std::source_location location = std::source_locat hints_map.clear(); auto content = unit->interested_content(); - auto line_starts = feature::lsp::build_line_starts(content); + auto line_starts = unit->line_starts(); for(auto& hint: hints) { hints_map[*feature::lsp::to_offset(content, line_starts, @@ -1543,7 +1543,7 @@ TEST_CASE(snapshot) { auto content = unit->interested_content(); LocalSourceRange range(0, content.size()); auto hints = feature::inlay_hints(*unit, range); - auto line_starts = feature::lsp::build_line_starts(content); + auto line_starts = unit->line_starts(); std::string result; for(auto& hint: hints) { auto pos = feature::lsp::to_position(content, diff --git a/tests/unit/feature/semantic_tokens_tests.cpp b/tests/unit/feature/semantic_tokens_tests.cpp index 0289ca68..cb930a48 100644 --- a/tests/unit/feature/semantic_tokens_tests.cpp +++ b/tests/unit/feature/semantic_tokens_tests.cpp @@ -589,7 +589,7 @@ TEST_CASE(snapshot) { return "COMPILE_ERROR"; auto content = unit->interested_content(); auto tokens = feature::semantic_tokens(*unit); - auto line_starts = feature::lsp::build_line_starts(content); + auto line_starts = unit->line_starts(); std::string result; for(auto& token: tokens) { if(!token.range.valid() || token.range.end <= token.range.begin || diff --git a/tests/unit/index/tu_index_tests.cpp b/tests/unit/index/tu_index_tests.cpp index babbf0c2..f0c98170 100644 --- a/tests/unit/index/tu_index_tests.cpp +++ b/tests/unit/index/tu_index_tests.cpp @@ -511,7 +511,7 @@ TEST_CASE(snapshot) { return "COMPILE_ERROR"; auto idx = index::TUIndex::build(*unit); auto content = unit->interested_content(); - auto line_starts = feature::lsp::build_line_starts(content); + auto line_starts = unit->line_starts(); std::string result; auto sorted = idx.main_file_index.occurrences; From d583e966a5d517dd645bfeba51882e1123a92e08 Mon Sep 17 00:00:00 2001 From: ykiko Date: Fri, 19 Jun 2026 17:24:47 +0800 Subject: [PATCH 3/8] refactor: use to_range helper and inline single-use variables --- src/feature/code_completion.cpp | 5 +---- src/feature/diagnostics.cpp | 8 +++----- src/feature/document_links.cpp | 4 ++-- src/feature/folding_ranges.cpp | 3 +-- src/feature/formatting.cpp | 14 ++++++-------- src/feature/hover.cpp | 4 ++-- 6 files changed, 15 insertions(+), 23 deletions(-) diff --git a/src/feature/code_completion.cpp b/src/feature/code_completion.cpp index 21accd96..b21facbc 100644 --- a/src/feature/code_completion.cpp +++ b/src/feature/code_completion.cpp @@ -256,10 +256,7 @@ class CodeCompletionCollector final : public clang::CodeCompleteConsumer { FuzzyMatcher matcher(prefix.spelling); auto line_starts = lsp::build_line_starts(content); - auto replace_range = protocol::Range{ - .start = *lsp::to_position(content, line_starts, encoding, prefix.range.begin), - .end = *lsp::to_position(content, line_starts, encoding, prefix.range.end), - }; + auto replace_range = to_range(content, line_starts, encoding, prefix.range); std::vector collected; collected.reserve(candidate_count); diff --git a/src/feature/diagnostics.cpp b/src/feature/diagnostics.cpp index d7a68862..c21d6e8b 100644 --- a/src/feature/diagnostics.cpp +++ b/src/feature/diagnostics.cpp @@ -151,11 +151,9 @@ auto diagnostics(CompilationUnitRef unit, PositionEncoding encoding) } auto offset = unit.file_offset(include_location); - auto end_offset = offset + unit.token_spelling(include_location).size(); - diagnostic.range = protocol::Range{ - .start = *lsp::to_position(main_content, main_line_starts, encoding, offset), - .end = *lsp::to_position(main_content, main_line_starts, encoding, end_offset), - }; + auto end_offset = + static_cast(offset + unit.token_spelling(include_location).size()); + diagnostic.range = to_range(main_content, main_line_starts, encoding, {offset, end_offset}); current = std::move(diagnostic); } diff --git a/src/feature/document_links.cpp b/src/feature/document_links.cpp index 1dd84163..91b686af 100644 --- a/src/feature/document_links.cpp +++ b/src/feature/document_links.cpp @@ -18,7 +18,6 @@ auto document_links(CompilationUnitRef unit, PositionEncoding encoding) } auto content = unit.interested_content(); - auto line_starts = unit.line_starts(); auto& directives = directives_it->second; auto* lang_opts = &unit.lang_options(); @@ -29,7 +28,8 @@ auto document_links(CompilationUnitRef unit, PositionEncoding encoding) auto range = find_directive_argument(content, offset, lang_opts); if(!range) return; - protocol::DocumentLink link{.range = to_range(content, line_starts, encoding, *range)}; + protocol::DocumentLink link{.range = + to_range(content, unit.line_starts(), encoding, *range)}; link.target = target.str(); links.push_back(std::move(link)); }; diff --git a/src/feature/folding_ranges.cpp b/src/feature/folding_ranges.cpp index aee2d708..5a0e57a5 100644 --- a/src/feature/folding_ranges.cpp +++ b/src/feature/folding_ranges.cpp @@ -356,8 +356,7 @@ auto folding_ranges(CompilationUnitRef unit, PositionEncoding encoding) result.reserve(collected.size()); for(const auto& item: collected) { - auto start = *lsp::to_position(content, line_starts, encoding, item.range.begin); - auto end = *lsp::to_position(content, line_starts, encoding, item.range.end); + auto [start, end] = to_range(content, line_starts, encoding, item.range); protocol::FoldingRange range{ .start_line = start.line, diff --git a/src/feature/formatting.cpp b/src/feature/formatting.cpp index ad640b12..dffa30f4 100644 --- a/src/feature/formatting.cpp +++ b/src/feature/formatting.cpp @@ -56,14 +56,12 @@ auto document_format(llvm::StringRef file, auto line_starts = lsp::build_line_starts(content); for(const auto& replacement: *replacements) { - protocol::TextEdit edit; - edit.range.start = - *lsp::to_position(content, line_starts, encoding, replacement.getOffset()); - edit.range.end = *lsp::to_position(content, - line_starts, - encoding, - replacement.getOffset() + replacement.getLength()); - edit.new_text = replacement.getReplacementText().str(); + auto begin = replacement.getOffset(); + auto end = begin + replacement.getLength(); + protocol::TextEdit edit{ + .range = to_range(content, line_starts, encoding, {begin, end}), + .new_text = replacement.getReplacementText().str(), + }; edits.push_back(std::move(edit)); } diff --git a/src/feature/hover.cpp b/src/feature/hover.cpp index 282414a5..30f50c75 100644 --- a/src/feature/hover.cpp +++ b/src/feature/hover.cpp @@ -1310,8 +1310,8 @@ auto to_protocol_hover(CompilationUnitRef unit, }; if(info.symbol_range) { - auto content = unit.interested_content(); - result.range = to_range(content, unit.line_starts(), encoding, *info.symbol_range); + result.range = + to_range(unit.interested_content(), unit.line_starts(), encoding, *info.symbol_range); } return result; From cc82e7ac9e0f171d30a9698a85cad99262a0235e Mon Sep 17 00:00:00 2001 From: ykiko Date: Fri, 19 Jun 2026 19:22:42 +0800 Subject: [PATCH 4/8] refactor: remove FileOverlay and add CompilationUnitRef position helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Remove the intermediate FileOverlay view type — Indexer now receives const Session& directly. Add to_range/to_position overloads taking CompilationUnitRef to simplify feature-layer call sites. --- src/feature/diagnostics.cpp | 7 +-- src/feature/document_links.cpp | 3 +- src/feature/document_symbols.cpp | 15 ++--- src/feature/feature.h | 12 ++++ src/feature/folding_ranges.cpp | 4 +- src/feature/hover.cpp | 3 +- src/feature/inlay_hints.cpp | 4 +- src/feature/semantic_tokens.cpp | 8 +-- src/server/compiler/indexer.cpp | 88 ++++++++++++++-------------- src/server/compiler/indexer.h | 22 +++---- src/server/service/agent_client.cpp | 42 ++++++------- src/server/service/master_server.cpp | 6 +- src/server/workspace/workspace.h | 9 --- 13 files changed, 105 insertions(+), 118 deletions(-) diff --git a/src/feature/diagnostics.cpp b/src/feature/diagnostics.cpp index c21d6e8b..4b3de5de 100644 --- a/src/feature/diagnostics.cpp +++ b/src/feature/diagnostics.cpp @@ -78,9 +78,6 @@ auto diagnostics(CompilationUnitRef unit, PositionEncoding encoding) } }; - auto main_content = unit.interested_content(); - auto main_line_starts = unit.line_starts(); - for(const auto& raw: unit.diagnostics()) { auto level = raw.id.level; @@ -135,7 +132,7 @@ auto diagnostics(CompilationUnitRef unit, PositionEncoding encoding) } if(raw.fid == unit.interested_file()) { - diagnostic.range = to_range(main_content, main_line_starts, encoding, raw.range); + diagnostic.range = to_range(unit, encoding, raw.range); current = std::move(diagnostic); continue; } @@ -153,7 +150,7 @@ auto diagnostics(CompilationUnitRef unit, PositionEncoding encoding) auto offset = unit.file_offset(include_location); auto end_offset = static_cast(offset + unit.token_spelling(include_location).size()); - diagnostic.range = to_range(main_content, main_line_starts, encoding, {offset, end_offset}); + diagnostic.range = to_range(unit, encoding, {offset, end_offset}); current = std::move(diagnostic); } diff --git a/src/feature/document_links.cpp b/src/feature/document_links.cpp index 91b686af..1d17f4e2 100644 --- a/src/feature/document_links.cpp +++ b/src/feature/document_links.cpp @@ -28,8 +28,7 @@ auto document_links(CompilationUnitRef unit, PositionEncoding encoding) auto range = find_directive_argument(content, offset, lang_opts); if(!range) return; - protocol::DocumentLink link{.range = - to_range(content, unit.line_starts(), encoding, *range)}; + protocol::DocumentLink link{.range = to_range(unit, encoding, *range)}; link.target = target.str(); links.push_back(std::move(link)); }; diff --git a/src/feature/document_symbols.cpp b/src/feature/document_symbols.cpp index 727c6fb6..a9b96c8d 100644 --- a/src/feature/document_symbols.cpp +++ b/src/feature/document_symbols.cpp @@ -179,14 +179,13 @@ void sort_symbols(std::vector& symbols) { } auto to_protocol_symbol(const DocumentSymbol& symbol, - std::string_view content, - std::span line_starts, - lsp::PositionEncoding encoding) -> protocol::DocumentSymbol { + CompilationUnitRef unit, + PositionEncoding encoding) -> protocol::DocumentSymbol { protocol::DocumentSymbol result{ .name = symbol.name, .kind = to_protocol_symbol_kind(symbol.kind), - .range = to_range(content, line_starts, encoding, symbol.range), - .selection_range = to_range(content, line_starts, encoding, symbol.selection_range), + .range = to_range(unit, encoding, symbol.range), + .selection_range = to_range(unit, encoding, symbol.selection_range), }; if(!symbol.detail.empty()) { @@ -198,7 +197,7 @@ auto to_protocol_symbol(const DocumentSymbol& symbol, children.reserve(symbol.children.size()); for(const auto& child: symbol.children) { children.push_back(std::make_shared( - to_protocol_symbol(child, content, line_starts, encoding))); + to_protocol_symbol(child, unit, encoding))); } result.children = std::move(children); } @@ -218,13 +217,11 @@ auto document_symbols(CompilationUnitRef unit, PositionEncoding encoding) -> std::vector { auto internal = document_symbols(unit); - auto content = unit.interested_content(); - auto line_starts = unit.line_starts(); std::vector symbols; symbols.reserve(internal.size()); for(const auto& symbol: internal) { - symbols.push_back(to_protocol_symbol(symbol, content, line_starts, encoding)); + symbols.push_back(to_protocol_symbol(symbol, unit, encoding)); } return symbols; diff --git a/src/feature/feature.h b/src/feature/feature.h index a9f2c65a..113c1652 100644 --- a/src/feature/feature.h +++ b/src/feature/feature.h @@ -33,6 +33,18 @@ inline auto to_range(std::string_view content, }; } +inline auto to_position(CompilationUnitRef unit, + lsp::PositionEncoding encoding, + std::uint32_t offset) -> std::optional { + return lsp::to_position(unit.interested_content(), unit.line_starts(), encoding, offset); +} + +inline auto to_range(CompilationUnitRef unit, + lsp::PositionEncoding encoding, + LocalSourceRange range) -> protocol::Range { + return to_range(unit.interested_content(), unit.line_starts(), encoding, range); +} + struct CodeCompletionOptions { bool enable_keyword_snippet = false; bool enable_function_arguments_snippet = false; diff --git a/src/feature/folding_ranges.cpp b/src/feature/folding_ranges.cpp index 5a0e57a5..3835b530 100644 --- a/src/feature/folding_ranges.cpp +++ b/src/feature/folding_ranges.cpp @@ -349,14 +349,12 @@ auto folding_ranges(CompilationUnitRef unit) -> std::vector { auto folding_ranges(CompilationUnitRef unit, PositionEncoding encoding) -> std::vector { auto collected = folding_ranges(unit); - auto content = unit.interested_content(); - auto line_starts = unit.line_starts(); std::vector result; result.reserve(collected.size()); for(const auto& item: collected) { - auto [start, end] = to_range(content, line_starts, encoding, item.range); + auto [start, end] = to_range(unit, encoding, item.range); protocol::FoldingRange range{ .start_line = start.line, diff --git a/src/feature/hover.cpp b/src/feature/hover.cpp index 30f50c75..2649df96 100644 --- a/src/feature/hover.cpp +++ b/src/feature/hover.cpp @@ -1310,8 +1310,7 @@ auto to_protocol_hover(CompilationUnitRef unit, }; if(info.symbol_range) { - result.range = - to_range(unit.interested_content(), unit.line_starts(), encoding, *info.symbol_range); + result.range = to_range(unit, encoding, *info.symbol_range); } return result; diff --git a/src/feature/inlay_hints.cpp b/src/feature/inlay_hints.cpp index 026bd9ac..fc68a38c 100644 --- a/src/feature/inlay_hints.cpp +++ b/src/feature/inlay_hints.cpp @@ -929,14 +929,12 @@ auto inlay_hints(CompilationUnitRef unit, PositionEncoding encoding) -> std::vector { auto collected = inlay_hints(unit, target, options); - auto content = unit.interested_content(); - auto line_starts = unit.line_starts(); std::vector hints; hints.reserve(collected.size()); for(const auto& hint: collected) { protocol::InlayHint out{ - .position = *lsp::to_position(content, line_starts, encoding, hint.offset), + .position = *to_position(unit, encoding, hint.offset), .label = hint.label, }; diff --git a/src/feature/semantic_tokens.cpp b/src/feature/semantic_tokens.cpp index 37cb635f..b3de1ad4 100644 --- a/src/feature/semantic_tokens.cpp +++ b/src/feature/semantic_tokens.cpp @@ -479,11 +479,11 @@ class SemanticTokensCollector : public SemanticVisitor class SemanticTokenEncoder { public: - SemanticTokenEncoder(llvm::StringRef content, - std::span line_starts, + SemanticTokenEncoder(CompilationUnitRef unit, PositionEncoding encoding, protocol::SemanticTokens& output) : - content(content), line_starts(line_starts), encoding(encoding), output(output) {} + content(unit.interested_content()), line_starts(unit.line_starts()), encoding(encoding), + output(output) {} void append(const SemanticToken& token) { if(!token.range.valid() || token.range.end <= token.range.begin || @@ -582,7 +582,7 @@ auto semantic_tokens(CompilationUnitRef unit, PositionEncoding encoding) protocol::SemanticTokens result; result.data.reserve(tokens.size() * 5); - SemanticTokenEncoder encoder(unit.interested_content(), unit.line_starts(), encoding, result); + SemanticTokenEncoder encoder(unit, encoding, result); for(const auto& token: tokens) { encoder.append(token); } diff --git a/src/server/compiler/indexer.cpp b/src/server/compiler/indexer.cpp index 75388ba0..3c0240c1 100644 --- a/src/server/compiler/indexer.cpp +++ b/src/server/compiler/indexer.cpp @@ -188,9 +188,9 @@ bool Indexer::need_update(llvm::StringRef file_path) { bool Indexer::find_symbol_info(index::SymbolHash hash, std::string& name, SymbolKind& kind) const { bool found = false; - for_each_overlay([&](std::uint32_t, const FileOverlay& overlay) -> bool { - auto it = overlay.symbols.find(hash); - if(it != overlay.symbols.end()) { + for_each_session([&](std::uint32_t, const Session& session) -> bool { + auto it = session.symbols->find(hash); + if(it != session.symbols->end()) { name = it->second.name; kind = it->second.kind; found = true; @@ -276,13 +276,13 @@ std::vector Indexer::query_relations(llvm::StringRef path, } } - for_each_overlay([&](std::uint32_t id, const FileOverlay& overlay) -> bool { + for_each_session([&](std::uint32_t id, const Session& session) -> bool { auto uri = lsp::URI::from_file_path(std::string(workspace.path_pool.resolve(id))); if(!uri) return true; - find_relations(overlay.file_index, - overlay.content, - overlay.line_starts, + find_relations(*session.file_index, + session.text, + session.line_starts, hit.hash, kind, [&](const auto&, protocol::Range range) { @@ -312,24 +312,24 @@ std::optional Indexer::lookup_symbol(const std::string& uri, } std::optional Indexer::find_definition_location(index::SymbolHash hash) { - std::optional overlay_result; - for_each_overlay([&](std::uint32_t id, const FileOverlay& overlay) -> bool { + std::optional session_result; + for_each_session([&](std::uint32_t id, const Session& session) -> bool { auto uri = lsp::URI::from_file_path(std::string(workspace.path_pool.resolve(id))); if(!uri) return true; - find_relations(overlay.file_index, - overlay.content, - overlay.line_starts, + find_relations(*session.file_index, + session.text, + session.line_starts, hash, RelationKind::Definition, [&](const auto&, protocol::Range range) { - overlay_result = protocol::Location{uri->str(), range}; + session_result = protocol::Location{uri->str(), range}; return false; }); - return !overlay_result.has_value(); + return !session_result.has_value(); }); - if(overlay_result) - return overlay_result; + if(session_result) + return session_result; // Fall back to ProjectIndex reference files. auto sym_it = workspace.project_index.symbols.find(hash); @@ -396,10 +396,10 @@ void Indexer::collect_grouped_relations( }); } } - for_each_overlay([&](std::uint32_t, const FileOverlay& overlay) -> bool { - find_relations(overlay.file_index, - overlay.content, - overlay.line_starts, + for_each_session([&](std::uint32_t, const Session& session) -> bool { + find_relations(*session.file_index, + session.text, + session.line_starts, hash, kind, [&](const auto& r, protocol::Range range) { @@ -431,9 +431,9 @@ void Indexer::collect_unique_targets(index::SymbolHash hash, }); } } - for_each_overlay([&](std::uint32_t, const FileOverlay& overlay) -> bool { - auto rel_it = overlay.file_index.relations.find(hash); - if(rel_it == overlay.file_index.relations.end()) + for_each_session([&](std::uint32_t, const Session& session) -> bool { + auto rel_it = session.file_index->relations.find(hash); + if(rel_it == session.file_index->relations.end()) return true; for(auto& r: rel_it->second) { if(r.kind & kind) { @@ -475,10 +475,10 @@ static std::string extract_line(llvm::StringRef content, std::uint32_t offset) { } std::optional Indexer::get_definition_text(index::SymbolHash hash) { - std::optional overlay_result; - for_each_overlay([&](std::uint32_t id, const FileOverlay& overlay) -> bool { - auto it = overlay.file_index.relations.find(hash); - if(it == overlay.file_index.relations.end()) + std::optional session_result; + for_each_session([&](std::uint32_t id, const Session& session) -> bool { + auto it = session.file_index->relations.find(hash); + if(it == session.file_index->relations.end()) return true; for(auto& rel: it->second) { if(rel.kind.value() != RelationKind::Definition) @@ -486,31 +486,31 @@ std::optional Indexer::get_definition_text(index::Symbo auto def_range = std::bit_cast(rel.target_symbol); if(def_range.begin >= def_range.end) continue; - if(def_range.end > overlay.content.size()) + if(def_range.end > session.text.size()) continue; - auto start = lsp::to_position(overlay.content, - overlay.line_starts, + auto start = lsp::to_position(session.text, + session.line_starts, lsp::PositionEncoding::UTF16, def_range.begin); - auto end = lsp::to_position(overlay.content, - overlay.line_starts, + auto end = lsp::to_position(session.text, + session.line_starts, lsp::PositionEncoding::UTF16, def_range.end); if(!start || !end) continue; - overlay_result = DefinitionText{ + session_result = DefinitionText{ .file = std::string(workspace.path_pool.resolve(id)), .start_line = static_cast(start->line) + 1, .end_line = static_cast(end->line) + 1, .text = std::string( - overlay.content.substr(def_range.begin, def_range.end - def_range.begin)), + session.text.substr(def_range.begin, def_range.end - def_range.begin)), }; return false; } return true; }); - if(overlay_result) - return overlay_result; + if(session_result) + return session_result; auto sym_it = workspace.project_index.symbols.find(hash); if(sym_it == workspace.project_index.symbols.end()) @@ -590,17 +590,17 @@ std::vector Indexer::collect_references(index::Sy } } - for_each_overlay([&](std::uint32_t id, const FileOverlay& overlay) -> bool { - auto it = overlay.file_index.relations.find(hash); - if(it == overlay.file_index.relations.end()) + for_each_session([&](std::uint32_t id, const Session& session) -> bool { + auto it = session.file_index->relations.find(hash); + if(it == session.file_index->relations.end()) return true; auto file_path = workspace.path_pool.resolve(id); for(auto& rel: it->second) { if(rel.kind != kind) continue; - auto start = lsp::to_position(overlay.content, - overlay.line_starts, + auto start = lsp::to_position(session.text, + session.line_starts, lsp::PositionEncoding::UTF16, rel.range.begin); if(!start) @@ -608,7 +608,7 @@ std::vector Indexer::collect_references(index::Sy results.push_back(ReferenceWithContext{ .file = file_path.str(), .line = static_cast(start->line) + 1, - .context = extract_line(overlay.content, rel.range.begin), + .context = extract_line(session.text, rel.range.begin), }); } return true; @@ -718,10 +718,10 @@ std::vector Indexer::search_symbols(llvm::StringRef seen.insert(hash); } - for_each_overlay([&](std::uint32_t, const FileOverlay& overlay) -> bool { + for_each_session([&](std::uint32_t, const Session& session) -> bool { if(results.size() >= max_results) return false; - for(auto& [hash, symbol]: overlay.symbols) { + for(auto& [hash, symbol]: *session.symbols) { if(results.size() >= max_results) return false; if(seen.contains(hash)) diff --git a/src/server/compiler/indexer.h b/src/server/compiler/indexer.h index 08b8ae7b..db33fe5a 100644 --- a/src/server/compiler/indexer.h +++ b/src/server/compiler/indexer.h @@ -42,7 +42,7 @@ struct SymbolInfo { /// /// Indexer holds no index data of its own. All persistent data lives in /// Workspace (disk-derived ProjectIndex + MergedIndex shards) and per-file -/// data lives in Session (FileOverlay views from unsaved buffers). +/// data lives in Session (file index from unsaved buffers). /// /// Responsibilities: /// - Cross-file navigation queries (definition, references, hierarchy) @@ -55,9 +55,9 @@ struct SymbolInfo { /// - Document lifecycle — handled by MasterServer class Indexer { public: - /// Visitor for iterating open-file overlays. Returns false to stop early. + /// Visitor for iterating open Sessions. Returns false to stop early. using OverlayVisitor = - std::function; + std::function; Indexer(kota::event_loop& loop, Workspace& workspace, @@ -193,19 +193,19 @@ class Indexer { /// Cancel background indexing and wait for all tasks to settle. kota::task<> stop(); - /// Iterate all open-file overlays via the callback set at construction. - void for_each_overlay(OverlayVisitor visitor) const { + /// Iterate all open Sessions via the callback set at construction. + void for_each_session(OverlayVisitor visitor) const { if(each_overlay) each_overlay(std::move(visitor)); } - /// Invoke a callback with the overlay for a specific server-level path_id. - /// The callback is not invoked if no overlay exists for that path_id. + /// Invoke a callback with the Session for a specific server-level path_id. + /// The callback is not invoked if no Session exists for that path_id. template - void with_overlay(std::uint32_t server_path_id, Fn&& fn) const { - for_each_overlay([&](std::uint32_t id, const FileOverlay& overlay) -> bool { + void with_session(std::uint32_t server_path_id, Fn&& fn) const { + for_each_session([&](std::uint32_t id, const Session& session) -> bool { if(id == server_path_id) { - fn(overlay); + fn(session); return false; } return true; @@ -282,7 +282,7 @@ class Indexer { /// Checks if a server-level path_id has an open Session. std::function is_open; - /// Iterates all open-file overlays (FileOverlay views from live compilations). + /// Iterates all open Sessions with valid file indices. std::function each_overlay; /// LSP peer for progress reporting (optional, not owned). diff --git a/src/server/service/agent_client.cpp b/src/server/service/agent_client.cpp index f85f03cd..4f6fed40 100644 --- a/src/server/service/agent_client.cpp +++ b/src/server/service/agent_client.cpp @@ -101,8 +101,8 @@ static std::vector resolve_locator(const agentic::ReadSymbolPara for(auto& [hash, symbol]: workspace.project_index.symbols) try_symbol(hash, symbol); - indexer.for_each_overlay([&](std::uint32_t, const FileOverlay& overlay) -> bool { - for(auto& [hash, symbol]: overlay.symbols) + indexer.for_each_session([&](std::uint32_t, const Session& session) -> bool { + for(auto& [hash, symbol]: *session.symbols) try_symbol(hash, symbol); return true; }); @@ -119,14 +119,14 @@ static std::vector resolve_locator(const agentic::ReadSymbolPara auto pool_it = workspace.path_pool.cache.find(path_str); auto server_id = pool_it != workspace.path_pool.cache.end() ? pool_it->second : ~0u; if(server_id != ~0u) { - std::vector overlay_result; - indexer.with_overlay(server_id, [&](const FileOverlay& overlay) { - for(auto& [hash, rels]: overlay.file_index.relations) { + std::vector session_result; + indexer.with_session(server_id, [&](const Session& session) { + for(auto& [hash, rels]: session.file_index->relations) { for(auto& rel: rels) { if(rel.kind.value() != RelationKind::Definition) continue; - auto start = lsp::to_position(overlay.content, - overlay.line_starts, + auto start = lsp::to_position(session.text, + session.line_starts, lsp::PositionEncoding::UTF16, rel.range.begin); if(start && start->line == target_line) { @@ -136,14 +136,14 @@ static std::vector resolve_locator(const agentic::ReadSymbolPara continue; if(kind == SymbolKind::Parameter || kind == SymbolKind::Label) continue; - overlay_result.push_back( + session_result.push_back( {hash, std::move(name), kind, path_str, *loc.line}); } } } }); - if(!overlay_result.empty()) - return overlay_result; + if(!session_result.empty()) + return session_result; } auto it = workspace.project_index.path_pool.find(path_str); @@ -436,8 +436,8 @@ AgentClient::AgentClient(MasterServer& server, kota::ipc::JsonPeer& peer) : for(auto& [hash, symbol]: srv.workspace.project_index.symbols) try_symbol(hash, symbol); - srv.indexer.for_each_overlay([&](std::uint32_t, const FileOverlay& overlay) -> bool { - for(auto& [hash, symbol]: overlay.symbols) + srv.indexer.for_each_session([&](std::uint32_t, const Session& session) -> bool { + for(auto& [hash, symbol]: *session.symbols) try_symbol(hash, symbol); return true; }); @@ -492,10 +492,10 @@ AgentClient::AgentClient(MasterServer& server, kota::ipc::JsonPeer& peer) : if(pool_it == srv.workspace.path_pool.cache.end()) co_return result; auto server_id = pool_it->second; - bool found_overlay = false; - srv.indexer.with_overlay(server_id, [&](const FileOverlay& overlay) { - found_overlay = true; - for(auto& [hash, rels]: overlay.file_index.relations) { + bool found_session = false; + srv.indexer.with_session(server_id, [&](const Session& session) { + found_session = true; + for(auto& [hash, rels]: session.file_index->relations) { for(auto& rel: rels) { if(rel.kind.value() != RelationKind::Definition) continue; @@ -505,12 +505,12 @@ AgentClient::AgentClient(MasterServer& server, kota::ipc::JsonPeer& peer) : continue; if(!is_document_level(kind)) continue; - auto start = lsp::to_position(overlay.content, - overlay.line_starts, + auto start = lsp::to_position(session.text, + session.line_starts, lsp::PositionEncoding::UTF16, rel.range.begin); - auto end = lsp::to_position(overlay.content, - overlay.line_starts, + auto end = lsp::to_position(session.text, + session.line_starts, lsp::PositionEncoding::UTF16, rel.range.end); if(start && end) { @@ -526,7 +526,7 @@ AgentClient::AgentClient(MasterServer& server, kota::ipc::JsonPeer& peer) : } } }); - if(found_overlay) + if(found_session) co_return result; auto it = srv.workspace.project_index.path_pool.find(params.path); diff --git a/src/server/service/master_server.cpp b/src/server/service/master_server.cpp index a3c40ffc..c5b49011 100644 --- a/src/server/service/master_server.cpp +++ b/src/server/service/master_server.cpp @@ -47,11 +47,7 @@ MasterServer::MasterServer(kota::event_loop& loop, std::string self_path) : [this](Indexer::OverlayVisitor visitor) { for(auto& [path_id, session]: sessions) { if(session && session->file_index && session->symbols) { - FileOverlay overlay{*session->file_index, - *session->symbols, - session->text, - session->line_starts}; - if(!visitor(path_id, overlay)) + if(!visitor(path_id, *session)) break; } } diff --git a/src/server/workspace/workspace.h b/src/server/workspace/workspace.h index cf7595b4..e8617c0d 100644 --- a/src/server/workspace/workspace.h +++ b/src/server/workspace/workspace.h @@ -53,15 +53,6 @@ struct HeaderFileContext { std::uint64_t preamble_hash; ///< Hash of preamble content for staleness. }; -/// Non-owning view of an open file's index data for overlay queries. -/// Constructed by MasterServer from Session fields and passed to Indexer. -struct FileOverlay { - const index::FileIndex& file_index; - const index::SymbolTable& symbols; - std::string_view content; - std::span line_starts; -}; - /// Find the tightest occurrence at `offset` using `line_starts` for conversion. std::optional> find_occurrence(const index::FileIndex& file_index, From 3ff7b4b86a56baf635b4f66a78eeda1b2f49685d Mon Sep 17 00:00:00 2001 From: ykiko Date: Sat, 20 Jun 2026 05:52:10 +0800 Subject: [PATCH 5/8] refactor: remove MergedIndexShard and add CompilationUnitRef position helpers --- src/index/merged_index.cpp | 13 ++ src/index/merged_index.h | 6 + src/server/compiler/indexer.cpp | 263 ++++++++++++++++++---------- src/server/service/agent_client.cpp | 65 ++++--- src/server/workspace/workspace.cpp | 61 ------- src/server/workspace/workspace.h | 87 +-------- 6 files changed, 231 insertions(+), 264 deletions(-) diff --git a/src/index/merged_index.cpp b/src/index/merged_index.cpp index b8c2dbbf..8f189bef 100644 --- a/src/index/merged_index.cpp +++ b/src/index/merged_index.cpp @@ -6,6 +6,7 @@ #include "index/serialization.h" #include "support/filesystem.h" +#include "kota/ipc/lsp/position.h" #include "llvm/ADT/DenseSet.h" #include "llvm/Support/raw_os_ostream.h" @@ -594,6 +595,7 @@ void MergedIndex::merge(this Self& self, context.include_locations = std::move(include_locations); }); self.impl->occurrences_cache.clear(); + self.cached_line_starts.clear(); } void MergedIndex::merge(this Self& self, @@ -610,6 +612,7 @@ void MergedIndex::merge(this Self& self, context.includes.emplace_back(include_id, canonical_id); }); self.impl->occurrences_cache.clear(); + self.cached_line_starts.clear(); } llvm::StringRef MergedIndex::content(this const Self& self) { @@ -624,6 +627,16 @@ llvm::StringRef MergedIndex::content(this const Self& self) { return {}; } +std::span MergedIndex::line_starts(this const Self& self) { + if(self.cached_line_starts.empty()) { + auto c = self.content(); + if(!c.empty()) { + self.cached_line_starts = kota::ipc::lsp::build_line_starts(c); + } + } + return self.cached_line_starts; +} + bool operator==(MergedIndex& lhs, MergedIndex& rhs) { lhs.load_in_memory(); rhs.load_in_memory(); diff --git a/src/index/merged_index.h b/src/index/merged_index.h index 2e4bc375..112f093b 100644 --- a/src/index/merged_index.h +++ b/src/index/merged_index.h @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "index/tu_index.h" @@ -67,6 +68,9 @@ class MergedIndex { /// Get the stored source content for position mapping. llvm::StringRef content(this const Self& self); + /// Get or lazily compute line starts from content. + std::span line_starts(this const Self& self); + /// Merge the index with given compilation context. void merge(this Self& self, std::uint32_t path_id, @@ -92,6 +96,8 @@ class MergedIndex { /// The in memory data of the index. std::unique_ptr impl; + + mutable std::vector cached_line_starts; }; } // namespace clice::index diff --git a/src/server/compiler/indexer.cpp b/src/server/compiler/indexer.cpp index 3c0240c1..f04b9f16 100644 --- a/src/server/compiler/indexer.cpp +++ b/src/server/compiler/indexer.cpp @@ -26,6 +26,107 @@ namespace clice { namespace lsp = kota::ipc::lsp; +static auto to_position(const Session& session, std::uint32_t offset) { + return lsp::to_position(session.text, + session.line_starts, + lsp::PositionEncoding::UTF16, + offset); +} + +static auto to_offset(const Session& session, const protocol::Position& position) { + return lsp::to_offset(session.text, + session.line_starts, + lsp::PositionEncoding::UTF16, + position); +} + +const static index::Occurrence* lookup_occurrence(const std::vector& occs, + std::uint32_t offset) { + auto it = std::ranges::lower_bound(occs, offset, {}, [](const index::Occurrence& o) { + return o.range.end; + }); + const index::Occurrence* best = nullptr; + while(it != occs.end() && it->range.contains(offset)) { + if(!best || (it->range.end - it->range.begin) < (best->range.end - best->range.begin)) + best = &*it; + ++it; + } + return best; +} + +static std::optional> + find_occurrence(const Session& session, std::uint32_t offset) { + auto* occ = lookup_occurrence(session.file_index->occurrences, offset); + if(!occ) + return std::nullopt; + auto start = to_position(session, occ->range.begin); + auto end = to_position(session, occ->range.end); + if(!start || !end) + return std::nullopt; + return std::pair{ + occ->target, + protocol::Range{*start, *end} + }; +} + +template +static void + find_relations(const Session& session, index::SymbolHash hash, RelationKind kind, Fn&& fn) { + auto it = session.file_index->relations.find(hash); + if(it == session.file_index->relations.end()) + return; + for(auto& r: it->second) { + if(r.kind & kind) { + auto start = to_position(session, r.range.begin); + auto end = to_position(session, r.range.end); + if(start && end) { + if(!fn(r, protocol::Range{*start, *end})) + return; + } + } + } +} + +static std::optional> + find_occurrence(const index::MergedIndex& index, std::uint32_t offset) { + auto ls = index.line_starts(); + auto c = index.content(); + if(ls.empty()) + return std::nullopt; + std::optional> result; + index.lookup(offset, [&](const index::Occurrence& o) { + auto start = lsp::to_position(c, ls, lsp::PositionEncoding::UTF16, o.range.begin); + auto end = lsp::to_position(c, ls, lsp::PositionEncoding::UTF16, o.range.end); + if(start && end) { + result = { + o.target, + protocol::Range{*start, *end} + }; + } + return false; + }); + return result; +} + +template +static void find_relations(const index::MergedIndex& index, + index::SymbolHash hash, + RelationKind kind, + Fn&& fn) { + auto ls = index.line_starts(); + auto c = index.content(); + if(ls.empty()) + return; + index.lookup(hash, kind, [&](const index::Relation& r) { + auto start = lsp::to_position(c, ls, lsp::PositionEncoding::UTF16, r.range.begin); + auto end = lsp::to_position(c, ls, lsp::PositionEncoding::UTF16, r.range.end); + if(start && end) { + return fn(r, protocol::Range{*start, *end}); + } + return true; + }); +} + void Indexer::merge(const void* tu_index_data, std::size_t size) { auto tu_index = index::TUIndex::from(tu_index_data); if(tu_index.graph.paths.empty()) { @@ -54,11 +155,11 @@ void Indexer::merge(const void* tu_index_data, std::size_t size) { file_content_storage = (*buf)->getBuffer().str(); file_content = file_content_storage; } - shard.index.merge(global_path_id, - tu_index.built_at, - std::move(include_locs), - file_idx, - file_content); + shard.merge(global_path_id, + tu_index.built_at, + std::move(include_locs), + file_idx, + file_content); } else { std::optional include_id; for(std::uint32_t i = 0; i < tu_index.graph.locations.size(); ++i) { @@ -79,9 +180,8 @@ void Indexer::merge(const void* tu_index_data, std::size_t size) { header_content_storage = (*header_buf)->getBuffer().str(); header_content = header_content_storage; } - shard.index.merge(global_path_id, *include_id, file_idx, header_content); + shard.merge(global_path_id, *include_id, file_idx, header_content); } - shard.invalidate(); }; for(auto& [tu_path_id, file_idx]: tu_index.path_file_indices) { @@ -126,13 +226,13 @@ void Indexer::save(llvm::StringRef index_dir) { std::size_t saved = 0; for(auto& [path_id, shard]: workspace.merged_indices) { - if(!shard.index.need_rewrite()) + if(!shard.need_rewrite()) continue; auto shard_path = path::join(shards_dir, std::to_string(path_id) + ".idx"); std::error_code write_ec; llvm::raw_fd_ostream os(shard_path, write_ec); if(!write_ec) { - shard.index.serialize(os); + shard.serialize(os); ++saved; } } @@ -162,7 +262,7 @@ void Indexer::load(llvm::StringRef index_dir) { std::uint32_t path_id = 0; if(stem.getAsInteger(10, path_id)) continue; - workspace.merged_indices[path_id] = MergedIndexShard{index::MergedIndex::load(it->path())}; + workspace.merged_indices[path_id] = index::MergedIndex::load(it->path()); } if(!workspace.merged_indices.empty()) { @@ -183,7 +283,7 @@ bool Indexer::need_update(llvm::StringRef file_path) { for(auto& p: workspace.project_index.path_pool.paths) { path_mapping.push_back(p); } - return merged_it->second.index.need_update(path_mapping); + return merged_it->second.need_update(path_mapping); } bool Indexer::find_symbol_info(index::SymbolHash hash, std::string& name, SymbolKind& kind) const { @@ -214,14 +314,10 @@ Indexer::CursorHit Indexer::resolve_cursor(llvm::StringRef path, Session* session) { // Try the session's open file index first. if(session && session->file_index) { - auto offset = lsp::to_offset(session->text, - session->line_starts, - lsp::PositionEncoding::UTF16, - position); + auto offset = to_offset(*session, position); if(!offset) return {}; - if(auto found = - find_occurrence(*session->file_index, session->text, session->line_starts, *offset)) + if(auto found = find_occurrence(*session, *offset)) return {found->first, found->second}; return {}; } @@ -229,8 +325,7 @@ Indexer::CursorHit Indexer::resolve_cursor(llvm::StringRef path, // Fallback to MergedIndex, using session text for position -> offset. if(!session) return {}; - auto offset = - lsp::to_offset(session->text, session->line_starts, lsp::PositionEncoding::UTF16, position); + auto offset = to_offset(*session, position); if(!offset) return {}; @@ -241,7 +336,7 @@ Indexer::CursorHit Indexer::resolve_cursor(llvm::StringRef path, if(shard_it == workspace.merged_indices.end()) return {}; - if(auto found = shard_it->second.find_occurrence(*offset)) + if(auto found = find_occurrence(shard_it->second, *offset)) return {found->first, found->second}; return {}; } @@ -267,12 +362,13 @@ std::vector Indexer::query_relations(llvm::StringRef path, auto uri = lsp::URI::from_file_path(workspace.project_index.path_pool.path(file_id)); if(!uri) continue; - shard_it->second.find_relations(hit.hash, - kind, - [&](const auto&, protocol::Range range) { - locations.push_back({uri->str(), range}); - return true; - }); + find_relations(shard_it->second, + hit.hash, + kind, + [&](const auto&, protocol::Range range) { + locations.push_back({uri->str(), range}); + return true; + }); } } @@ -280,15 +376,10 @@ std::vector Indexer::query_relations(llvm::StringRef path, auto uri = lsp::URI::from_file_path(std::string(workspace.path_pool.resolve(id))); if(!uri) return true; - find_relations(*session.file_index, - session.text, - session.line_starts, - hit.hash, - kind, - [&](const auto&, protocol::Range range) { - locations.push_back({uri->str(), range}); - return true; - }); + find_relations(session, hit.hash, kind, [&](const auto&, protocol::Range range) { + locations.push_back({uri->str(), range}); + return true; + }); return true; }); @@ -317,9 +408,7 @@ std::optional Indexer::find_definition_location(index::Symbo auto uri = lsp::URI::from_file_path(std::string(workspace.path_pool.resolve(id))); if(!uri) return true; - find_relations(*session.file_index, - session.text, - session.line_starts, + find_relations(session, hash, RelationKind::Definition, [&](const auto&, protocol::Range range) { @@ -346,12 +435,13 @@ std::optional Indexer::find_definition_location(index::Symbo if(!uri) continue; std::optional result; - shard_it->second.find_relations(hash, - RelationKind::Definition, - [&](const auto&, protocol::Range range) { - result = protocol::Location{uri->str(), range}; - return false; - }); + find_relations(shard_it->second, + hash, + RelationKind::Definition, + [&](const auto&, protocol::Range range) { + result = protocol::Location{uri->str(), range}; + return false; + }); if(result) return result; } @@ -390,22 +480,17 @@ void Indexer::collect_grouped_relations( auto shard_it = workspace.merged_indices.find(file_id); if(shard_it == workspace.merged_indices.end()) continue; - shard_it->second.find_relations(hash, kind, [&](const auto& r, protocol::Range range) { + find_relations(shard_it->second, hash, kind, [&](const auto& r, protocol::Range range) { target_ranges[r.target_symbol].push_back(range); return true; }); } } for_each_session([&](std::uint32_t, const Session& session) -> bool { - find_relations(*session.file_index, - session.text, - session.line_starts, - hash, - kind, - [&](const auto& r, protocol::Range range) { - target_ranges[r.target_symbol].push_back(range); - return true; - }); + find_relations(session, hash, kind, [&](const auto& r, protocol::Range range) { + target_ranges[r.target_symbol].push_back(range); + return true; + }); return true; }); } @@ -422,8 +507,7 @@ void Indexer::collect_unique_targets(index::SymbolHash hash, auto shard_it = workspace.merged_indices.find(file_id); if(shard_it == workspace.merged_indices.end()) continue; - /// No position conversion needed -- just collect target symbol hashes. - shard_it->second.index.lookup(hash, kind, [&](const index::Relation& r) { + shard_it->second.lookup(hash, kind, [&](const index::Relation& r) { if(seen.insert(r.target_symbol).second) { targets.push_back(r.target_symbol); } @@ -488,14 +572,8 @@ std::optional Indexer::get_definition_text(index::Symbo continue; if(def_range.end > session.text.size()) continue; - auto start = lsp::to_position(session.text, - session.line_starts, - lsp::PositionEncoding::UTF16, - def_range.begin); - auto end = lsp::to_position(session.text, - session.line_starts, - lsp::PositionEncoding::UTF16, - def_range.end); + auto start = to_position(session, def_range.begin); + auto end = to_position(session, def_range.end); if(!start || !end) continue; session_result = DefinitionText{ @@ -522,34 +600,31 @@ std::optional Indexer::get_definition_text(index::Symbo auto shard_it = workspace.merged_indices.find(file_id); if(shard_it == workspace.merged_indices.end()) continue; - auto ls = shard_it->second.line_starts(); + auto& mi = shard_it->second; + auto ls = mi.line_starts(); if(ls.empty()) continue; - auto content = shard_it->second.index.content(); + auto content = mi.content(); std::optional result; - shard_it->second.index.lookup( - hash, - RelationKind::Definition, - [&](const index::Relation& r) { - auto def_range = std::bit_cast(r.target_symbol); - if(def_range.begin >= def_range.end || def_range.end > content.size()) - return true; - auto start = - lsp::to_position(content, ls, lsp::PositionEncoding::UTF16, def_range.begin); - auto end = - lsp::to_position(content, ls, lsp::PositionEncoding::UTF16, def_range.end); - if(!start || !end) - return true; - result = DefinitionText{ - .file = workspace.project_index.path_pool.path(file_id).str(), - .start_line = static_cast(start->line) + 1, - .end_line = static_cast(end->line) + 1, - .text = std::string( - content.substr(def_range.begin, def_range.end - def_range.begin)), - }; - return false; - }); + mi.lookup(hash, RelationKind::Definition, [&](const index::Relation& r) { + auto def_range = std::bit_cast(r.target_symbol); + if(def_range.begin >= def_range.end || def_range.end > content.size()) + return true; + auto start = + lsp::to_position(content, ls, lsp::PositionEncoding::UTF16, def_range.begin); + auto end = lsp::to_position(content, ls, lsp::PositionEncoding::UTF16, def_range.end); + if(!start || !end) + return true; + result = DefinitionText{ + .file = workspace.project_index.path_pool.path(file_id).str(), + .start_line = static_cast(start->line) + 1, + .end_line = static_cast(end->line) + 1, + .text = + std::string(content.substr(def_range.begin, def_range.end - def_range.begin)), + }; + return false; + }); if(result) return result; } @@ -569,13 +644,14 @@ std::vector Indexer::collect_references(index::Sy auto shard_it = workspace.merged_indices.find(file_id); if(shard_it == workspace.merged_indices.end()) continue; - auto ls = shard_it->second.line_starts(); + auto& mi = shard_it->second; + auto ls = mi.line_starts(); if(ls.empty()) continue; - auto content = shard_it->second.index.content(); + auto content = mi.content(); auto file_path = workspace.project_index.path_pool.path(file_id); - shard_it->second.index.lookup(hash, kind, [&](const index::Relation& r) { + mi.lookup(hash, kind, [&](const index::Relation& r) { auto start = lsp::to_position(content, ls, lsp::PositionEncoding::UTF16, r.range.begin); if(!start) @@ -599,10 +675,7 @@ std::vector Indexer::collect_references(index::Sy for(auto& rel: it->second) { if(rel.kind != kind) continue; - auto start = lsp::to_position(session.text, - session.line_starts, - lsp::PositionEncoding::UTF16, - rel.range.begin); + auto start = to_position(session, rel.range.begin); if(!start) continue; results.push_back(ReferenceWithContext{ diff --git a/src/server/service/agent_client.cpp b/src/server/service/agent_client.cpp index 4f6fed40..eade0a8a 100644 --- a/src/server/service/agent_client.cpp +++ b/src/server/service/agent_client.cpp @@ -11,6 +11,7 @@ #include "support/filesystem.h" #include "support/logging.h" +#include "kota/ipc/lsp/position.h" #include "kota/ipc/lsp/uri.h" #include "kota/meta/enum.h" #include "llvm/ADT/DenseSet.h" @@ -23,6 +24,25 @@ using RequestContext = kota::ipc::JsonPeer::RequestContext; namespace lsp = kota::ipc::lsp; namespace protocol = kota::ipc::protocol; +template +static void find_relations(const index::MergedIndex& index, + index::SymbolHash hash, + RelationKind kind, + Fn&& fn) { + auto ls = index.line_starts(); + auto c = index.content(); + if(ls.empty()) + return; + index.lookup(hash, kind, [&](const index::Relation& r) { + auto start = lsp::to_position(c, ls, lsp::PositionEncoding::UTF16, r.range.begin); + auto end = lsp::to_position(c, ls, lsp::PositionEncoding::UTF16, r.range.end); + if(start && end) { + return fn(r, protocol::Range{*start, *end}); + } + return true; + }); +} + static std::string_view symbol_kind_name(SymbolKind kind) { constexpr auto names = kota::meta::reflection::member_names; auto idx = static_cast(kind.value()); @@ -159,15 +179,16 @@ static std::vector resolve_locator(const agentic::ReadSymbolPara if(!symbol.reference_files.contains(proj_id)) continue; bool found = false; - shard_it->second.find_relations(hash, - RelationKind::Definition, - [&](const index::Relation&, protocol::Range range) { - if(range.start.line == target_line) { - found = true; - return false; - } - return true; - }); + find_relations(shard_it->second, + hash, + RelationKind::Definition, + [&](const index::Relation&, protocol::Range range) { + if(range.start.line == target_line) { + found = true; + return false; + } + return true; + }); if(found) return { {hash, symbol.name, symbol.kind, path_str, *loc.line} @@ -546,19 +567,19 @@ AgentClient::AgentClient(MasterServer& server, kota::ipc::JsonPeer& peer) : if(!symbol.reference_files.contains(proj_id)) continue; - shard_it->second.find_relations( - hash, - RelationKind::Definition, - [&](const index::Relation&, protocol::Range range) { - result.symbols.push_back(DocumentSymbolEntry{ - .name = symbol.name, - .kind = std::string(symbol_kind_name(symbol.kind)), - .start_line = static_cast(range.start.line) + 1, - .end_line = static_cast(range.end.line) + 1, - .symbol_id = hash, - }); - return true; - }); + find_relations(shard_it->second, + hash, + RelationKind::Definition, + [&](const index::Relation&, protocol::Range range) { + result.symbols.push_back(DocumentSymbolEntry{ + .name = symbol.name, + .kind = std::string(symbol_kind_name(symbol.kind)), + .start_line = static_cast(range.start.line) + 1, + .end_line = static_cast(range.end.line) + 1, + .symbol_id = hash, + }); + return true; + }); } co_return result; diff --git a/src/server/workspace/workspace.cpp b/src/server/workspace/workspace.cpp index 2f88309d..9b27a575 100644 --- a/src/server/workspace/workspace.cpp +++ b/src/server/workspace/workspace.cpp @@ -1,6 +1,5 @@ #include "server/workspace/workspace.h" -#include #include #include "support/filesystem.h" @@ -8,8 +7,6 @@ #include "syntax/scan.h" #include "kota/codec/json/json.h" -#include "kota/ipc/lsp/position.h" -#include "kota/ipc/lsp/protocol.h" #include "llvm/Support/Chrono.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" @@ -18,64 +15,6 @@ namespace clice { -namespace lsp = kota::ipc::lsp; - -/// Find the tightest (innermost) occurrence containing `offset` via binary search. -const static index::Occurrence* lookup_occurrence(const std::vector& occs, - std::uint32_t offset) { - auto it = std::ranges::lower_bound(occs, offset, {}, [](const index::Occurrence& o) { - return o.range.end; - }); - const index::Occurrence* best = nullptr; - while(it != occs.end() && it->range.contains(offset)) { - if(!best || (it->range.end - it->range.begin) < (best->range.end - best->range.begin)) { - best = &*it; - } - ++it; - } - return best; -} - -std::optional> - find_occurrence(const index::FileIndex& file_index, - std::string_view content, - std::span line_starts, - std::uint32_t offset) { - auto* occ = lookup_occurrence(file_index.occurrences, offset); - if(!occ) - return std::nullopt; - auto start = - lsp::to_position(content, line_starts, lsp::PositionEncoding::UTF16, occ->range.begin); - auto end = lsp::to_position(content, line_starts, lsp::PositionEncoding::UTF16, occ->range.end); - if(!start || !end) - return std::nullopt; - return std::pair{ - occ->target, - protocol::Range{*start, *end} - }; -} - -std::optional> - MergedIndexShard::find_occurrence(std::uint32_t offset) const { - auto ls = line_starts(); - auto c = index.content(); - if(ls.empty()) - return std::nullopt; - std::optional> result; - index.lookup(offset, [&](const index::Occurrence& o) { - auto start = lsp::to_position(c, ls, lsp::PositionEncoding::UTF16, o.range.begin); - auto end = lsp::to_position(c, ls, lsp::PositionEncoding::UTF16, o.range.end); - if(start && end) { - result = { - o.target, - protocol::Range{*start, *end} - }; - } - return false; - }); - return result; -} - llvm::SmallVector Workspace::on_file_saved(std::uint32_t path_id) { llvm::SmallVector dirtied; diff --git a/src/server/workspace/workspace.h b/src/server/workspace/workspace.h index e8617c0d..46eba389 100644 --- a/src/server/workspace/workspace.h +++ b/src/server/workspace/workspace.h @@ -3,9 +3,7 @@ #include #include #include -#include #include -#include #include #include #include @@ -20,8 +18,6 @@ #include "support/path_pool.h" #include "syntax/dependency_graph.h" -#include "kota/ipc/lsp/position.h" -#include "kota/ipc/lsp/protocol.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallVector.h" @@ -29,9 +25,6 @@ namespace clice { -namespace protocol = kota::ipc::protocol; -namespace lsp = kota::ipc::lsp; - /// Two-layer staleness snapshot for compilation artifacts (PCH, AST, etc.). /// /// Layer 1 (fast): compare each file's current mtime against build_at. @@ -53,84 +46,6 @@ struct HeaderFileContext { std::uint64_t preamble_hash; ///< Hash of preamble content for staleness. }; -/// Find the tightest occurrence at `offset` using `line_starts` for conversion. -std::optional> - find_occurrence(const index::FileIndex& file_index, - std::string_view content, - std::span line_starts, - std::uint32_t offset); - -/// Iterate relations matching `kind`, calling back with pre-converted ranges. -/// Callback: (const index::Relation&, protocol::Range) -> bool (true = continue). -template -void find_relations(const index::FileIndex& file_index, - std::string_view content, - std::span line_starts, - index::SymbolHash hash, - RelationKind kind, - Fn&& fn) { - auto it = file_index.relations.find(hash); - if(it == file_index.relations.end()) - return; - for(auto& r: it->second) { - if(r.kind & kind) { - auto start = - lsp::to_position(content, line_starts, lsp::PositionEncoding::UTF16, r.range.begin); - auto end = - lsp::to_position(content, line_starts, lsp::PositionEncoding::UTF16, r.range.end); - if(start && end) { - if(!fn(r, protocol::Range{*start, *end})) - return; - } - } - } -} - -/// Wraps index::MergedIndex with lazily-cached line starts for position mapping. -struct MergedIndexShard { - index::MergedIndex index; - mutable std::vector cached_line_starts; - - /// Get or lazily build line starts from the index's stored content. - std::span line_starts() const { - if(cached_line_starts.empty()) { - auto c = index.content(); - if(!c.empty()) { - cached_line_starts = lsp::build_line_starts(c); - } - } - return cached_line_starts; - } - - /// Invalidate cached line starts (call after merge changes content). - void invalidate() { - cached_line_starts.clear(); - } - - /// Find occurrence at byte offset. - /// Returns (symbol_hash, LSP range) with positions already converted. - std::optional> - find_occurrence(std::uint32_t offset) const; - - /// Iterate relations matching `kind`, calling back with pre-converted ranges. - /// Callback: (const index::Relation&, protocol::Range) -> bool (true = continue). - template - void find_relations(index::SymbolHash hash, RelationKind kind, Fn&& fn) const { - auto ls = line_starts(); - auto c = index.content(); - if(ls.empty()) - return; - index.lookup(hash, kind, [&](const index::Relation& r) { - auto start = lsp::to_position(c, ls, lsp::PositionEncoding::UTF16, r.range.begin); - auto end = lsp::to_position(c, ls, lsp::PositionEncoding::UTF16, r.range.end); - if(start && end) { - return fn(r, protocol::Range{*start, *end}); - } - return true; - }); - } -}; - /// Cached PCH state. Content-addressed by preamble hash — shared across all /// files (open or on-disk) that have the same preamble content. struct PCHState { @@ -206,7 +121,7 @@ struct Workspace { /// Per-file index shards from background indexing, keyed by project-level /// path_id. Contains symbol occurrences, relations, and stored content /// for position mapping. - llvm::DenseMap merged_indices; + llvm::DenseMap merged_indices; /// Called when a file is saved to disk. Cascades invalidation through /// compile_graph and clears affected PCM caches. From f0372573a7cd140b22a6e40388b0202dea813058 Mon Sep 17 00:00:00 2001 From: ykiko Date: Sat, 20 Jun 2026 16:55:49 +0800 Subject: [PATCH 6/8] refactor: compute line_starts eagerly at merge/load time --- src/index/merged_index.cpp | 26 +++++++++++++++----------- src/index/merged_index.h | 2 +- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/index/merged_index.cpp b/src/index/merged_index.cpp index 8f189bef..26f6589c 100644 --- a/src/index/merged_index.cpp +++ b/src/index/merged_index.cpp @@ -179,7 +179,12 @@ MergedIndex::MergedIndex(std::unique_ptr buffer, std::unique MergedIndex::MergedIndex() = default; MergedIndex::MergedIndex(llvm::StringRef data) : - MergedIndex(llvm::MemoryBuffer::getMemBuffer(data, "", false), nullptr) {} + MergedIndex(llvm::MemoryBuffer::getMemBuffer(data, "", false), nullptr) { + auto c = content(); + if(!c.empty()) { + cached_line_starts = kota::ipc::lsp::build_line_starts(c); + } +} MergedIndex::MergedIndex(MergedIndex&& other) = default; @@ -256,6 +261,7 @@ void MergedIndex::load_in_memory(this Self& self) { if(root->content()) { index.content = root->content()->str(); + self.cached_line_starts = kota::ipc::lsp::build_line_starts(index.content); } self.buffer.reset(); @@ -265,9 +271,13 @@ MergedIndex MergedIndex::load(llvm::StringRef path) { auto buffer = llvm::MemoryBuffer::getFile(path); if(!buffer) { return MergedIndex(); - } else { - return MergedIndex(std::move(*buffer), nullptr); } + auto mi = MergedIndex(std::move(*buffer), nullptr); + auto c = mi.content(); + if(!c.empty()) { + mi.cached_line_starts = kota::ipc::lsp::build_line_starts(c); + } + return mi; } void MergedIndex::serialize(this const Self& self, llvm::raw_ostream& out) { @@ -595,7 +605,7 @@ void MergedIndex::merge(this Self& self, context.include_locations = std::move(include_locations); }); self.impl->occurrences_cache.clear(); - self.cached_line_starts.clear(); + self.cached_line_starts = kota::ipc::lsp::build_line_starts(self.impl->content); } void MergedIndex::merge(this Self& self, @@ -606,13 +616,13 @@ void MergedIndex::merge(this Self& self, self.load_in_memory(); if(self.impl->content.empty() && !content.empty()) { self.impl->content = content.str(); + self.cached_line_starts = kota::ipc::lsp::build_line_starts(self.impl->content); } self.impl->merge(path_id, index, [&](Impl& self, std::uint32_t canonical_id) { auto& context = self.header_contexts[path_id]; context.includes.emplace_back(include_id, canonical_id); }); self.impl->occurrences_cache.clear(); - self.cached_line_starts.clear(); } llvm::StringRef MergedIndex::content(this const Self& self) { @@ -628,12 +638,6 @@ llvm::StringRef MergedIndex::content(this const Self& self) { } std::span MergedIndex::line_starts(this const Self& self) { - if(self.cached_line_starts.empty()) { - auto c = self.content(); - if(!c.empty()) { - self.cached_line_starts = kota::ipc::lsp::build_line_starts(c); - } - } return self.cached_line_starts; } diff --git a/src/index/merged_index.h b/src/index/merged_index.h index 112f093b..f331da66 100644 --- a/src/index/merged_index.h +++ b/src/index/merged_index.h @@ -97,7 +97,7 @@ class MergedIndex { /// The in memory data of the index. std::unique_ptr impl; - mutable std::vector cached_line_starts; + std::vector cached_line_starts; }; } // namespace clice::index From 6037adc77db21624cec4c049328d950a8cf382d0 Mon Sep 17 00:00:00 2001 From: ykiko Date: Sat, 20 Jun 2026 17:02:29 +0800 Subject: [PATCH 7/8] refactor: serialize line_starts in MergedIndex binary format --- src/index/merged_index.cpp | 43 +- src/index/merged_index.h | 4 +- src/index/schema.fbs | 3 + src/index/schema_generated.h | 1547 ++++++++++++++++++++++++++++++++++ 4 files changed, 1577 insertions(+), 20 deletions(-) create mode 100644 src/index/schema_generated.h diff --git a/src/index/merged_index.cpp b/src/index/merged_index.cpp index 26f6589c..61bd0a30 100644 --- a/src/index/merged_index.cpp +++ b/src/index/merged_index.cpp @@ -109,6 +109,9 @@ struct MergedIndex::Impl { /// The content of corresponding source file. std::string content; + /// Line start offsets for position mapping. + std::vector line_starts; + /// If this file is included by other source file, then it has header contexts. /// The key represents the source file id, value represents the context in the /// source file. @@ -179,12 +182,7 @@ MergedIndex::MergedIndex(std::unique_ptr buffer, std::unique MergedIndex::MergedIndex() = default; MergedIndex::MergedIndex(llvm::StringRef data) : - MergedIndex(llvm::MemoryBuffer::getMemBuffer(data, "", false), nullptr) { - auto c = content(); - if(!c.empty()) { - cached_line_starts = kota::ipc::lsp::build_line_starts(c); - } -} + MergedIndex(llvm::MemoryBuffer::getMemBuffer(data, "", false), nullptr) {} MergedIndex::MergedIndex(MergedIndex&& other) = default; @@ -261,7 +259,13 @@ void MergedIndex::load_in_memory(this Self& self) { if(root->content()) { index.content = root->content()->str(); - self.cached_line_starts = kota::ipc::lsp::build_line_starts(index.content); + } + + if(root->line_starts() && root->line_starts()->size() > 0) { + auto* ls = root->line_starts(); + index.line_starts.assign(ls->begin(), ls->end()); + } else if(!index.content.empty()) { + index.line_starts = kota::ipc::lsp::build_line_starts(index.content); } self.buffer.reset(); @@ -272,12 +276,7 @@ MergedIndex MergedIndex::load(llvm::StringRef path) { if(!buffer) { return MergedIndex(); } - auto mi = MergedIndex(std::move(*buffer), nullptr); - auto c = mi.content(); - if(!c.empty()) { - mi.cached_line_starts = kota::ipc::lsp::build_line_starts(c); - } - return mi; + return MergedIndex(std::move(*buffer), nullptr); } void MergedIndex::serialize(this const Self& self, llvm::raw_ostream& out) { @@ -371,6 +370,7 @@ void MergedIndex::serialize(this const Self& self, llvm::raw_ostream& out) { auto removed = CreateVector(builder, buffer); auto content_offset = CreateString(builder, index->content); + auto line_starts_offset = builder.CreateVector(index->line_starts); auto merged_index = binary::CreateMergedIndex(builder, index->max_canonical_id, @@ -380,7 +380,8 @@ void MergedIndex::serialize(this const Self& self, llvm::raw_ostream& out) { CreateVector(builder, occurrences), CreateVector(builder, relations), removed, - content_offset); + content_offset, + line_starts_offset); builder.Finish(merged_index); out.write(safe_cast(builder.GetBufferPointer()), builder.GetSize()); @@ -598,6 +599,7 @@ void MergedIndex::merge(this Self& self, llvm::StringRef content) { self.load_in_memory(); self.impl->content = content.str(); + self.impl->line_starts = kota::ipc::lsp::build_line_starts(self.impl->content); self.impl->merge(path_id, index, [&](Impl& self, std::uint32_t canonical_id) { auto& context = self.compilation_contexts[path_id]; context.canonical_id = canonical_id; @@ -605,7 +607,6 @@ void MergedIndex::merge(this Self& self, context.include_locations = std::move(include_locations); }); self.impl->occurrences_cache.clear(); - self.cached_line_starts = kota::ipc::lsp::build_line_starts(self.impl->content); } void MergedIndex::merge(this Self& self, @@ -616,7 +617,7 @@ void MergedIndex::merge(this Self& self, self.load_in_memory(); if(self.impl->content.empty() && !content.empty()) { self.impl->content = content.str(); - self.cached_line_starts = kota::ipc::lsp::build_line_starts(self.impl->content); + self.impl->line_starts = kota::ipc::lsp::build_line_starts(self.impl->content); } self.impl->merge(path_id, index, [&](Impl& self, std::uint32_t canonical_id) { auto& context = self.header_contexts[path_id]; @@ -638,7 +639,15 @@ llvm::StringRef MergedIndex::content(this const Self& self) { } std::span MergedIndex::line_starts(this const Self& self) { - return self.cached_line_starts; + if(self.impl) { + return self.impl->line_starts; + } else if(self.buffer) { + auto root = fbs::GetRoot(self.buffer->getBufferStart()); + if(root->line_starts() && root->line_starts()->size() > 0) { + return {root->line_starts()->data(), root->line_starts()->size()}; + } + } + return {}; } bool operator==(MergedIndex& lhs, MergedIndex& rhs) { diff --git a/src/index/merged_index.h b/src/index/merged_index.h index f331da66..4d6f4eda 100644 --- a/src/index/merged_index.h +++ b/src/index/merged_index.h @@ -68,7 +68,7 @@ class MergedIndex { /// Get the stored source content for position mapping. llvm::StringRef content(this const Self& self); - /// Get or lazily compute line starts from content. + /// Get line starts for position mapping. std::span line_starts(this const Self& self); /// Merge the index with given compilation context. @@ -96,8 +96,6 @@ class MergedIndex { /// The in memory data of the index. std::unique_ptr impl; - - std::vector cached_line_starts; }; } // namespace clice::index diff --git a/src/index/schema.fbs b/src/index/schema.fbs index e25e1f29..29db9ace 100644 --- a/src/index/schema.fbs +++ b/src/index/schema.fbs @@ -118,6 +118,9 @@ removed: content: string; + +line_starts: + [uint]; } table TUFileRelationsEntry { diff --git a/src/index/schema_generated.h b/src/index/schema_generated.h new file mode 100644 index 00000000..bec4a661 --- /dev/null +++ b/src/index/schema_generated.h @@ -0,0 +1,1547 @@ +// automatically generated by the FlatBuffers compiler, do not modify + +#ifndef FLATBUFFERS_GENERATED_SCHEMA_CLICE_INDEX_BINARY_H_ +#define FLATBUFFERS_GENERATED_SCHEMA_CLICE_INDEX_BINARY_H_ + +#include "flatbuffers/flatbuffers.h" + +// Ensure the included flatbuffers.h is the same version as when this file was +// generated, otherwise it may not be compatible. +static_assert(FLATBUFFERS_VERSION_MAJOR == 25 && FLATBUFFERS_VERSION_MINOR == 9 && + FLATBUFFERS_VERSION_REVISION == 23, + "Non-compatible flatbuffers version included"); + +namespace clice { +namespace index { +namespace binary { + +struct Range; + +struct Occurrence; + +struct Relation; + +struct CacheEntry; +struct CacheEntryBuilder; + +struct IncludeContext; + +struct HeaderContextEntry; +struct HeaderContextEntryBuilder; + +struct IncludeLocation; + +struct CompilationContextEntry; +struct CompilationContextEntryBuilder; + +struct OccurrenceEntry; +struct OccurrenceEntryBuilder; + +struct RelationEntry; +struct RelationEntryBuilder; + +struct SymbolRelationsEntry; +struct SymbolRelationsEntryBuilder; + +struct Symbol; +struct SymbolBuilder; + +struct SymbolEntry; +struct SymbolEntryBuilder; + +struct MergedIndex; +struct MergedIndexBuilder; + +struct TUFileRelationsEntry; +struct TUFileRelationsEntryBuilder; + +struct TUFileIndexEntry; +struct TUFileIndexEntryBuilder; + +struct TUIndex; +struct TUIndexBuilder; + +struct PathEntry; +struct PathEntryBuilder; + +struct PathMapEntry; + +struct ProjectIndex; +struct ProjectIndexBuilder; + +FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Range FLATBUFFERS_FINAL_CLASS { +private: + uint32_t begin_; + uint32_t end_; + +public: + Range() : begin_(0), end_(0) {} + Range(uint32_t _begin, uint32_t _end) : + begin_(::flatbuffers::EndianScalar(_begin)), end_(::flatbuffers::EndianScalar(_end)) {} + uint32_t begin() const { + return ::flatbuffers::EndianScalar(begin_); + } + uint32_t end() const { + return ::flatbuffers::EndianScalar(end_); + } +}; + +FLATBUFFERS_STRUCT_END(Range, 8); + +FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Occurrence FLATBUFFERS_FINAL_CLASS { +private: + clice::index::binary::Range range_; + uint64_t target_; + +public: + Occurrence() : range_(), target_(0) {} + Occurrence(const clice::index::binary::Range& _range, uint64_t _target) : + range_(_range), target_(::flatbuffers::EndianScalar(_target)) {} + const clice::index::binary::Range& range() const { + return range_; + } + uint64_t target() const { + return ::flatbuffers::EndianScalar(target_); + } +}; + +FLATBUFFERS_STRUCT_END(Occurrence, 16); + +FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Relation FLATBUFFERS_FINAL_CLASS { +private: + uint32_t kind_; + uint32_t padding_; + clice::index::binary::Range range_; + uint64_t target_symbol_; + +public: + Relation() : kind_(0), padding_(0), range_(), target_symbol_(0) {} + Relation(uint32_t _kind, + uint32_t _padding, + const clice::index::binary::Range& _range, + uint64_t _target_symbol) : + kind_(::flatbuffers::EndianScalar(_kind)), padding_(::flatbuffers::EndianScalar(_padding)), + range_(_range), target_symbol_(::flatbuffers::EndianScalar(_target_symbol)) {} + uint32_t kind() const { + return ::flatbuffers::EndianScalar(kind_); + } + uint32_t padding() const { + return ::flatbuffers::EndianScalar(padding_); + } + const clice::index::binary::Range& range() const { + return range_; + } + uint64_t target_symbol() const { + return ::flatbuffers::EndianScalar(target_symbol_); + } +}; + +FLATBUFFERS_STRUCT_END(Relation, 24); + +FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) IncludeContext FLATBUFFERS_FINAL_CLASS { +private: + uint32_t include_id_; + uint32_t canonical_id_; + +public: + IncludeContext() : include_id_(0), canonical_id_(0) {} + IncludeContext(uint32_t _include_id, uint32_t _canonical_id) : + include_id_(::flatbuffers::EndianScalar(_include_id)), + canonical_id_(::flatbuffers::EndianScalar(_canonical_id)) {} + uint32_t include_id() const { + return ::flatbuffers::EndianScalar(include_id_); + } + uint32_t canonical_id() const { + return ::flatbuffers::EndianScalar(canonical_id_); + } +}; + +FLATBUFFERS_STRUCT_END(IncludeContext, 8); + +FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) IncludeLocation FLATBUFFERS_FINAL_CLASS { +private: + uint32_t path_id_; + uint32_t line_; + uint32_t include_id_; + +public: + IncludeLocation() : path_id_(0), line_(0), include_id_(0) {} + IncludeLocation(uint32_t _path_id, uint32_t _line, uint32_t _include_id) : + path_id_(::flatbuffers::EndianScalar(_path_id)), line_(::flatbuffers::EndianScalar(_line)), + include_id_(::flatbuffers::EndianScalar(_include_id)) {} + uint32_t path_id() const { + return ::flatbuffers::EndianScalar(path_id_); + } + uint32_t line() const { + return ::flatbuffers::EndianScalar(line_); + } + uint32_t include_id() const { + return ::flatbuffers::EndianScalar(include_id_); + } +}; + +FLATBUFFERS_STRUCT_END(IncludeLocation, 12); + +FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) PathMapEntry FLATBUFFERS_FINAL_CLASS { +private: + uint32_t source_; + uint32_t index_; + +public: + PathMapEntry() : source_(0), index_(0) {} + PathMapEntry(uint32_t _source, uint32_t _index) : + source_(::flatbuffers::EndianScalar(_source)), index_(::flatbuffers::EndianScalar(_index)) { + } + uint32_t source() const { + return ::flatbuffers::EndianScalar(source_); + } + uint32_t index() const { + return ::flatbuffers::EndianScalar(index_); + } +}; + +FLATBUFFERS_STRUCT_END(PathMapEntry, 8); + +struct CacheEntry FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef CacheEntryBuilder Builder; + + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SHA256 = 4, + VT_CANONICAL_ID = 6 + }; + + const ::flatbuffers::String* sha256() const { + return GetPointer(VT_SHA256); + } + + uint32_t canonical_id() const { + return GetField(VT_CANONICAL_ID, 0); + } + + bool Verify(::flatbuffers::Verifier& verifier) const { + return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_SHA256) && + verifier.VerifyString(sha256()) && + VerifyField(verifier, VT_CANONICAL_ID, 4) && verifier.EndTable(); + } +}; + +struct CacheEntryBuilder { + typedef CacheEntry Table; + ::flatbuffers::FlatBufferBuilder& fbb_; + ::flatbuffers::uoffset_t start_; + + void add_sha256(::flatbuffers::Offset<::flatbuffers::String> sha256) { + fbb_.AddOffset(CacheEntry::VT_SHA256, sha256); + } + + void add_canonical_id(uint32_t canonical_id) { + fbb_.AddElement(CacheEntry::VT_CANONICAL_ID, canonical_id, 0); + } + + explicit CacheEntryBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset + CreateCacheEntry(::flatbuffers::FlatBufferBuilder& _fbb, + ::flatbuffers::Offset<::flatbuffers::String> sha256 = 0, + uint32_t canonical_id = 0) { + CacheEntryBuilder builder_(_fbb); + builder_.add_canonical_id(canonical_id); + builder_.add_sha256(sha256); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset + CreateCacheEntryDirect(::flatbuffers::FlatBufferBuilder& _fbb, + const char* sha256 = nullptr, + uint32_t canonical_id = 0) { + auto sha256__ = sha256 ? _fbb.CreateString(sha256) : 0; + return clice::index::binary::CreateCacheEntry(_fbb, sha256__, canonical_id); +} + +struct HeaderContextEntry FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef HeaderContextEntryBuilder Builder; + + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_PATH_ID = 4, + VT_VERSION = 6, + VT_INCLUDES = 8 + }; + + uint32_t path_id() const { + return GetField(VT_PATH_ID, 0); + } + + uint32_t version() const { + return GetField(VT_VERSION, 0); + } + + const ::flatbuffers::Vector* includes() const { + return GetPointer< + const ::flatbuffers::Vector*>(VT_INCLUDES); + } + + bool Verify(::flatbuffers::Verifier& verifier) const { + return VerifyTableStart(verifier) && VerifyField(verifier, VT_PATH_ID, 4) && + VerifyField(verifier, VT_VERSION, 4) && + VerifyOffset(verifier, VT_INCLUDES) && verifier.VerifyVector(includes()) && + verifier.EndTable(); + } +}; + +struct HeaderContextEntryBuilder { + typedef HeaderContextEntry Table; + ::flatbuffers::FlatBufferBuilder& fbb_; + ::flatbuffers::uoffset_t start_; + + void add_path_id(uint32_t path_id) { + fbb_.AddElement(HeaderContextEntry::VT_PATH_ID, path_id, 0); + } + + void add_version(uint32_t version) { + fbb_.AddElement(HeaderContextEntry::VT_VERSION, version, 0); + } + + void add_includes( + ::flatbuffers::Offset<::flatbuffers::Vector> + includes) { + fbb_.AddOffset(HeaderContextEntry::VT_INCLUDES, includes); + } + + explicit HeaderContextEntryBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateHeaderContextEntry( + ::flatbuffers::FlatBufferBuilder& _fbb, + uint32_t path_id = 0, + uint32_t version = 0, + ::flatbuffers::Offset<::flatbuffers::Vector> + includes = 0) { + HeaderContextEntryBuilder builder_(_fbb); + builder_.add_includes(includes); + builder_.add_version(version); + builder_.add_path_id(path_id); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset CreateHeaderContextEntryDirect( + ::flatbuffers::FlatBufferBuilder& _fbb, + uint32_t path_id = 0, + uint32_t version = 0, + const std::vector* includes = nullptr) { + auto includes__ = + includes ? _fbb.CreateVectorOfStructs(*includes) : 0; + return clice::index::binary::CreateHeaderContextEntry(_fbb, path_id, version, includes__); +} + +struct CompilationContextEntry FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef CompilationContextEntryBuilder Builder; + + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_PATH_ID = 4, + VT_VERSION = 6, + VT_CANONICAL_ID = 8, + VT_BUILD_AT = 10, + VT_INCLUDE_LOCATIONS = 12 + }; + + uint32_t path_id() const { + return GetField(VT_PATH_ID, 0); + } + + uint32_t version() const { + return GetField(VT_VERSION, 0); + } + + uint32_t canonical_id() const { + return GetField(VT_CANONICAL_ID, 0); + } + + uint64_t build_at() const { + return GetField(VT_BUILD_AT, 0); + } + + const ::flatbuffers::Vector* + include_locations() const { + return GetPointer< + const ::flatbuffers::Vector*>( + VT_INCLUDE_LOCATIONS); + } + + bool Verify(::flatbuffers::Verifier& verifier) const { + return VerifyTableStart(verifier) && VerifyField(verifier, VT_PATH_ID, 4) && + VerifyField(verifier, VT_VERSION, 4) && + VerifyField(verifier, VT_CANONICAL_ID, 4) && + VerifyField(verifier, VT_BUILD_AT, 8) && + VerifyOffset(verifier, VT_INCLUDE_LOCATIONS) && + verifier.VerifyVector(include_locations()) && verifier.EndTable(); + } +}; + +struct CompilationContextEntryBuilder { + typedef CompilationContextEntry Table; + ::flatbuffers::FlatBufferBuilder& fbb_; + ::flatbuffers::uoffset_t start_; + + void add_path_id(uint32_t path_id) { + fbb_.AddElement(CompilationContextEntry::VT_PATH_ID, path_id, 0); + } + + void add_version(uint32_t version) { + fbb_.AddElement(CompilationContextEntry::VT_VERSION, version, 0); + } + + void add_canonical_id(uint32_t canonical_id) { + fbb_.AddElement(CompilationContextEntry::VT_CANONICAL_ID, canonical_id, 0); + } + + void add_build_at(uint64_t build_at) { + fbb_.AddElement(CompilationContextEntry::VT_BUILD_AT, build_at, 0); + } + + void add_include_locations( + ::flatbuffers::Offset<::flatbuffers::Vector> + include_locations) { + fbb_.AddOffset(CompilationContextEntry::VT_INCLUDE_LOCATIONS, include_locations); + } + + explicit CompilationContextEntryBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateCompilationContextEntry( + ::flatbuffers::FlatBufferBuilder& _fbb, + uint32_t path_id = 0, + uint32_t version = 0, + uint32_t canonical_id = 0, + uint64_t build_at = 0, + ::flatbuffers::Offset<::flatbuffers::Vector> + include_locations = 0) { + CompilationContextEntryBuilder builder_(_fbb); + builder_.add_build_at(build_at); + builder_.add_include_locations(include_locations); + builder_.add_canonical_id(canonical_id); + builder_.add_version(version); + builder_.add_path_id(path_id); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset CreateCompilationContextEntryDirect( + ::flatbuffers::FlatBufferBuilder& _fbb, + uint32_t path_id = 0, + uint32_t version = 0, + uint32_t canonical_id = 0, + uint64_t build_at = 0, + const std::vector* include_locations = nullptr) { + auto include_locations__ = + include_locations + ? _fbb.CreateVectorOfStructs(*include_locations) + : 0; + return clice::index::binary::CreateCompilationContextEntry(_fbb, + path_id, + version, + canonical_id, + build_at, + include_locations__); +} + +struct OccurrenceEntry FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef OccurrenceEntryBuilder Builder; + + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_OCCURRENCE = 4, + VT_CONTEXT = 6 + }; + + const clice::index::binary::Occurrence* occurrence() const { + return GetStruct(VT_OCCURRENCE); + } + + const ::flatbuffers::Vector* context() const { + return GetPointer*>(VT_CONTEXT); + } + + bool Verify(::flatbuffers::Verifier& verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_OCCURRENCE, 8) && + VerifyOffset(verifier, VT_CONTEXT) && verifier.VerifyVector(context()) && + verifier.EndTable(); + } +}; + +struct OccurrenceEntryBuilder { + typedef OccurrenceEntry Table; + ::flatbuffers::FlatBufferBuilder& fbb_; + ::flatbuffers::uoffset_t start_; + + void add_occurrence(const clice::index::binary::Occurrence* occurrence) { + fbb_.AddStruct(OccurrenceEntry::VT_OCCURRENCE, occurrence); + } + + void add_context(::flatbuffers::Offset<::flatbuffers::Vector> context) { + fbb_.AddOffset(OccurrenceEntry::VT_CONTEXT, context); + } + + explicit OccurrenceEntryBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset + CreateOccurrenceEntry(::flatbuffers::FlatBufferBuilder& _fbb, + const clice::index::binary::Occurrence* occurrence = nullptr, + ::flatbuffers::Offset<::flatbuffers::Vector> context = 0) { + OccurrenceEntryBuilder builder_(_fbb); + builder_.add_context(context); + builder_.add_occurrence(occurrence); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset + CreateOccurrenceEntryDirect(::flatbuffers::FlatBufferBuilder& _fbb, + const clice::index::binary::Occurrence* occurrence = nullptr, + const std::vector* context = nullptr) { + auto context__ = context ? _fbb.CreateVector(*context) : 0; + return clice::index::binary::CreateOccurrenceEntry(_fbb, occurrence, context__); +} + +struct RelationEntry FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef RelationEntryBuilder Builder; + + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_RELATION = 4, + VT_CONTEXT = 6 + }; + + const clice::index::binary::Relation* relation() const { + return GetStruct(VT_RELATION); + } + + const ::flatbuffers::Vector* context() const { + return GetPointer*>(VT_CONTEXT); + } + + bool Verify(::flatbuffers::Verifier& verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_RELATION, 8) && + VerifyOffset(verifier, VT_CONTEXT) && verifier.VerifyVector(context()) && + verifier.EndTable(); + } +}; + +struct RelationEntryBuilder { + typedef RelationEntry Table; + ::flatbuffers::FlatBufferBuilder& fbb_; + ::flatbuffers::uoffset_t start_; + + void add_relation(const clice::index::binary::Relation* relation) { + fbb_.AddStruct(RelationEntry::VT_RELATION, relation); + } + + void add_context(::flatbuffers::Offset<::flatbuffers::Vector> context) { + fbb_.AddOffset(RelationEntry::VT_CONTEXT, context); + } + + explicit RelationEntryBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset + CreateRelationEntry(::flatbuffers::FlatBufferBuilder& _fbb, + const clice::index::binary::Relation* relation = nullptr, + ::flatbuffers::Offset<::flatbuffers::Vector> context = 0) { + RelationEntryBuilder builder_(_fbb); + builder_.add_context(context); + builder_.add_relation(relation); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset + CreateRelationEntryDirect(::flatbuffers::FlatBufferBuilder& _fbb, + const clice::index::binary::Relation* relation = nullptr, + const std::vector* context = nullptr) { + auto context__ = context ? _fbb.CreateVector(*context) : 0; + return clice::index::binary::CreateRelationEntry(_fbb, relation, context__); +} + +struct SymbolRelationsEntry FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef SymbolRelationsEntryBuilder Builder; + + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SYMBOL = 4, + VT_RELATIONS = 6 + }; + + uint64_t symbol() const { + return GetField(VT_SYMBOL, 0); + } + + const ::flatbuffers::Vector<::flatbuffers::Offset>* + relations() const { + return GetPointer>*>(VT_RELATIONS); + } + + bool Verify(::flatbuffers::Verifier& verifier) const { + return VerifyTableStart(verifier) && VerifyField(verifier, VT_SYMBOL, 8) && + VerifyOffset(verifier, VT_RELATIONS) && verifier.VerifyVector(relations()) && + verifier.VerifyVectorOfTables(relations()) && verifier.EndTable(); + } +}; + +struct SymbolRelationsEntryBuilder { + typedef SymbolRelationsEntry Table; + ::flatbuffers::FlatBufferBuilder& fbb_; + ::flatbuffers::uoffset_t start_; + + void add_symbol(uint64_t symbol) { + fbb_.AddElement(SymbolRelationsEntry::VT_SYMBOL, symbol, 0); + } + + void add_relations(::flatbuffers::Offset<::flatbuffers::Vector< + ::flatbuffers::Offset>> relations) { + fbb_.AddOffset(SymbolRelationsEntry::VT_RELATIONS, relations); + } + + explicit SymbolRelationsEntryBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateSymbolRelationsEntry( + ::flatbuffers::FlatBufferBuilder& _fbb, + uint64_t symbol = 0, + ::flatbuffers::Offset<::flatbuffers::Vector< + ::flatbuffers::Offset>> relations = 0) { + SymbolRelationsEntryBuilder builder_(_fbb); + builder_.add_symbol(symbol); + builder_.add_relations(relations); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset CreateSymbolRelationsEntryDirect( + ::flatbuffers::FlatBufferBuilder& _fbb, + uint64_t symbol = 0, + const std::vector<::flatbuffers::Offset>* relations = + nullptr) { + auto relations__ = + relations ? _fbb.CreateVector<::flatbuffers::Offset>( + *relations) + : 0; + return clice::index::binary::CreateSymbolRelationsEntry(_fbb, symbol, relations__); +} + +struct Symbol FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef SymbolBuilder Builder; + + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_NAME = 4, + VT_KIND = 6, + VT_REFS = 8 + }; + + const ::flatbuffers::String* name() const { + return GetPointer(VT_NAME); + } + + uint8_t kind() const { + return GetField(VT_KIND, 0); + } + + const ::flatbuffers::Vector* refs() const { + return GetPointer*>(VT_REFS); + } + + bool Verify(::flatbuffers::Verifier& verifier) const { + return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_NAME) && + verifier.VerifyString(name()) && VerifyField(verifier, VT_KIND, 1) && + VerifyOffset(verifier, VT_REFS) && verifier.VerifyVector(refs()) && + verifier.EndTable(); + } +}; + +struct SymbolBuilder { + typedef Symbol Table; + ::flatbuffers::FlatBufferBuilder& fbb_; + ::flatbuffers::uoffset_t start_; + + void add_name(::flatbuffers::Offset<::flatbuffers::String> name) { + fbb_.AddOffset(Symbol::VT_NAME, name); + } + + void add_kind(uint8_t kind) { + fbb_.AddElement(Symbol::VT_KIND, kind, 0); + } + + void add_refs(::flatbuffers::Offset<::flatbuffers::Vector> refs) { + fbb_.AddOffset(Symbol::VT_REFS, refs); + } + + explicit SymbolBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset + CreateSymbol(::flatbuffers::FlatBufferBuilder& _fbb, + ::flatbuffers::Offset<::flatbuffers::String> name = 0, + uint8_t kind = 0, + ::flatbuffers::Offset<::flatbuffers::Vector> refs = 0) { + SymbolBuilder builder_(_fbb); + builder_.add_refs(refs); + builder_.add_name(name); + builder_.add_kind(kind); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset + CreateSymbolDirect(::flatbuffers::FlatBufferBuilder& _fbb, + const char* name = nullptr, + uint8_t kind = 0, + const std::vector* refs = nullptr) { + auto name__ = name ? _fbb.CreateString(name) : 0; + auto refs__ = refs ? _fbb.CreateVector(*refs) : 0; + return clice::index::binary::CreateSymbol(_fbb, name__, kind, refs__); +} + +struct SymbolEntry FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef SymbolEntryBuilder Builder; + + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SYMBOL_ID = 4, + VT_SYMBOL = 6 + }; + + uint64_t symbol_id() const { + return GetField(VT_SYMBOL_ID, 0); + } + + const clice::index::binary::Symbol* symbol() const { + return GetPointer(VT_SYMBOL); + } + + bool Verify(::flatbuffers::Verifier& verifier) const { + return VerifyTableStart(verifier) && VerifyField(verifier, VT_SYMBOL_ID, 8) && + VerifyOffset(verifier, VT_SYMBOL) && verifier.VerifyTable(symbol()) && + verifier.EndTable(); + } +}; + +struct SymbolEntryBuilder { + typedef SymbolEntry Table; + ::flatbuffers::FlatBufferBuilder& fbb_; + ::flatbuffers::uoffset_t start_; + + void add_symbol_id(uint64_t symbol_id) { + fbb_.AddElement(SymbolEntry::VT_SYMBOL_ID, symbol_id, 0); + } + + void add_symbol(::flatbuffers::Offset symbol) { + fbb_.AddOffset(SymbolEntry::VT_SYMBOL, symbol); + } + + explicit SymbolEntryBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset + CreateSymbolEntry(::flatbuffers::FlatBufferBuilder& _fbb, + uint64_t symbol_id = 0, + ::flatbuffers::Offset symbol = 0) { + SymbolEntryBuilder builder_(_fbb); + builder_.add_symbol_id(symbol_id); + builder_.add_symbol(symbol); + return builder_.Finish(); +} + +struct MergedIndex FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef MergedIndexBuilder Builder; + + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_MAX_CANONICAL_ID = 4, + VT_CANONICAL_CACHE = 6, + VT_HEADER_CONTEXTS = 8, + VT_COMPILATION_CONTEXTS = 10, + VT_OCCURRENCES = 12, + VT_RELATIONS = 14, + VT_REMOVED = 16, + VT_CONTENT = 18, + VT_LINE_STARTS = 20 + }; + + uint32_t max_canonical_id() const { + return GetField(VT_MAX_CANONICAL_ID, 0); + } + + const ::flatbuffers::Vector<::flatbuffers::Offset>* + canonical_cache() const { + return GetPointer< + const ::flatbuffers::Vector<::flatbuffers::Offset>*>( + VT_CANONICAL_CACHE); + } + + const ::flatbuffers::Vector<::flatbuffers::Offset>* + header_contexts() const { + return GetPointer>*>(VT_HEADER_CONTEXTS); + } + + const ::flatbuffers::Vector< + ::flatbuffers::Offset>* + compilation_contexts() const { + return GetPointer>*>( + VT_COMPILATION_CONTEXTS); + } + + const ::flatbuffers::Vector<::flatbuffers::Offset>* + occurrences() const { + return GetPointer>*>(VT_OCCURRENCES); + } + + const ::flatbuffers::Vector<::flatbuffers::Offset>* + relations() const { + return GetPointer>*>(VT_RELATIONS); + } + + const ::flatbuffers::Vector* removed() const { + return GetPointer*>(VT_REMOVED); + } + + const ::flatbuffers::String* content() const { + return GetPointer(VT_CONTENT); + } + + const ::flatbuffers::Vector* line_starts() const { + return GetPointer*>(VT_LINE_STARTS); + } + + bool Verify(::flatbuffers::Verifier& verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_MAX_CANONICAL_ID, 4) && + VerifyOffset(verifier, VT_CANONICAL_CACHE) && + verifier.VerifyVector(canonical_cache()) && + verifier.VerifyVectorOfTables(canonical_cache()) && + VerifyOffset(verifier, VT_HEADER_CONTEXTS) && + verifier.VerifyVector(header_contexts()) && + verifier.VerifyVectorOfTables(header_contexts()) && + VerifyOffset(verifier, VT_COMPILATION_CONTEXTS) && + verifier.VerifyVector(compilation_contexts()) && + verifier.VerifyVectorOfTables(compilation_contexts()) && + VerifyOffset(verifier, VT_OCCURRENCES) && verifier.VerifyVector(occurrences()) && + verifier.VerifyVectorOfTables(occurrences()) && + VerifyOffset(verifier, VT_RELATIONS) && verifier.VerifyVector(relations()) && + verifier.VerifyVectorOfTables(relations()) && VerifyOffset(verifier, VT_REMOVED) && + verifier.VerifyVector(removed()) && VerifyOffset(verifier, VT_CONTENT) && + verifier.VerifyString(content()) && VerifyOffset(verifier, VT_LINE_STARTS) && + verifier.VerifyVector(line_starts()) && verifier.EndTable(); + } +}; + +struct MergedIndexBuilder { + typedef MergedIndex Table; + ::flatbuffers::FlatBufferBuilder& fbb_; + ::flatbuffers::uoffset_t start_; + + void add_max_canonical_id(uint32_t max_canonical_id) { + fbb_.AddElement(MergedIndex::VT_MAX_CANONICAL_ID, max_canonical_id, 0); + } + + void add_canonical_cache( + ::flatbuffers::Offset< + ::flatbuffers::Vector<::flatbuffers::Offset>> + canonical_cache) { + fbb_.AddOffset(MergedIndex::VT_CANONICAL_CACHE, canonical_cache); + } + + void add_header_contexts( + ::flatbuffers::Offset< + ::flatbuffers::Vector<::flatbuffers::Offset>> + header_contexts) { + fbb_.AddOffset(MergedIndex::VT_HEADER_CONTEXTS, header_contexts); + } + + void add_compilation_contexts( + ::flatbuffers::Offset<::flatbuffers::Vector< + ::flatbuffers::Offset>> + compilation_contexts) { + fbb_.AddOffset(MergedIndex::VT_COMPILATION_CONTEXTS, compilation_contexts); + } + + void add_occurrences( + ::flatbuffers::Offset< + ::flatbuffers::Vector<::flatbuffers::Offset>> + occurrences) { + fbb_.AddOffset(MergedIndex::VT_OCCURRENCES, occurrences); + } + + void add_relations( + ::flatbuffers::Offset<::flatbuffers::Vector< + ::flatbuffers::Offset>> relations) { + fbb_.AddOffset(MergedIndex::VT_RELATIONS, relations); + } + + void add_removed(::flatbuffers::Offset<::flatbuffers::Vector> removed) { + fbb_.AddOffset(MergedIndex::VT_REMOVED, removed); + } + + void add_content(::flatbuffers::Offset<::flatbuffers::String> content) { + fbb_.AddOffset(MergedIndex::VT_CONTENT, content); + } + + void add_line_starts(::flatbuffers::Offset<::flatbuffers::Vector> line_starts) { + fbb_.AddOffset(MergedIndex::VT_LINE_STARTS, line_starts); + } + + explicit MergedIndexBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateMergedIndex( + ::flatbuffers::FlatBufferBuilder& _fbb, + uint32_t max_canonical_id = 0, + ::flatbuffers::Offset<::flatbuffers::Vector< + ::flatbuffers::Offset>> canonical_cache = 0, + ::flatbuffers::Offset<::flatbuffers::Vector< + ::flatbuffers::Offset>> header_contexts = 0, + ::flatbuffers::Offset< + ::flatbuffers::Vector<::flatbuffers::Offset>> + compilation_contexts = 0, + ::flatbuffers::Offset<::flatbuffers::Vector< + ::flatbuffers::Offset>> occurrences = 0, + ::flatbuffers::Offset<::flatbuffers::Vector< + ::flatbuffers::Offset>> relations = 0, + ::flatbuffers::Offset<::flatbuffers::Vector> removed = 0, + ::flatbuffers::Offset<::flatbuffers::String> content = 0, + ::flatbuffers::Offset<::flatbuffers::Vector> line_starts = 0) { + MergedIndexBuilder builder_(_fbb); + builder_.add_line_starts(line_starts); + builder_.add_content(content); + builder_.add_removed(removed); + builder_.add_relations(relations); + builder_.add_occurrences(occurrences); + builder_.add_compilation_contexts(compilation_contexts); + builder_.add_header_contexts(header_contexts); + builder_.add_canonical_cache(canonical_cache); + builder_.add_max_canonical_id(max_canonical_id); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset CreateMergedIndexDirect( + ::flatbuffers::FlatBufferBuilder& _fbb, + uint32_t max_canonical_id = 0, + const std::vector<::flatbuffers::Offset>* canonical_cache = + nullptr, + const std::vector<::flatbuffers::Offset>* + header_contexts = nullptr, + const std::vector<::flatbuffers::Offset>* + compilation_contexts = nullptr, + const std::vector<::flatbuffers::Offset>* occurrences = + nullptr, + const std::vector<::flatbuffers::Offset>* + relations = nullptr, + const std::vector* removed = nullptr, + const char* content = nullptr, + const std::vector* line_starts = nullptr) { + auto canonical_cache__ = + canonical_cache + ? _fbb.CreateVector<::flatbuffers::Offset>( + *canonical_cache) + : 0; + auto header_contexts__ = + header_contexts + ? _fbb.CreateVector<::flatbuffers::Offset>( + *header_contexts) + : 0; + auto compilation_contexts__ = + compilation_contexts + ? _fbb.CreateVector< + ::flatbuffers::Offset>( + *compilation_contexts) + : 0; + auto occurrences__ = + occurrences + ? _fbb.CreateVector<::flatbuffers::Offset>( + *occurrences) + : 0; + auto relations__ = + relations + ? _fbb.CreateVector<::flatbuffers::Offset>( + *relations) + : 0; + auto removed__ = removed ? _fbb.CreateVector(*removed) : 0; + auto content__ = content ? _fbb.CreateString(content) : 0; + auto line_starts__ = line_starts ? _fbb.CreateVector(*line_starts) : 0; + return clice::index::binary::CreateMergedIndex(_fbb, + max_canonical_id, + canonical_cache__, + header_contexts__, + compilation_contexts__, + occurrences__, + relations__, + removed__, + content__, + line_starts__); +} + +struct TUFileRelationsEntry FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef TUFileRelationsEntryBuilder Builder; + + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SYMBOL = 4, + VT_RELATIONS = 6 + }; + + uint64_t symbol() const { + return GetField(VT_SYMBOL, 0); + } + + const ::flatbuffers::Vector* relations() const { + return GetPointer*>( + VT_RELATIONS); + } + + bool Verify(::flatbuffers::Verifier& verifier) const { + return VerifyTableStart(verifier) && VerifyField(verifier, VT_SYMBOL, 8) && + VerifyOffset(verifier, VT_RELATIONS) && verifier.VerifyVector(relations()) && + verifier.EndTable(); + } +}; + +struct TUFileRelationsEntryBuilder { + typedef TUFileRelationsEntry Table; + ::flatbuffers::FlatBufferBuilder& fbb_; + ::flatbuffers::uoffset_t start_; + + void add_symbol(uint64_t symbol) { + fbb_.AddElement(TUFileRelationsEntry::VT_SYMBOL, symbol, 0); + } + + void add_relations( + ::flatbuffers::Offset<::flatbuffers::Vector> + relations) { + fbb_.AddOffset(TUFileRelationsEntry::VT_RELATIONS, relations); + } + + explicit TUFileRelationsEntryBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateTUFileRelationsEntry( + ::flatbuffers::FlatBufferBuilder& _fbb, + uint64_t symbol = 0, + ::flatbuffers::Offset<::flatbuffers::Vector> relations = + 0) { + TUFileRelationsEntryBuilder builder_(_fbb); + builder_.add_symbol(symbol); + builder_.add_relations(relations); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset CreateTUFileRelationsEntryDirect( + ::flatbuffers::FlatBufferBuilder& _fbb, + uint64_t symbol = 0, + const std::vector* relations = nullptr) { + auto relations__ = + relations ? _fbb.CreateVectorOfStructs(*relations) : 0; + return clice::index::binary::CreateTUFileRelationsEntry(_fbb, symbol, relations__); +} + +struct TUFileIndexEntry FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef TUFileIndexEntryBuilder Builder; + + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_FILE_ID = 4, + VT_OCCURRENCES = 6, + VT_RELATIONS = 8 + }; + + uint32_t file_id() const { + return GetField(VT_FILE_ID, 0); + } + + const ::flatbuffers::Vector* occurrences() const { + return GetPointer*>( + VT_OCCURRENCES); + } + + const ::flatbuffers::Vector<::flatbuffers::Offset>* + relations() const { + return GetPointer>*>(VT_RELATIONS); + } + + bool Verify(::flatbuffers::Verifier& verifier) const { + return VerifyTableStart(verifier) && VerifyField(verifier, VT_FILE_ID, 4) && + VerifyOffset(verifier, VT_OCCURRENCES) && verifier.VerifyVector(occurrences()) && + VerifyOffset(verifier, VT_RELATIONS) && verifier.VerifyVector(relations()) && + verifier.VerifyVectorOfTables(relations()) && verifier.EndTable(); + } +}; + +struct TUFileIndexEntryBuilder { + typedef TUFileIndexEntry Table; + ::flatbuffers::FlatBufferBuilder& fbb_; + ::flatbuffers::uoffset_t start_; + + void add_file_id(uint32_t file_id) { + fbb_.AddElement(TUFileIndexEntry::VT_FILE_ID, file_id, 0); + } + + void add_occurrences( + ::flatbuffers::Offset<::flatbuffers::Vector> + occurrences) { + fbb_.AddOffset(TUFileIndexEntry::VT_OCCURRENCES, occurrences); + } + + void add_relations( + ::flatbuffers::Offset<::flatbuffers::Vector< + ::flatbuffers::Offset>> relations) { + fbb_.AddOffset(TUFileIndexEntry::VT_RELATIONS, relations); + } + + explicit TUFileIndexEntryBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateTUFileIndexEntry( + ::flatbuffers::FlatBufferBuilder& _fbb, + uint32_t file_id = 0, + ::flatbuffers::Offset<::flatbuffers::Vector> + occurrences = 0, + ::flatbuffers::Offset<::flatbuffers::Vector< + ::flatbuffers::Offset>> relations = 0) { + TUFileIndexEntryBuilder builder_(_fbb); + builder_.add_relations(relations); + builder_.add_occurrences(occurrences); + builder_.add_file_id(file_id); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset CreateTUFileIndexEntryDirect( + ::flatbuffers::FlatBufferBuilder& _fbb, + uint32_t file_id = 0, + const std::vector* occurrences = nullptr, + const std::vector<::flatbuffers::Offset>* + relations = nullptr) { + auto occurrences__ = + occurrences ? _fbb.CreateVectorOfStructs(*occurrences) + : 0; + auto relations__ = + relations + ? _fbb.CreateVector<::flatbuffers::Offset>( + *relations) + : 0; + return clice::index::binary::CreateTUFileIndexEntry(_fbb, file_id, occurrences__, relations__); +} + +struct TUIndex FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef TUIndexBuilder Builder; + + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_BUILT_AT = 4, + VT_PATHS = 6, + VT_LOCATIONS = 8, + VT_SYMBOLS = 10, + VT_FILE_INDICES = 12, + VT_MAIN_FILE_INDEX = 14 + }; + + uint64_t built_at() const { + return GetField(VT_BUILT_AT, 0); + } + + const ::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>* paths() const { + return GetPointer< + const ::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>*>(VT_PATHS); + } + + const ::flatbuffers::Vector* locations() const { + return GetPointer< + const ::flatbuffers::Vector*>( + VT_LOCATIONS); + } + + const ::flatbuffers::Vector<::flatbuffers::Offset>* + symbols() const { + return GetPointer< + const ::flatbuffers::Vector<::flatbuffers::Offset>*>( + VT_SYMBOLS); + } + + const ::flatbuffers::Vector<::flatbuffers::Offset>* + file_indices() const { + return GetPointer>*>(VT_FILE_INDICES); + } + + const clice::index::binary::TUFileIndexEntry* main_file_index() const { + return GetPointer(VT_MAIN_FILE_INDEX); + } + + bool Verify(::flatbuffers::Verifier& verifier) const { + return VerifyTableStart(verifier) && VerifyField(verifier, VT_BUILT_AT, 8) && + VerifyOffset(verifier, VT_PATHS) && verifier.VerifyVector(paths()) && + verifier.VerifyVectorOfStrings(paths()) && VerifyOffset(verifier, VT_LOCATIONS) && + verifier.VerifyVector(locations()) && VerifyOffset(verifier, VT_SYMBOLS) && + verifier.VerifyVector(symbols()) && verifier.VerifyVectorOfTables(symbols()) && + VerifyOffset(verifier, VT_FILE_INDICES) && verifier.VerifyVector(file_indices()) && + verifier.VerifyVectorOfTables(file_indices()) && + VerifyOffset(verifier, VT_MAIN_FILE_INDEX) && + verifier.VerifyTable(main_file_index()) && verifier.EndTable(); + } +}; + +struct TUIndexBuilder { + typedef TUIndex Table; + ::flatbuffers::FlatBufferBuilder& fbb_; + ::flatbuffers::uoffset_t start_; + + void add_built_at(uint64_t built_at) { + fbb_.AddElement(TUIndex::VT_BUILT_AT, built_at, 0); + } + + void add_paths( + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> + paths) { + fbb_.AddOffset(TUIndex::VT_PATHS, paths); + } + + void add_locations( + ::flatbuffers::Offset<::flatbuffers::Vector> + locations) { + fbb_.AddOffset(TUIndex::VT_LOCATIONS, locations); + } + + void add_symbols(::flatbuffers::Offset<::flatbuffers::Vector< + ::flatbuffers::Offset>> symbols) { + fbb_.AddOffset(TUIndex::VT_SYMBOLS, symbols); + } + + void add_file_indices( + ::flatbuffers::Offset< + ::flatbuffers::Vector<::flatbuffers::Offset>> + file_indices) { + fbb_.AddOffset(TUIndex::VT_FILE_INDICES, file_indices); + } + + void add_main_file_index( + ::flatbuffers::Offset main_file_index) { + fbb_.AddOffset(TUIndex::VT_MAIN_FILE_INDEX, main_file_index); + } + + explicit TUIndexBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateTUIndex( + ::flatbuffers::FlatBufferBuilder& _fbb, + uint64_t built_at = 0, + ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> + paths = 0, + ::flatbuffers::Offset<::flatbuffers::Vector> + locations = 0, + ::flatbuffers::Offset< + ::flatbuffers::Vector<::flatbuffers::Offset>> symbols = + 0, + ::flatbuffers::Offset<::flatbuffers::Vector< + ::flatbuffers::Offset>> file_indices = 0, + ::flatbuffers::Offset main_file_index = 0) { + TUIndexBuilder builder_(_fbb); + builder_.add_built_at(built_at); + builder_.add_main_file_index(main_file_index); + builder_.add_file_indices(file_indices); + builder_.add_symbols(symbols); + builder_.add_locations(locations); + builder_.add_paths(paths); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset CreateTUIndexDirect( + ::flatbuffers::FlatBufferBuilder& _fbb, + uint64_t built_at = 0, + const std::vector<::flatbuffers::Offset<::flatbuffers::String>>* paths = nullptr, + const std::vector* locations = nullptr, + const std::vector<::flatbuffers::Offset>* symbols = nullptr, + const std::vector<::flatbuffers::Offset>* file_indices = + nullptr, + ::flatbuffers::Offset main_file_index = 0) { + auto paths__ = + paths ? _fbb.CreateVector<::flatbuffers::Offset<::flatbuffers::String>>(*paths) : 0; + auto locations__ = + locations ? _fbb.CreateVectorOfStructs(*locations) + : 0; + auto symbols__ = + symbols + ? _fbb.CreateVector<::flatbuffers::Offset>(*symbols) + : 0; + auto file_indices__ = + file_indices + ? _fbb.CreateVector<::flatbuffers::Offset>( + *file_indices) + : 0; + return clice::index::binary::CreateTUIndex(_fbb, + built_at, + paths__, + locations__, + symbols__, + file_indices__, + main_file_index); +} + +struct PathEntry FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef PathEntryBuilder Builder; + + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_PATH = 4, VT_ID = 6 }; + + const ::flatbuffers::String* path() const { + return GetPointer(VT_PATH); + } + + uint32_t id() const { + return GetField(VT_ID, 0); + } + + bool Verify(::flatbuffers::Verifier& verifier) const { + return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_PATH) && + verifier.VerifyString(path()) && VerifyField(verifier, VT_ID, 4) && + verifier.EndTable(); + } +}; + +struct PathEntryBuilder { + typedef PathEntry Table; + ::flatbuffers::FlatBufferBuilder& fbb_; + ::flatbuffers::uoffset_t start_; + + void add_path(::flatbuffers::Offset<::flatbuffers::String> path) { + fbb_.AddOffset(PathEntry::VT_PATH, path); + } + + void add_id(uint32_t id) { + fbb_.AddElement(PathEntry::VT_ID, id, 0); + } + + explicit PathEntryBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset + CreatePathEntry(::flatbuffers::FlatBufferBuilder& _fbb, + ::flatbuffers::Offset<::flatbuffers::String> path = 0, + uint32_t id = 0) { + PathEntryBuilder builder_(_fbb); + builder_.add_id(id); + builder_.add_path(path); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset + CreatePathEntryDirect(::flatbuffers::FlatBufferBuilder& _fbb, + const char* path = nullptr, + uint32_t id = 0) { + auto path__ = path ? _fbb.CreateString(path) : 0; + return clice::index::binary::CreatePathEntry(_fbb, path__, id); +} + +struct ProjectIndex FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { + typedef ProjectIndexBuilder Builder; + + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_PATHS = 4, + VT_INDICES = 6, + VT_SYMBOLS = 8 + }; + + const ::flatbuffers::Vector<::flatbuffers::Offset>* + paths() const { + return GetPointer< + const ::flatbuffers::Vector<::flatbuffers::Offset>*>( + VT_PATHS); + } + + const ::flatbuffers::Vector* indices() const { + return GetPointer*>( + VT_INDICES); + } + + const ::flatbuffers::Vector<::flatbuffers::Offset>* + symbols() const { + return GetPointer< + const ::flatbuffers::Vector<::flatbuffers::Offset>*>( + VT_SYMBOLS); + } + + bool Verify(::flatbuffers::Verifier& verifier) const { + return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_PATHS) && + verifier.VerifyVector(paths()) && verifier.VerifyVectorOfTables(paths()) && + VerifyOffset(verifier, VT_INDICES) && verifier.VerifyVector(indices()) && + VerifyOffset(verifier, VT_SYMBOLS) && verifier.VerifyVector(symbols()) && + verifier.VerifyVectorOfTables(symbols()) && verifier.EndTable(); + } +}; + +struct ProjectIndexBuilder { + typedef ProjectIndex Table; + ::flatbuffers::FlatBufferBuilder& fbb_; + ::flatbuffers::uoffset_t start_; + + void add_paths( + ::flatbuffers::Offset< + ::flatbuffers::Vector<::flatbuffers::Offset>> paths) { + fbb_.AddOffset(ProjectIndex::VT_PATHS, paths); + } + + void add_indices( + ::flatbuffers::Offset<::flatbuffers::Vector> + indices) { + fbb_.AddOffset(ProjectIndex::VT_INDICES, indices); + } + + void add_symbols(::flatbuffers::Offset<::flatbuffers::Vector< + ::flatbuffers::Offset>> symbols) { + fbb_.AddOffset(ProjectIndex::VT_SYMBOLS, symbols); + } + + explicit ProjectIndexBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + + ::flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = ::flatbuffers::Offset(end); + return o; + } +}; + +inline ::flatbuffers::Offset CreateProjectIndex( + ::flatbuffers::FlatBufferBuilder& _fbb, + ::flatbuffers::Offset< + ::flatbuffers::Vector<::flatbuffers::Offset>> paths = 0, + ::flatbuffers::Offset<::flatbuffers::Vector> + indices = 0, + ::flatbuffers::Offset< + ::flatbuffers::Vector<::flatbuffers::Offset>> symbols = + 0) { + ProjectIndexBuilder builder_(_fbb); + builder_.add_symbols(symbols); + builder_.add_indices(indices); + builder_.add_paths(paths); + return builder_.Finish(); +} + +inline ::flatbuffers::Offset CreateProjectIndexDirect( + ::flatbuffers::FlatBufferBuilder& _fbb, + const std::vector<::flatbuffers::Offset>* paths = nullptr, + const std::vector* indices = nullptr, + const std::vector<::flatbuffers::Offset>* symbols = + nullptr) { + auto paths__ = + paths ? _fbb.CreateVector<::flatbuffers::Offset>(*paths) + : 0; + auto indices__ = + indices ? _fbb.CreateVectorOfStructs(*indices) : 0; + auto symbols__ = + symbols + ? _fbb.CreateVector<::flatbuffers::Offset>(*symbols) + : 0; + return clice::index::binary::CreateProjectIndex(_fbb, paths__, indices__, symbols__); +} + +} // namespace binary +} // namespace index +} // namespace clice + +#endif // FLATBUFFERS_GENERATED_SCHEMA_CLICE_INDEX_BINARY_H_ From b8e68e7394323ae4dec1b65d4aa4bcb007a6c3af Mon Sep 17 00:00:00 2001 From: ykiko Date: Sat, 20 Jun 2026 17:03:14 +0800 Subject: [PATCH 8/8] chore: remove accidentally committed generated header --- src/index/schema_generated.h | 1547 ---------------------------------- 1 file changed, 1547 deletions(-) delete mode 100644 src/index/schema_generated.h diff --git a/src/index/schema_generated.h b/src/index/schema_generated.h deleted file mode 100644 index bec4a661..00000000 --- a/src/index/schema_generated.h +++ /dev/null @@ -1,1547 +0,0 @@ -// automatically generated by the FlatBuffers compiler, do not modify - -#ifndef FLATBUFFERS_GENERATED_SCHEMA_CLICE_INDEX_BINARY_H_ -#define FLATBUFFERS_GENERATED_SCHEMA_CLICE_INDEX_BINARY_H_ - -#include "flatbuffers/flatbuffers.h" - -// Ensure the included flatbuffers.h is the same version as when this file was -// generated, otherwise it may not be compatible. -static_assert(FLATBUFFERS_VERSION_MAJOR == 25 && FLATBUFFERS_VERSION_MINOR == 9 && - FLATBUFFERS_VERSION_REVISION == 23, - "Non-compatible flatbuffers version included"); - -namespace clice { -namespace index { -namespace binary { - -struct Range; - -struct Occurrence; - -struct Relation; - -struct CacheEntry; -struct CacheEntryBuilder; - -struct IncludeContext; - -struct HeaderContextEntry; -struct HeaderContextEntryBuilder; - -struct IncludeLocation; - -struct CompilationContextEntry; -struct CompilationContextEntryBuilder; - -struct OccurrenceEntry; -struct OccurrenceEntryBuilder; - -struct RelationEntry; -struct RelationEntryBuilder; - -struct SymbolRelationsEntry; -struct SymbolRelationsEntryBuilder; - -struct Symbol; -struct SymbolBuilder; - -struct SymbolEntry; -struct SymbolEntryBuilder; - -struct MergedIndex; -struct MergedIndexBuilder; - -struct TUFileRelationsEntry; -struct TUFileRelationsEntryBuilder; - -struct TUFileIndexEntry; -struct TUFileIndexEntryBuilder; - -struct TUIndex; -struct TUIndexBuilder; - -struct PathEntry; -struct PathEntryBuilder; - -struct PathMapEntry; - -struct ProjectIndex; -struct ProjectIndexBuilder; - -FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Range FLATBUFFERS_FINAL_CLASS { -private: - uint32_t begin_; - uint32_t end_; - -public: - Range() : begin_(0), end_(0) {} - Range(uint32_t _begin, uint32_t _end) : - begin_(::flatbuffers::EndianScalar(_begin)), end_(::flatbuffers::EndianScalar(_end)) {} - uint32_t begin() const { - return ::flatbuffers::EndianScalar(begin_); - } - uint32_t end() const { - return ::flatbuffers::EndianScalar(end_); - } -}; - -FLATBUFFERS_STRUCT_END(Range, 8); - -FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Occurrence FLATBUFFERS_FINAL_CLASS { -private: - clice::index::binary::Range range_; - uint64_t target_; - -public: - Occurrence() : range_(), target_(0) {} - Occurrence(const clice::index::binary::Range& _range, uint64_t _target) : - range_(_range), target_(::flatbuffers::EndianScalar(_target)) {} - const clice::index::binary::Range& range() const { - return range_; - } - uint64_t target() const { - return ::flatbuffers::EndianScalar(target_); - } -}; - -FLATBUFFERS_STRUCT_END(Occurrence, 16); - -FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(8) Relation FLATBUFFERS_FINAL_CLASS { -private: - uint32_t kind_; - uint32_t padding_; - clice::index::binary::Range range_; - uint64_t target_symbol_; - -public: - Relation() : kind_(0), padding_(0), range_(), target_symbol_(0) {} - Relation(uint32_t _kind, - uint32_t _padding, - const clice::index::binary::Range& _range, - uint64_t _target_symbol) : - kind_(::flatbuffers::EndianScalar(_kind)), padding_(::flatbuffers::EndianScalar(_padding)), - range_(_range), target_symbol_(::flatbuffers::EndianScalar(_target_symbol)) {} - uint32_t kind() const { - return ::flatbuffers::EndianScalar(kind_); - } - uint32_t padding() const { - return ::flatbuffers::EndianScalar(padding_); - } - const clice::index::binary::Range& range() const { - return range_; - } - uint64_t target_symbol() const { - return ::flatbuffers::EndianScalar(target_symbol_); - } -}; - -FLATBUFFERS_STRUCT_END(Relation, 24); - -FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) IncludeContext FLATBUFFERS_FINAL_CLASS { -private: - uint32_t include_id_; - uint32_t canonical_id_; - -public: - IncludeContext() : include_id_(0), canonical_id_(0) {} - IncludeContext(uint32_t _include_id, uint32_t _canonical_id) : - include_id_(::flatbuffers::EndianScalar(_include_id)), - canonical_id_(::flatbuffers::EndianScalar(_canonical_id)) {} - uint32_t include_id() const { - return ::flatbuffers::EndianScalar(include_id_); - } - uint32_t canonical_id() const { - return ::flatbuffers::EndianScalar(canonical_id_); - } -}; - -FLATBUFFERS_STRUCT_END(IncludeContext, 8); - -FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) IncludeLocation FLATBUFFERS_FINAL_CLASS { -private: - uint32_t path_id_; - uint32_t line_; - uint32_t include_id_; - -public: - IncludeLocation() : path_id_(0), line_(0), include_id_(0) {} - IncludeLocation(uint32_t _path_id, uint32_t _line, uint32_t _include_id) : - path_id_(::flatbuffers::EndianScalar(_path_id)), line_(::flatbuffers::EndianScalar(_line)), - include_id_(::flatbuffers::EndianScalar(_include_id)) {} - uint32_t path_id() const { - return ::flatbuffers::EndianScalar(path_id_); - } - uint32_t line() const { - return ::flatbuffers::EndianScalar(line_); - } - uint32_t include_id() const { - return ::flatbuffers::EndianScalar(include_id_); - } -}; - -FLATBUFFERS_STRUCT_END(IncludeLocation, 12); - -FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) PathMapEntry FLATBUFFERS_FINAL_CLASS { -private: - uint32_t source_; - uint32_t index_; - -public: - PathMapEntry() : source_(0), index_(0) {} - PathMapEntry(uint32_t _source, uint32_t _index) : - source_(::flatbuffers::EndianScalar(_source)), index_(::flatbuffers::EndianScalar(_index)) { - } - uint32_t source() const { - return ::flatbuffers::EndianScalar(source_); - } - uint32_t index() const { - return ::flatbuffers::EndianScalar(index_); - } -}; - -FLATBUFFERS_STRUCT_END(PathMapEntry, 8); - -struct CacheEntry FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef CacheEntryBuilder Builder; - - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_SHA256 = 4, - VT_CANONICAL_ID = 6 - }; - - const ::flatbuffers::String* sha256() const { - return GetPointer(VT_SHA256); - } - - uint32_t canonical_id() const { - return GetField(VT_CANONICAL_ID, 0); - } - - bool Verify(::flatbuffers::Verifier& verifier) const { - return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_SHA256) && - verifier.VerifyString(sha256()) && - VerifyField(verifier, VT_CANONICAL_ID, 4) && verifier.EndTable(); - } -}; - -struct CacheEntryBuilder { - typedef CacheEntry Table; - ::flatbuffers::FlatBufferBuilder& fbb_; - ::flatbuffers::uoffset_t start_; - - void add_sha256(::flatbuffers::Offset<::flatbuffers::String> sha256) { - fbb_.AddOffset(CacheEntry::VT_SHA256, sha256); - } - - void add_canonical_id(uint32_t canonical_id) { - fbb_.AddElement(CacheEntry::VT_CANONICAL_ID, canonical_id, 0); - } - - explicit CacheEntryBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - return o; - } -}; - -inline ::flatbuffers::Offset - CreateCacheEntry(::flatbuffers::FlatBufferBuilder& _fbb, - ::flatbuffers::Offset<::flatbuffers::String> sha256 = 0, - uint32_t canonical_id = 0) { - CacheEntryBuilder builder_(_fbb); - builder_.add_canonical_id(canonical_id); - builder_.add_sha256(sha256); - return builder_.Finish(); -} - -inline ::flatbuffers::Offset - CreateCacheEntryDirect(::flatbuffers::FlatBufferBuilder& _fbb, - const char* sha256 = nullptr, - uint32_t canonical_id = 0) { - auto sha256__ = sha256 ? _fbb.CreateString(sha256) : 0; - return clice::index::binary::CreateCacheEntry(_fbb, sha256__, canonical_id); -} - -struct HeaderContextEntry FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef HeaderContextEntryBuilder Builder; - - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_PATH_ID = 4, - VT_VERSION = 6, - VT_INCLUDES = 8 - }; - - uint32_t path_id() const { - return GetField(VT_PATH_ID, 0); - } - - uint32_t version() const { - return GetField(VT_VERSION, 0); - } - - const ::flatbuffers::Vector* includes() const { - return GetPointer< - const ::flatbuffers::Vector*>(VT_INCLUDES); - } - - bool Verify(::flatbuffers::Verifier& verifier) const { - return VerifyTableStart(verifier) && VerifyField(verifier, VT_PATH_ID, 4) && - VerifyField(verifier, VT_VERSION, 4) && - VerifyOffset(verifier, VT_INCLUDES) && verifier.VerifyVector(includes()) && - verifier.EndTable(); - } -}; - -struct HeaderContextEntryBuilder { - typedef HeaderContextEntry Table; - ::flatbuffers::FlatBufferBuilder& fbb_; - ::flatbuffers::uoffset_t start_; - - void add_path_id(uint32_t path_id) { - fbb_.AddElement(HeaderContextEntry::VT_PATH_ID, path_id, 0); - } - - void add_version(uint32_t version) { - fbb_.AddElement(HeaderContextEntry::VT_VERSION, version, 0); - } - - void add_includes( - ::flatbuffers::Offset<::flatbuffers::Vector> - includes) { - fbb_.AddOffset(HeaderContextEntry::VT_INCLUDES, includes); - } - - explicit HeaderContextEntryBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - return o; - } -}; - -inline ::flatbuffers::Offset CreateHeaderContextEntry( - ::flatbuffers::FlatBufferBuilder& _fbb, - uint32_t path_id = 0, - uint32_t version = 0, - ::flatbuffers::Offset<::flatbuffers::Vector> - includes = 0) { - HeaderContextEntryBuilder builder_(_fbb); - builder_.add_includes(includes); - builder_.add_version(version); - builder_.add_path_id(path_id); - return builder_.Finish(); -} - -inline ::flatbuffers::Offset CreateHeaderContextEntryDirect( - ::flatbuffers::FlatBufferBuilder& _fbb, - uint32_t path_id = 0, - uint32_t version = 0, - const std::vector* includes = nullptr) { - auto includes__ = - includes ? _fbb.CreateVectorOfStructs(*includes) : 0; - return clice::index::binary::CreateHeaderContextEntry(_fbb, path_id, version, includes__); -} - -struct CompilationContextEntry FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef CompilationContextEntryBuilder Builder; - - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_PATH_ID = 4, - VT_VERSION = 6, - VT_CANONICAL_ID = 8, - VT_BUILD_AT = 10, - VT_INCLUDE_LOCATIONS = 12 - }; - - uint32_t path_id() const { - return GetField(VT_PATH_ID, 0); - } - - uint32_t version() const { - return GetField(VT_VERSION, 0); - } - - uint32_t canonical_id() const { - return GetField(VT_CANONICAL_ID, 0); - } - - uint64_t build_at() const { - return GetField(VT_BUILD_AT, 0); - } - - const ::flatbuffers::Vector* - include_locations() const { - return GetPointer< - const ::flatbuffers::Vector*>( - VT_INCLUDE_LOCATIONS); - } - - bool Verify(::flatbuffers::Verifier& verifier) const { - return VerifyTableStart(verifier) && VerifyField(verifier, VT_PATH_ID, 4) && - VerifyField(verifier, VT_VERSION, 4) && - VerifyField(verifier, VT_CANONICAL_ID, 4) && - VerifyField(verifier, VT_BUILD_AT, 8) && - VerifyOffset(verifier, VT_INCLUDE_LOCATIONS) && - verifier.VerifyVector(include_locations()) && verifier.EndTable(); - } -}; - -struct CompilationContextEntryBuilder { - typedef CompilationContextEntry Table; - ::flatbuffers::FlatBufferBuilder& fbb_; - ::flatbuffers::uoffset_t start_; - - void add_path_id(uint32_t path_id) { - fbb_.AddElement(CompilationContextEntry::VT_PATH_ID, path_id, 0); - } - - void add_version(uint32_t version) { - fbb_.AddElement(CompilationContextEntry::VT_VERSION, version, 0); - } - - void add_canonical_id(uint32_t canonical_id) { - fbb_.AddElement(CompilationContextEntry::VT_CANONICAL_ID, canonical_id, 0); - } - - void add_build_at(uint64_t build_at) { - fbb_.AddElement(CompilationContextEntry::VT_BUILD_AT, build_at, 0); - } - - void add_include_locations( - ::flatbuffers::Offset<::flatbuffers::Vector> - include_locations) { - fbb_.AddOffset(CompilationContextEntry::VT_INCLUDE_LOCATIONS, include_locations); - } - - explicit CompilationContextEntryBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - return o; - } -}; - -inline ::flatbuffers::Offset CreateCompilationContextEntry( - ::flatbuffers::FlatBufferBuilder& _fbb, - uint32_t path_id = 0, - uint32_t version = 0, - uint32_t canonical_id = 0, - uint64_t build_at = 0, - ::flatbuffers::Offset<::flatbuffers::Vector> - include_locations = 0) { - CompilationContextEntryBuilder builder_(_fbb); - builder_.add_build_at(build_at); - builder_.add_include_locations(include_locations); - builder_.add_canonical_id(canonical_id); - builder_.add_version(version); - builder_.add_path_id(path_id); - return builder_.Finish(); -} - -inline ::flatbuffers::Offset CreateCompilationContextEntryDirect( - ::flatbuffers::FlatBufferBuilder& _fbb, - uint32_t path_id = 0, - uint32_t version = 0, - uint32_t canonical_id = 0, - uint64_t build_at = 0, - const std::vector* include_locations = nullptr) { - auto include_locations__ = - include_locations - ? _fbb.CreateVectorOfStructs(*include_locations) - : 0; - return clice::index::binary::CreateCompilationContextEntry(_fbb, - path_id, - version, - canonical_id, - build_at, - include_locations__); -} - -struct OccurrenceEntry FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef OccurrenceEntryBuilder Builder; - - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_OCCURRENCE = 4, - VT_CONTEXT = 6 - }; - - const clice::index::binary::Occurrence* occurrence() const { - return GetStruct(VT_OCCURRENCE); - } - - const ::flatbuffers::Vector* context() const { - return GetPointer*>(VT_CONTEXT); - } - - bool Verify(::flatbuffers::Verifier& verifier) const { - return VerifyTableStart(verifier) && - VerifyField(verifier, VT_OCCURRENCE, 8) && - VerifyOffset(verifier, VT_CONTEXT) && verifier.VerifyVector(context()) && - verifier.EndTable(); - } -}; - -struct OccurrenceEntryBuilder { - typedef OccurrenceEntry Table; - ::flatbuffers::FlatBufferBuilder& fbb_; - ::flatbuffers::uoffset_t start_; - - void add_occurrence(const clice::index::binary::Occurrence* occurrence) { - fbb_.AddStruct(OccurrenceEntry::VT_OCCURRENCE, occurrence); - } - - void add_context(::flatbuffers::Offset<::flatbuffers::Vector> context) { - fbb_.AddOffset(OccurrenceEntry::VT_CONTEXT, context); - } - - explicit OccurrenceEntryBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - return o; - } -}; - -inline ::flatbuffers::Offset - CreateOccurrenceEntry(::flatbuffers::FlatBufferBuilder& _fbb, - const clice::index::binary::Occurrence* occurrence = nullptr, - ::flatbuffers::Offset<::flatbuffers::Vector> context = 0) { - OccurrenceEntryBuilder builder_(_fbb); - builder_.add_context(context); - builder_.add_occurrence(occurrence); - return builder_.Finish(); -} - -inline ::flatbuffers::Offset - CreateOccurrenceEntryDirect(::flatbuffers::FlatBufferBuilder& _fbb, - const clice::index::binary::Occurrence* occurrence = nullptr, - const std::vector* context = nullptr) { - auto context__ = context ? _fbb.CreateVector(*context) : 0; - return clice::index::binary::CreateOccurrenceEntry(_fbb, occurrence, context__); -} - -struct RelationEntry FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef RelationEntryBuilder Builder; - - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_RELATION = 4, - VT_CONTEXT = 6 - }; - - const clice::index::binary::Relation* relation() const { - return GetStruct(VT_RELATION); - } - - const ::flatbuffers::Vector* context() const { - return GetPointer*>(VT_CONTEXT); - } - - bool Verify(::flatbuffers::Verifier& verifier) const { - return VerifyTableStart(verifier) && - VerifyField(verifier, VT_RELATION, 8) && - VerifyOffset(verifier, VT_CONTEXT) && verifier.VerifyVector(context()) && - verifier.EndTable(); - } -}; - -struct RelationEntryBuilder { - typedef RelationEntry Table; - ::flatbuffers::FlatBufferBuilder& fbb_; - ::flatbuffers::uoffset_t start_; - - void add_relation(const clice::index::binary::Relation* relation) { - fbb_.AddStruct(RelationEntry::VT_RELATION, relation); - } - - void add_context(::flatbuffers::Offset<::flatbuffers::Vector> context) { - fbb_.AddOffset(RelationEntry::VT_CONTEXT, context); - } - - explicit RelationEntryBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - return o; - } -}; - -inline ::flatbuffers::Offset - CreateRelationEntry(::flatbuffers::FlatBufferBuilder& _fbb, - const clice::index::binary::Relation* relation = nullptr, - ::flatbuffers::Offset<::flatbuffers::Vector> context = 0) { - RelationEntryBuilder builder_(_fbb); - builder_.add_context(context); - builder_.add_relation(relation); - return builder_.Finish(); -} - -inline ::flatbuffers::Offset - CreateRelationEntryDirect(::flatbuffers::FlatBufferBuilder& _fbb, - const clice::index::binary::Relation* relation = nullptr, - const std::vector* context = nullptr) { - auto context__ = context ? _fbb.CreateVector(*context) : 0; - return clice::index::binary::CreateRelationEntry(_fbb, relation, context__); -} - -struct SymbolRelationsEntry FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef SymbolRelationsEntryBuilder Builder; - - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_SYMBOL = 4, - VT_RELATIONS = 6 - }; - - uint64_t symbol() const { - return GetField(VT_SYMBOL, 0); - } - - const ::flatbuffers::Vector<::flatbuffers::Offset>* - relations() const { - return GetPointer>*>(VT_RELATIONS); - } - - bool Verify(::flatbuffers::Verifier& verifier) const { - return VerifyTableStart(verifier) && VerifyField(verifier, VT_SYMBOL, 8) && - VerifyOffset(verifier, VT_RELATIONS) && verifier.VerifyVector(relations()) && - verifier.VerifyVectorOfTables(relations()) && verifier.EndTable(); - } -}; - -struct SymbolRelationsEntryBuilder { - typedef SymbolRelationsEntry Table; - ::flatbuffers::FlatBufferBuilder& fbb_; - ::flatbuffers::uoffset_t start_; - - void add_symbol(uint64_t symbol) { - fbb_.AddElement(SymbolRelationsEntry::VT_SYMBOL, symbol, 0); - } - - void add_relations(::flatbuffers::Offset<::flatbuffers::Vector< - ::flatbuffers::Offset>> relations) { - fbb_.AddOffset(SymbolRelationsEntry::VT_RELATIONS, relations); - } - - explicit SymbolRelationsEntryBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - return o; - } -}; - -inline ::flatbuffers::Offset CreateSymbolRelationsEntry( - ::flatbuffers::FlatBufferBuilder& _fbb, - uint64_t symbol = 0, - ::flatbuffers::Offset<::flatbuffers::Vector< - ::flatbuffers::Offset>> relations = 0) { - SymbolRelationsEntryBuilder builder_(_fbb); - builder_.add_symbol(symbol); - builder_.add_relations(relations); - return builder_.Finish(); -} - -inline ::flatbuffers::Offset CreateSymbolRelationsEntryDirect( - ::flatbuffers::FlatBufferBuilder& _fbb, - uint64_t symbol = 0, - const std::vector<::flatbuffers::Offset>* relations = - nullptr) { - auto relations__ = - relations ? _fbb.CreateVector<::flatbuffers::Offset>( - *relations) - : 0; - return clice::index::binary::CreateSymbolRelationsEntry(_fbb, symbol, relations__); -} - -struct Symbol FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef SymbolBuilder Builder; - - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_NAME = 4, - VT_KIND = 6, - VT_REFS = 8 - }; - - const ::flatbuffers::String* name() const { - return GetPointer(VT_NAME); - } - - uint8_t kind() const { - return GetField(VT_KIND, 0); - } - - const ::flatbuffers::Vector* refs() const { - return GetPointer*>(VT_REFS); - } - - bool Verify(::flatbuffers::Verifier& verifier) const { - return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_NAME) && - verifier.VerifyString(name()) && VerifyField(verifier, VT_KIND, 1) && - VerifyOffset(verifier, VT_REFS) && verifier.VerifyVector(refs()) && - verifier.EndTable(); - } -}; - -struct SymbolBuilder { - typedef Symbol Table; - ::flatbuffers::FlatBufferBuilder& fbb_; - ::flatbuffers::uoffset_t start_; - - void add_name(::flatbuffers::Offset<::flatbuffers::String> name) { - fbb_.AddOffset(Symbol::VT_NAME, name); - } - - void add_kind(uint8_t kind) { - fbb_.AddElement(Symbol::VT_KIND, kind, 0); - } - - void add_refs(::flatbuffers::Offset<::flatbuffers::Vector> refs) { - fbb_.AddOffset(Symbol::VT_REFS, refs); - } - - explicit SymbolBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - return o; - } -}; - -inline ::flatbuffers::Offset - CreateSymbol(::flatbuffers::FlatBufferBuilder& _fbb, - ::flatbuffers::Offset<::flatbuffers::String> name = 0, - uint8_t kind = 0, - ::flatbuffers::Offset<::flatbuffers::Vector> refs = 0) { - SymbolBuilder builder_(_fbb); - builder_.add_refs(refs); - builder_.add_name(name); - builder_.add_kind(kind); - return builder_.Finish(); -} - -inline ::flatbuffers::Offset - CreateSymbolDirect(::flatbuffers::FlatBufferBuilder& _fbb, - const char* name = nullptr, - uint8_t kind = 0, - const std::vector* refs = nullptr) { - auto name__ = name ? _fbb.CreateString(name) : 0; - auto refs__ = refs ? _fbb.CreateVector(*refs) : 0; - return clice::index::binary::CreateSymbol(_fbb, name__, kind, refs__); -} - -struct SymbolEntry FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef SymbolEntryBuilder Builder; - - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_SYMBOL_ID = 4, - VT_SYMBOL = 6 - }; - - uint64_t symbol_id() const { - return GetField(VT_SYMBOL_ID, 0); - } - - const clice::index::binary::Symbol* symbol() const { - return GetPointer(VT_SYMBOL); - } - - bool Verify(::flatbuffers::Verifier& verifier) const { - return VerifyTableStart(verifier) && VerifyField(verifier, VT_SYMBOL_ID, 8) && - VerifyOffset(verifier, VT_SYMBOL) && verifier.VerifyTable(symbol()) && - verifier.EndTable(); - } -}; - -struct SymbolEntryBuilder { - typedef SymbolEntry Table; - ::flatbuffers::FlatBufferBuilder& fbb_; - ::flatbuffers::uoffset_t start_; - - void add_symbol_id(uint64_t symbol_id) { - fbb_.AddElement(SymbolEntry::VT_SYMBOL_ID, symbol_id, 0); - } - - void add_symbol(::flatbuffers::Offset symbol) { - fbb_.AddOffset(SymbolEntry::VT_SYMBOL, symbol); - } - - explicit SymbolEntryBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - return o; - } -}; - -inline ::flatbuffers::Offset - CreateSymbolEntry(::flatbuffers::FlatBufferBuilder& _fbb, - uint64_t symbol_id = 0, - ::flatbuffers::Offset symbol = 0) { - SymbolEntryBuilder builder_(_fbb); - builder_.add_symbol_id(symbol_id); - builder_.add_symbol(symbol); - return builder_.Finish(); -} - -struct MergedIndex FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef MergedIndexBuilder Builder; - - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_MAX_CANONICAL_ID = 4, - VT_CANONICAL_CACHE = 6, - VT_HEADER_CONTEXTS = 8, - VT_COMPILATION_CONTEXTS = 10, - VT_OCCURRENCES = 12, - VT_RELATIONS = 14, - VT_REMOVED = 16, - VT_CONTENT = 18, - VT_LINE_STARTS = 20 - }; - - uint32_t max_canonical_id() const { - return GetField(VT_MAX_CANONICAL_ID, 0); - } - - const ::flatbuffers::Vector<::flatbuffers::Offset>* - canonical_cache() const { - return GetPointer< - const ::flatbuffers::Vector<::flatbuffers::Offset>*>( - VT_CANONICAL_CACHE); - } - - const ::flatbuffers::Vector<::flatbuffers::Offset>* - header_contexts() const { - return GetPointer>*>(VT_HEADER_CONTEXTS); - } - - const ::flatbuffers::Vector< - ::flatbuffers::Offset>* - compilation_contexts() const { - return GetPointer>*>( - VT_COMPILATION_CONTEXTS); - } - - const ::flatbuffers::Vector<::flatbuffers::Offset>* - occurrences() const { - return GetPointer>*>(VT_OCCURRENCES); - } - - const ::flatbuffers::Vector<::flatbuffers::Offset>* - relations() const { - return GetPointer>*>(VT_RELATIONS); - } - - const ::flatbuffers::Vector* removed() const { - return GetPointer*>(VT_REMOVED); - } - - const ::flatbuffers::String* content() const { - return GetPointer(VT_CONTENT); - } - - const ::flatbuffers::Vector* line_starts() const { - return GetPointer*>(VT_LINE_STARTS); - } - - bool Verify(::flatbuffers::Verifier& verifier) const { - return VerifyTableStart(verifier) && - VerifyField(verifier, VT_MAX_CANONICAL_ID, 4) && - VerifyOffset(verifier, VT_CANONICAL_CACHE) && - verifier.VerifyVector(canonical_cache()) && - verifier.VerifyVectorOfTables(canonical_cache()) && - VerifyOffset(verifier, VT_HEADER_CONTEXTS) && - verifier.VerifyVector(header_contexts()) && - verifier.VerifyVectorOfTables(header_contexts()) && - VerifyOffset(verifier, VT_COMPILATION_CONTEXTS) && - verifier.VerifyVector(compilation_contexts()) && - verifier.VerifyVectorOfTables(compilation_contexts()) && - VerifyOffset(verifier, VT_OCCURRENCES) && verifier.VerifyVector(occurrences()) && - verifier.VerifyVectorOfTables(occurrences()) && - VerifyOffset(verifier, VT_RELATIONS) && verifier.VerifyVector(relations()) && - verifier.VerifyVectorOfTables(relations()) && VerifyOffset(verifier, VT_REMOVED) && - verifier.VerifyVector(removed()) && VerifyOffset(verifier, VT_CONTENT) && - verifier.VerifyString(content()) && VerifyOffset(verifier, VT_LINE_STARTS) && - verifier.VerifyVector(line_starts()) && verifier.EndTable(); - } -}; - -struct MergedIndexBuilder { - typedef MergedIndex Table; - ::flatbuffers::FlatBufferBuilder& fbb_; - ::flatbuffers::uoffset_t start_; - - void add_max_canonical_id(uint32_t max_canonical_id) { - fbb_.AddElement(MergedIndex::VT_MAX_CANONICAL_ID, max_canonical_id, 0); - } - - void add_canonical_cache( - ::flatbuffers::Offset< - ::flatbuffers::Vector<::flatbuffers::Offset>> - canonical_cache) { - fbb_.AddOffset(MergedIndex::VT_CANONICAL_CACHE, canonical_cache); - } - - void add_header_contexts( - ::flatbuffers::Offset< - ::flatbuffers::Vector<::flatbuffers::Offset>> - header_contexts) { - fbb_.AddOffset(MergedIndex::VT_HEADER_CONTEXTS, header_contexts); - } - - void add_compilation_contexts( - ::flatbuffers::Offset<::flatbuffers::Vector< - ::flatbuffers::Offset>> - compilation_contexts) { - fbb_.AddOffset(MergedIndex::VT_COMPILATION_CONTEXTS, compilation_contexts); - } - - void add_occurrences( - ::flatbuffers::Offset< - ::flatbuffers::Vector<::flatbuffers::Offset>> - occurrences) { - fbb_.AddOffset(MergedIndex::VT_OCCURRENCES, occurrences); - } - - void add_relations( - ::flatbuffers::Offset<::flatbuffers::Vector< - ::flatbuffers::Offset>> relations) { - fbb_.AddOffset(MergedIndex::VT_RELATIONS, relations); - } - - void add_removed(::flatbuffers::Offset<::flatbuffers::Vector> removed) { - fbb_.AddOffset(MergedIndex::VT_REMOVED, removed); - } - - void add_content(::flatbuffers::Offset<::flatbuffers::String> content) { - fbb_.AddOffset(MergedIndex::VT_CONTENT, content); - } - - void add_line_starts(::flatbuffers::Offset<::flatbuffers::Vector> line_starts) { - fbb_.AddOffset(MergedIndex::VT_LINE_STARTS, line_starts); - } - - explicit MergedIndexBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - return o; - } -}; - -inline ::flatbuffers::Offset CreateMergedIndex( - ::flatbuffers::FlatBufferBuilder& _fbb, - uint32_t max_canonical_id = 0, - ::flatbuffers::Offset<::flatbuffers::Vector< - ::flatbuffers::Offset>> canonical_cache = 0, - ::flatbuffers::Offset<::flatbuffers::Vector< - ::flatbuffers::Offset>> header_contexts = 0, - ::flatbuffers::Offset< - ::flatbuffers::Vector<::flatbuffers::Offset>> - compilation_contexts = 0, - ::flatbuffers::Offset<::flatbuffers::Vector< - ::flatbuffers::Offset>> occurrences = 0, - ::flatbuffers::Offset<::flatbuffers::Vector< - ::flatbuffers::Offset>> relations = 0, - ::flatbuffers::Offset<::flatbuffers::Vector> removed = 0, - ::flatbuffers::Offset<::flatbuffers::String> content = 0, - ::flatbuffers::Offset<::flatbuffers::Vector> line_starts = 0) { - MergedIndexBuilder builder_(_fbb); - builder_.add_line_starts(line_starts); - builder_.add_content(content); - builder_.add_removed(removed); - builder_.add_relations(relations); - builder_.add_occurrences(occurrences); - builder_.add_compilation_contexts(compilation_contexts); - builder_.add_header_contexts(header_contexts); - builder_.add_canonical_cache(canonical_cache); - builder_.add_max_canonical_id(max_canonical_id); - return builder_.Finish(); -} - -inline ::flatbuffers::Offset CreateMergedIndexDirect( - ::flatbuffers::FlatBufferBuilder& _fbb, - uint32_t max_canonical_id = 0, - const std::vector<::flatbuffers::Offset>* canonical_cache = - nullptr, - const std::vector<::flatbuffers::Offset>* - header_contexts = nullptr, - const std::vector<::flatbuffers::Offset>* - compilation_contexts = nullptr, - const std::vector<::flatbuffers::Offset>* occurrences = - nullptr, - const std::vector<::flatbuffers::Offset>* - relations = nullptr, - const std::vector* removed = nullptr, - const char* content = nullptr, - const std::vector* line_starts = nullptr) { - auto canonical_cache__ = - canonical_cache - ? _fbb.CreateVector<::flatbuffers::Offset>( - *canonical_cache) - : 0; - auto header_contexts__ = - header_contexts - ? _fbb.CreateVector<::flatbuffers::Offset>( - *header_contexts) - : 0; - auto compilation_contexts__ = - compilation_contexts - ? _fbb.CreateVector< - ::flatbuffers::Offset>( - *compilation_contexts) - : 0; - auto occurrences__ = - occurrences - ? _fbb.CreateVector<::flatbuffers::Offset>( - *occurrences) - : 0; - auto relations__ = - relations - ? _fbb.CreateVector<::flatbuffers::Offset>( - *relations) - : 0; - auto removed__ = removed ? _fbb.CreateVector(*removed) : 0; - auto content__ = content ? _fbb.CreateString(content) : 0; - auto line_starts__ = line_starts ? _fbb.CreateVector(*line_starts) : 0; - return clice::index::binary::CreateMergedIndex(_fbb, - max_canonical_id, - canonical_cache__, - header_contexts__, - compilation_contexts__, - occurrences__, - relations__, - removed__, - content__, - line_starts__); -} - -struct TUFileRelationsEntry FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef TUFileRelationsEntryBuilder Builder; - - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_SYMBOL = 4, - VT_RELATIONS = 6 - }; - - uint64_t symbol() const { - return GetField(VT_SYMBOL, 0); - } - - const ::flatbuffers::Vector* relations() const { - return GetPointer*>( - VT_RELATIONS); - } - - bool Verify(::flatbuffers::Verifier& verifier) const { - return VerifyTableStart(verifier) && VerifyField(verifier, VT_SYMBOL, 8) && - VerifyOffset(verifier, VT_RELATIONS) && verifier.VerifyVector(relations()) && - verifier.EndTable(); - } -}; - -struct TUFileRelationsEntryBuilder { - typedef TUFileRelationsEntry Table; - ::flatbuffers::FlatBufferBuilder& fbb_; - ::flatbuffers::uoffset_t start_; - - void add_symbol(uint64_t symbol) { - fbb_.AddElement(TUFileRelationsEntry::VT_SYMBOL, symbol, 0); - } - - void add_relations( - ::flatbuffers::Offset<::flatbuffers::Vector> - relations) { - fbb_.AddOffset(TUFileRelationsEntry::VT_RELATIONS, relations); - } - - explicit TUFileRelationsEntryBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - return o; - } -}; - -inline ::flatbuffers::Offset CreateTUFileRelationsEntry( - ::flatbuffers::FlatBufferBuilder& _fbb, - uint64_t symbol = 0, - ::flatbuffers::Offset<::flatbuffers::Vector> relations = - 0) { - TUFileRelationsEntryBuilder builder_(_fbb); - builder_.add_symbol(symbol); - builder_.add_relations(relations); - return builder_.Finish(); -} - -inline ::flatbuffers::Offset CreateTUFileRelationsEntryDirect( - ::flatbuffers::FlatBufferBuilder& _fbb, - uint64_t symbol = 0, - const std::vector* relations = nullptr) { - auto relations__ = - relations ? _fbb.CreateVectorOfStructs(*relations) : 0; - return clice::index::binary::CreateTUFileRelationsEntry(_fbb, symbol, relations__); -} - -struct TUFileIndexEntry FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef TUFileIndexEntryBuilder Builder; - - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_FILE_ID = 4, - VT_OCCURRENCES = 6, - VT_RELATIONS = 8 - }; - - uint32_t file_id() const { - return GetField(VT_FILE_ID, 0); - } - - const ::flatbuffers::Vector* occurrences() const { - return GetPointer*>( - VT_OCCURRENCES); - } - - const ::flatbuffers::Vector<::flatbuffers::Offset>* - relations() const { - return GetPointer>*>(VT_RELATIONS); - } - - bool Verify(::flatbuffers::Verifier& verifier) const { - return VerifyTableStart(verifier) && VerifyField(verifier, VT_FILE_ID, 4) && - VerifyOffset(verifier, VT_OCCURRENCES) && verifier.VerifyVector(occurrences()) && - VerifyOffset(verifier, VT_RELATIONS) && verifier.VerifyVector(relations()) && - verifier.VerifyVectorOfTables(relations()) && verifier.EndTable(); - } -}; - -struct TUFileIndexEntryBuilder { - typedef TUFileIndexEntry Table; - ::flatbuffers::FlatBufferBuilder& fbb_; - ::flatbuffers::uoffset_t start_; - - void add_file_id(uint32_t file_id) { - fbb_.AddElement(TUFileIndexEntry::VT_FILE_ID, file_id, 0); - } - - void add_occurrences( - ::flatbuffers::Offset<::flatbuffers::Vector> - occurrences) { - fbb_.AddOffset(TUFileIndexEntry::VT_OCCURRENCES, occurrences); - } - - void add_relations( - ::flatbuffers::Offset<::flatbuffers::Vector< - ::flatbuffers::Offset>> relations) { - fbb_.AddOffset(TUFileIndexEntry::VT_RELATIONS, relations); - } - - explicit TUFileIndexEntryBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - return o; - } -}; - -inline ::flatbuffers::Offset CreateTUFileIndexEntry( - ::flatbuffers::FlatBufferBuilder& _fbb, - uint32_t file_id = 0, - ::flatbuffers::Offset<::flatbuffers::Vector> - occurrences = 0, - ::flatbuffers::Offset<::flatbuffers::Vector< - ::flatbuffers::Offset>> relations = 0) { - TUFileIndexEntryBuilder builder_(_fbb); - builder_.add_relations(relations); - builder_.add_occurrences(occurrences); - builder_.add_file_id(file_id); - return builder_.Finish(); -} - -inline ::flatbuffers::Offset CreateTUFileIndexEntryDirect( - ::flatbuffers::FlatBufferBuilder& _fbb, - uint32_t file_id = 0, - const std::vector* occurrences = nullptr, - const std::vector<::flatbuffers::Offset>* - relations = nullptr) { - auto occurrences__ = - occurrences ? _fbb.CreateVectorOfStructs(*occurrences) - : 0; - auto relations__ = - relations - ? _fbb.CreateVector<::flatbuffers::Offset>( - *relations) - : 0; - return clice::index::binary::CreateTUFileIndexEntry(_fbb, file_id, occurrences__, relations__); -} - -struct TUIndex FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef TUIndexBuilder Builder; - - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_BUILT_AT = 4, - VT_PATHS = 6, - VT_LOCATIONS = 8, - VT_SYMBOLS = 10, - VT_FILE_INDICES = 12, - VT_MAIN_FILE_INDEX = 14 - }; - - uint64_t built_at() const { - return GetField(VT_BUILT_AT, 0); - } - - const ::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>* paths() const { - return GetPointer< - const ::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>*>(VT_PATHS); - } - - const ::flatbuffers::Vector* locations() const { - return GetPointer< - const ::flatbuffers::Vector*>( - VT_LOCATIONS); - } - - const ::flatbuffers::Vector<::flatbuffers::Offset>* - symbols() const { - return GetPointer< - const ::flatbuffers::Vector<::flatbuffers::Offset>*>( - VT_SYMBOLS); - } - - const ::flatbuffers::Vector<::flatbuffers::Offset>* - file_indices() const { - return GetPointer>*>(VT_FILE_INDICES); - } - - const clice::index::binary::TUFileIndexEntry* main_file_index() const { - return GetPointer(VT_MAIN_FILE_INDEX); - } - - bool Verify(::flatbuffers::Verifier& verifier) const { - return VerifyTableStart(verifier) && VerifyField(verifier, VT_BUILT_AT, 8) && - VerifyOffset(verifier, VT_PATHS) && verifier.VerifyVector(paths()) && - verifier.VerifyVectorOfStrings(paths()) && VerifyOffset(verifier, VT_LOCATIONS) && - verifier.VerifyVector(locations()) && VerifyOffset(verifier, VT_SYMBOLS) && - verifier.VerifyVector(symbols()) && verifier.VerifyVectorOfTables(symbols()) && - VerifyOffset(verifier, VT_FILE_INDICES) && verifier.VerifyVector(file_indices()) && - verifier.VerifyVectorOfTables(file_indices()) && - VerifyOffset(verifier, VT_MAIN_FILE_INDEX) && - verifier.VerifyTable(main_file_index()) && verifier.EndTable(); - } -}; - -struct TUIndexBuilder { - typedef TUIndex Table; - ::flatbuffers::FlatBufferBuilder& fbb_; - ::flatbuffers::uoffset_t start_; - - void add_built_at(uint64_t built_at) { - fbb_.AddElement(TUIndex::VT_BUILT_AT, built_at, 0); - } - - void add_paths( - ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> - paths) { - fbb_.AddOffset(TUIndex::VT_PATHS, paths); - } - - void add_locations( - ::flatbuffers::Offset<::flatbuffers::Vector> - locations) { - fbb_.AddOffset(TUIndex::VT_LOCATIONS, locations); - } - - void add_symbols(::flatbuffers::Offset<::flatbuffers::Vector< - ::flatbuffers::Offset>> symbols) { - fbb_.AddOffset(TUIndex::VT_SYMBOLS, symbols); - } - - void add_file_indices( - ::flatbuffers::Offset< - ::flatbuffers::Vector<::flatbuffers::Offset>> - file_indices) { - fbb_.AddOffset(TUIndex::VT_FILE_INDICES, file_indices); - } - - void add_main_file_index( - ::flatbuffers::Offset main_file_index) { - fbb_.AddOffset(TUIndex::VT_MAIN_FILE_INDEX, main_file_index); - } - - explicit TUIndexBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - return o; - } -}; - -inline ::flatbuffers::Offset CreateTUIndex( - ::flatbuffers::FlatBufferBuilder& _fbb, - uint64_t built_at = 0, - ::flatbuffers::Offset<::flatbuffers::Vector<::flatbuffers::Offset<::flatbuffers::String>>> - paths = 0, - ::flatbuffers::Offset<::flatbuffers::Vector> - locations = 0, - ::flatbuffers::Offset< - ::flatbuffers::Vector<::flatbuffers::Offset>> symbols = - 0, - ::flatbuffers::Offset<::flatbuffers::Vector< - ::flatbuffers::Offset>> file_indices = 0, - ::flatbuffers::Offset main_file_index = 0) { - TUIndexBuilder builder_(_fbb); - builder_.add_built_at(built_at); - builder_.add_main_file_index(main_file_index); - builder_.add_file_indices(file_indices); - builder_.add_symbols(symbols); - builder_.add_locations(locations); - builder_.add_paths(paths); - return builder_.Finish(); -} - -inline ::flatbuffers::Offset CreateTUIndexDirect( - ::flatbuffers::FlatBufferBuilder& _fbb, - uint64_t built_at = 0, - const std::vector<::flatbuffers::Offset<::flatbuffers::String>>* paths = nullptr, - const std::vector* locations = nullptr, - const std::vector<::flatbuffers::Offset>* symbols = nullptr, - const std::vector<::flatbuffers::Offset>* file_indices = - nullptr, - ::flatbuffers::Offset main_file_index = 0) { - auto paths__ = - paths ? _fbb.CreateVector<::flatbuffers::Offset<::flatbuffers::String>>(*paths) : 0; - auto locations__ = - locations ? _fbb.CreateVectorOfStructs(*locations) - : 0; - auto symbols__ = - symbols - ? _fbb.CreateVector<::flatbuffers::Offset>(*symbols) - : 0; - auto file_indices__ = - file_indices - ? _fbb.CreateVector<::flatbuffers::Offset>( - *file_indices) - : 0; - return clice::index::binary::CreateTUIndex(_fbb, - built_at, - paths__, - locations__, - symbols__, - file_indices__, - main_file_index); -} - -struct PathEntry FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef PathEntryBuilder Builder; - - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_PATH = 4, VT_ID = 6 }; - - const ::flatbuffers::String* path() const { - return GetPointer(VT_PATH); - } - - uint32_t id() const { - return GetField(VT_ID, 0); - } - - bool Verify(::flatbuffers::Verifier& verifier) const { - return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_PATH) && - verifier.VerifyString(path()) && VerifyField(verifier, VT_ID, 4) && - verifier.EndTable(); - } -}; - -struct PathEntryBuilder { - typedef PathEntry Table; - ::flatbuffers::FlatBufferBuilder& fbb_; - ::flatbuffers::uoffset_t start_; - - void add_path(::flatbuffers::Offset<::flatbuffers::String> path) { - fbb_.AddOffset(PathEntry::VT_PATH, path); - } - - void add_id(uint32_t id) { - fbb_.AddElement(PathEntry::VT_ID, id, 0); - } - - explicit PathEntryBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - return o; - } -}; - -inline ::flatbuffers::Offset - CreatePathEntry(::flatbuffers::FlatBufferBuilder& _fbb, - ::flatbuffers::Offset<::flatbuffers::String> path = 0, - uint32_t id = 0) { - PathEntryBuilder builder_(_fbb); - builder_.add_id(id); - builder_.add_path(path); - return builder_.Finish(); -} - -inline ::flatbuffers::Offset - CreatePathEntryDirect(::flatbuffers::FlatBufferBuilder& _fbb, - const char* path = nullptr, - uint32_t id = 0) { - auto path__ = path ? _fbb.CreateString(path) : 0; - return clice::index::binary::CreatePathEntry(_fbb, path__, id); -} - -struct ProjectIndex FLATBUFFERS_FINAL_CLASS : private ::flatbuffers::Table { - typedef ProjectIndexBuilder Builder; - - enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_PATHS = 4, - VT_INDICES = 6, - VT_SYMBOLS = 8 - }; - - const ::flatbuffers::Vector<::flatbuffers::Offset>* - paths() const { - return GetPointer< - const ::flatbuffers::Vector<::flatbuffers::Offset>*>( - VT_PATHS); - } - - const ::flatbuffers::Vector* indices() const { - return GetPointer*>( - VT_INDICES); - } - - const ::flatbuffers::Vector<::flatbuffers::Offset>* - symbols() const { - return GetPointer< - const ::flatbuffers::Vector<::flatbuffers::Offset>*>( - VT_SYMBOLS); - } - - bool Verify(::flatbuffers::Verifier& verifier) const { - return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_PATHS) && - verifier.VerifyVector(paths()) && verifier.VerifyVectorOfTables(paths()) && - VerifyOffset(verifier, VT_INDICES) && verifier.VerifyVector(indices()) && - VerifyOffset(verifier, VT_SYMBOLS) && verifier.VerifyVector(symbols()) && - verifier.VerifyVectorOfTables(symbols()) && verifier.EndTable(); - } -}; - -struct ProjectIndexBuilder { - typedef ProjectIndex Table; - ::flatbuffers::FlatBufferBuilder& fbb_; - ::flatbuffers::uoffset_t start_; - - void add_paths( - ::flatbuffers::Offset< - ::flatbuffers::Vector<::flatbuffers::Offset>> paths) { - fbb_.AddOffset(ProjectIndex::VT_PATHS, paths); - } - - void add_indices( - ::flatbuffers::Offset<::flatbuffers::Vector> - indices) { - fbb_.AddOffset(ProjectIndex::VT_INDICES, indices); - } - - void add_symbols(::flatbuffers::Offset<::flatbuffers::Vector< - ::flatbuffers::Offset>> symbols) { - fbb_.AddOffset(ProjectIndex::VT_SYMBOLS, symbols); - } - - explicit ProjectIndexBuilder(::flatbuffers::FlatBufferBuilder& _fbb) : fbb_(_fbb) { - start_ = fbb_.StartTable(); - } - - ::flatbuffers::Offset Finish() { - const auto end = fbb_.EndTable(start_); - auto o = ::flatbuffers::Offset(end); - return o; - } -}; - -inline ::flatbuffers::Offset CreateProjectIndex( - ::flatbuffers::FlatBufferBuilder& _fbb, - ::flatbuffers::Offset< - ::flatbuffers::Vector<::flatbuffers::Offset>> paths = 0, - ::flatbuffers::Offset<::flatbuffers::Vector> - indices = 0, - ::flatbuffers::Offset< - ::flatbuffers::Vector<::flatbuffers::Offset>> symbols = - 0) { - ProjectIndexBuilder builder_(_fbb); - builder_.add_symbols(symbols); - builder_.add_indices(indices); - builder_.add_paths(paths); - return builder_.Finish(); -} - -inline ::flatbuffers::Offset CreateProjectIndexDirect( - ::flatbuffers::FlatBufferBuilder& _fbb, - const std::vector<::flatbuffers::Offset>* paths = nullptr, - const std::vector* indices = nullptr, - const std::vector<::flatbuffers::Offset>* symbols = - nullptr) { - auto paths__ = - paths ? _fbb.CreateVector<::flatbuffers::Offset>(*paths) - : 0; - auto indices__ = - indices ? _fbb.CreateVectorOfStructs(*indices) : 0; - auto symbols__ = - symbols - ? _fbb.CreateVector<::flatbuffers::Offset>(*symbols) - : 0; - return clice::index::binary::CreateProjectIndex(_fbb, paths__, indices__, symbols__); -} - -} // namespace binary -} // namespace index -} // namespace clice - -#endif // FLATBUFFERS_GENERATED_SCHEMA_CLICE_INDEX_BINARY_H_