[clang-tools-extra] 67b2dbd - [clangd] Extend dexp to support remote index
Kirill Bobyrev via cfe-commits
cfe-commits at lists.llvm.org
Fri Apr 24 04:59:33 PDT 2020
Author: Kirill Bobyrev
Date: 2020-04-24T13:59:21+02:00
New Revision: 67b2dbd5a33583fe148fd12f141e15301cfe99d1
URL: https://github.com/llvm/llvm-project/commit/67b2dbd5a33583fe148fd12f141e15301cfe99d1
DIFF: https://github.com/llvm/llvm-project/commit/67b2dbd5a33583fe148fd12f141e15301cfe99d1.diff
LOG: [clangd] Extend dexp to support remote index
Summary:
* Merge clangd-remote-client into dexp
* Implement `clangd::remote::IndexClient` that is derived from `SymbolIndex`
* Upgrade remote mode-related CMake infrastructure
Reviewers: sammccall
Reviewed By: sammccall
Subscribers: mgorny, ilya-biryukov, MaskRay, jkorous, arphaman, kadircet, usaxena95, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D78521
Added:
clang-tools-extra/clangd/index/remote/Client.cpp
clang-tools-extra/clangd/index/remote/Client.h
clang-tools-extra/clangd/index/remote/marshalling/CMakeLists.txt
clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp
clang-tools-extra/clangd/index/remote/marshalling/Marshalling.h
clang-tools-extra/clangd/index/remote/unimplemented/CMakeLists.txt
clang-tools-extra/clangd/index/remote/unimplemented/UnimplementedClient.cpp
Modified:
clang-tools-extra/clangd/CMakeLists.txt
clang-tools-extra/clangd/Features.inc.in
clang-tools-extra/clangd/index/Serialization.h
clang-tools-extra/clangd/index/YAMLSerialization.cpp
clang-tools-extra/clangd/index/dex/dexp/CMakeLists.txt
clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp
clang-tools-extra/clangd/index/remote/CMakeLists.txt
clang-tools-extra/clangd/index/remote/Index.proto
clang-tools-extra/clangd/index/remote/server/CMakeLists.txt
clang-tools-extra/clangd/index/remote/server/Server.cpp
Removed:
clang-tools-extra/clangd/index/remote/client/CMakeLists.txt
clang-tools-extra/clangd/index/remote/client/Client.cpp
################################################################################
diff --git a/clang-tools-extra/clangd/CMakeLists.txt b/clang-tools-extra/clangd/CMakeLists.txt
index 1c2cbf398b77..124f087589d6 100644
--- a/clang-tools-extra/clangd/CMakeLists.txt
+++ b/clang-tools-extra/clangd/CMakeLists.txt
@@ -140,7 +140,6 @@ if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
endif()
add_subdirectory(tool)
add_subdirectory(indexer)
-add_subdirectory(index/dex/dexp)
if (LLVM_INCLUDE_BENCHMARKS)
add_subdirectory(benchmarks)
@@ -160,5 +159,6 @@ set(GRPC_INSTALL_PATH "" CACHE PATH "Path to gRPC library manual installation.")
if (CLANGD_ENABLE_REMOTE)
include(FindGRPC)
- add_subdirectory(index/remote)
endif()
+add_subdirectory(index/remote)
+add_subdirectory(index/dex/dexp)
diff --git a/clang-tools-extra/clangd/Features.inc.in b/clang-tools-extra/clangd/Features.inc.in
index da75aa67a65b..6797232ddac7 100644
--- a/clang-tools-extra/clangd/Features.inc.in
+++ b/clang-tools-extra/clangd/Features.inc.in
@@ -1 +1,2 @@
#define CLANGD_BUILD_XPC @CLANGD_BUILD_XPC@
+#define CLANGD_ENABLE_REMOTE @CLANGD_ENABLE_REMOTE@
diff --git a/clang-tools-extra/clangd/index/Serialization.h b/clang-tools-extra/clangd/index/Serialization.h
index 47317c0401fc..99510630f1ca 100644
--- a/clang-tools-extra/clangd/index/Serialization.h
+++ b/clang-tools-extra/clangd/index/Serialization.h
@@ -77,6 +77,13 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const IndexFileOut &O);
std::string toYAML(const Symbol &);
std::string toYAML(const std::pair<SymbolID, ArrayRef<Ref>> &);
std::string toYAML(const Relation &);
+std::string toYAML(const Ref &);
+
+// Deserialize a single symbol from YAML.
+llvm::Expected<clangd::Symbol> symbolFromYAML(StringRef YAML,
+ llvm::UniqueStringSaver *Strings);
+llvm::Expected<clangd::Ref> refFromYAML(StringRef YAML,
+ llvm::UniqueStringSaver *Strings);
// Build an in-memory static index from an index file.
// The size should be relatively small, so data can be managed in memory.
diff --git a/clang-tools-extra/clangd/index/YAMLSerialization.cpp b/clang-tools-extra/clangd/index/YAMLSerialization.cpp
index 79965ceb1634..fc515a17d100 100644
--- a/clang-tools-extra/clangd/index/YAMLSerialization.cpp
+++ b/clang-tools-extra/clangd/index/YAMLSerialization.cpp
@@ -517,5 +517,40 @@ std::string toYAML(const Relation &R) {
return Buf;
}
+std::string toYAML(const Ref &R) {
+ std::string Buf;
+ {
+ llvm::raw_string_ostream OS(Buf);
+ llvm::yaml::Output Yout(OS);
+ Ref Reference = R; // copy: Yout<< requires mutability.
+ Yout << Reference;
+ }
+ return Buf;
+}
+
+llvm::Expected<clangd::Symbol>
+symbolFromYAML(StringRef YAML, llvm::UniqueStringSaver *Strings) {
+ clangd::Symbol Deserialized;
+ llvm::yaml::Input YAMLInput(YAML, Strings);
+ if (YAMLInput.error())
+ return llvm::make_error<llvm::StringError>(
+ llvm::formatv("Unable to deserialize Symbol from YAML: {0}", YAML),
+ llvm::inconvertibleErrorCode());
+ YAMLInput >> Deserialized;
+ return Deserialized;
+}
+
+llvm::Expected<clangd::Ref> refFromYAML(StringRef YAML,
+ llvm::UniqueStringSaver *Strings) {
+ clangd::Ref Deserialized;
+ llvm::yaml::Input YAMLInput(YAML, Strings);
+ if (YAMLInput.error())
+ return llvm::make_error<llvm::StringError>(
+ llvm::formatv("Unable to deserialize Symbol from YAML: {0}", YAML),
+ llvm::inconvertibleErrorCode());
+ YAMLInput >> Deserialized;
+ return Deserialized;
+}
+
} // namespace clangd
} // namespace clang
diff --git a/clang-tools-extra/clangd/index/dex/dexp/CMakeLists.txt b/clang-tools-extra/clangd/index/dex/dexp/CMakeLists.txt
index a4edbb372a76..7b4b6e53a4ad 100644
--- a/clang-tools-extra/clangd/index/dex/dexp/CMakeLists.txt
+++ b/clang-tools-extra/clangd/index/dex/dexp/CMakeLists.txt
@@ -1,4 +1,5 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../)
+include_directories(${CMAKE_CURRENT_BINARY_DIR}/../../../)
set(LLVM_LINK_COMPONENTS
LineEditor
@@ -16,4 +17,5 @@ clang_target_link_libraries(dexp
target_link_libraries(dexp
PRIVATE
clangDaemon
+ clangdRemoteIndex
)
diff --git a/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp b/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp
index 015246d1a82f..101367ce7c67 100644
--- a/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp
+++ b/clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp
@@ -11,9 +11,11 @@
//
//===----------------------------------------------------------------------===//
+#include "Features.inc"
#include "SourceCode.h"
#include "index/Serialization.h"
#include "index/dex/Dex.h"
+#include "index/remote/Client.h"
#include "llvm/ADT/ScopeExit.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
@@ -26,8 +28,9 @@ namespace clang {
namespace clangd {
namespace {
-llvm::cl::opt<std::string> IndexPath(llvm::cl::desc("<INDEX FILE>"),
- llvm::cl::Positional, llvm::cl::Required);
+llvm::cl::opt<std::string> IndexLocation(
+ llvm::cl::desc("<path to index file | remote:server.address>"),
+ llvm::cl::Positional);
llvm::cl::opt<std::string>
ExecCommand("c", llvm::cl::desc("Command to execute and then exit"));
@@ -38,6 +41,10 @@ queries over given symbol collection obtained via clangd-indexer. The
tool can be used to evaluate search quality of existing index implementations
and manually construct non-trivial test cases.
+You can connect to remote index by passing remote:address to dexp. Example:
+
+$ dexp remote:0.0.0.0:9000
+
Type use "help" request to get information about the details.
)";
@@ -150,7 +157,7 @@ class FuzzyFind : public Command {
}
Request.AnyScope = Request.Scopes.empty();
// FIXME(kbobyrev): Print symbol final scores to see the distribution.
- static const auto OutputFormat = "{0,-4} | {1,-40} | {2,-25}\n";
+ static const auto *OutputFormat = "{0,-4} | {1,-40} | {2,-25}\n";
llvm::outs() << llvm::formatv(OutputFormat, "Rank", "Symbol ID",
"Symbol Name");
size_t Rank = 0;
@@ -316,13 +323,14 @@ struct {
{"find", "Search for symbols with fuzzyFind", std::make_unique<FuzzyFind>},
{"lookup", "Dump symbol details by ID or qualified name",
std::make_unique<Lookup>},
- {"refs", "Find references by ID or qualified name",
- std::make_unique<Refs>},
+ {"refs", "Find references by ID or qualified name", std::make_unique<Refs>},
{"export", "Export index", std::make_unique<Export>},
};
std::unique_ptr<SymbolIndex> openIndex(llvm::StringRef Index) {
- return loadIndex(Index, /*UseDex=*/true);
+ return Index.startswith("remote:")
+ ? remote::getClient(Index.drop_front(strlen("remote:")))
+ : loadIndex(Index, /*UseDex=*/true);
}
bool runCommand(std::string Request, const SymbolIndex &Index) {
@@ -365,9 +373,10 @@ int main(int argc, const char *argv[]) {
llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
std::unique_ptr<SymbolIndex> Index;
- reportTime("Dex build", [&]() {
- Index = openIndex(IndexPath);
- });
+ reportTime(llvm::StringRef(IndexLocation).startswith("remote:")
+ ? "Remote index client creation"
+ : "Dex build",
+ [&]() { Index = openIndex(IndexLocation); });
if (!Index) {
llvm::outs() << "Failed to open the index.\n";
diff --git a/clang-tools-extra/clangd/index/remote/CMakeLists.txt b/clang-tools-extra/clangd/index/remote/CMakeLists.txt
index b946958f3c5f..1bd336e626d9 100644
--- a/clang-tools-extra/clangd/index/remote/CMakeLists.txt
+++ b/clang-tools-extra/clangd/index/remote/CMakeLists.txt
@@ -1,7 +1,28 @@
-generate_grpc_protos(RemoteIndexProtos "Index.proto")
+if (CLANGD_ENABLE_REMOTE)
+ generate_grpc_protos(RemoteIndexProtos "Index.proto")
+ include_directories(${CMAKE_CURRENT_BINARY_DIR})
+ include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../)
-include_directories("${CMAKE_CURRENT_BINARY_DIR}")
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../)
+ # FIXME(kirillbobyrev): target_compile_definitions is not working with
+ # add_clang_library for some reason. Is there any way to make this
+ # target-local?
+ add_definitions(-DGOOGLE_PROTOBUF_NO_RTTI=1)
-add_subdirectory(client)
-add_subdirectory(server)
+ add_clang_library(clangdRemoteIndex
+ Client.cpp
+
+ LINK_LIBS
+ RemoteIndexProtos
+ clangdRemoteMarshalling
+
+ protobuf
+ grpc++
+ clangDaemon
+ )
+
+ add_subdirectory(marshalling)
+ add_subdirectory(server)
+else()
+ # Provides a dummy implementation of clangdRemoteIndex.
+ add_subdirectory(unimplemented)
+endif()
diff --git a/clang-tools-extra/clangd/index/remote/Client.cpp b/clang-tools-extra/clangd/index/remote/Client.cpp
new file mode 100644
index 000000000000..79f303978c31
--- /dev/null
+++ b/clang-tools-extra/clangd/index/remote/Client.cpp
@@ -0,0 +1,105 @@
+//===--- Client.cpp ----------------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include <grpcpp/grpcpp.h>
+
+#include "Client.h"
+#include "Index.grpc.pb.h"
+#include "Logger.h"
+#include "Trace.h"
+#include "index/Serialization.h"
+#include "marshalling/Marshalling.h"
+#include "llvm/Support/YAMLTraits.h"
+
+namespace clang {
+namespace clangd {
+namespace remote {
+namespace {
+
+class IndexClient : public clangd::SymbolIndex {
+ template <typename RequestT, typename ReplyT>
+ using StreamingCall = std::unique_ptr<grpc::ClientReader<ReplyT>> (
+ remote::SymbolIndex::Stub::*)(grpc::ClientContext *, const RequestT &);
+
+ // FIXME(kirillbobyrev): Set deadlines for requests.
+ template <typename RequestT, typename ReplyT, typename ClangdRequestT,
+ typename CallbackT>
+ bool streamRPC(ClangdRequestT Request,
+ StreamingCall<RequestT, ReplyT> RPCCall,
+ CallbackT Callback) const {
+ bool FinalResult = false;
+ trace::Span Tracer(RequestT::descriptor()->name());
+ const auto RPCRequest = toProtobuf(Request);
+ grpc::ClientContext Context;
+ auto Reader = (Stub.get()->*RPCCall)(&Context, RPCRequest);
+ llvm::BumpPtrAllocator Arena;
+ llvm::UniqueStringSaver Strings(Arena);
+ ReplyT Reply;
+ while (Reader->Read(&Reply)) {
+ if (!Reply.has_stream_result()) {
+ FinalResult = Reply.final_result();
+ continue;
+ }
+ auto Sym = fromProtobuf(Reply.stream_result(), &Strings);
+ if (!Sym)
+ elog("Received invalid {0}: {1}", ReplyT::descriptor()->name(),
+ Reply.stream_result().yaml_serialization());
+ Callback(*Sym);
+ }
+ SPAN_ATTACH(Tracer, "status", Reader->Finish().ok());
+ return FinalResult;
+ }
+
+public:
+ IndexClient(std::shared_ptr<grpc::Channel> Channel)
+ : Stub(remote::SymbolIndex::NewStub(Channel)) {}
+
+ void lookup(const clangd::LookupRequest &Request,
+ llvm::function_ref<void(const clangd::Symbol &)> Callback) const {
+ streamRPC<LookupRequest, LookupReply>(
+ Request, &remote::SymbolIndex::Stub::Lookup, Callback);
+ }
+
+ bool
+ fuzzyFind(const clangd::FuzzyFindRequest &Request,
+ llvm::function_ref<void(const clangd::Symbol &)> Callback) const {
+ return streamRPC<FuzzyFindRequest, FuzzyFindReply>(
+ Request, &remote::SymbolIndex::Stub::FuzzyFind, Callback);
+ }
+
+ bool refs(const clangd::RefsRequest &Request,
+ llvm::function_ref<void(const clangd::Ref &)> Callback) const {
+ return streamRPC<RefsRequest, RefsReply>(
+ Request, &remote::SymbolIndex::Stub::Refs, Callback);
+ }
+
+ // FIXME(kirillbobyrev): Implement this.
+ void
+ relations(const clangd::RelationsRequest &,
+ llvm::function_ref<void(const SymbolID &, const clangd::Symbol &)>)
+ const {}
+
+ // IndexClient does not take any space since the data is stored on the server.
+ size_t estimateMemoryUsage() const { return 0; }
+
+private:
+ std::unique_ptr<remote::SymbolIndex::Stub> Stub;
+};
+
+} // namespace
+
+std::unique_ptr<clangd::SymbolIndex> getClient(llvm::StringRef Address) {
+ const auto Channel =
+ grpc::CreateChannel(Address.str(), grpc::InsecureChannelCredentials());
+ Channel->GetState(true);
+ return std::unique_ptr<clangd::SymbolIndex>(new IndexClient(Channel));
+}
+
+} // namespace remote
+} // namespace clangd
+} // namespace clang
diff --git a/clang-tools-extra/clangd/index/remote/Client.h b/clang-tools-extra/clangd/index/remote/Client.h
new file mode 100644
index 000000000000..9708fdbe851a
--- /dev/null
+++ b/clang-tools-extra/clangd/index/remote/Client.h
@@ -0,0 +1,31 @@
+//===--- Client.h - Connect to a remote index via gRPC -----------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_REMOTE_INDEX_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_REMOTE_INDEX_H
+
+#include "index/Index.h"
+
+namespace clang {
+namespace clangd {
+namespace remote {
+
+/// Returns an SymbolIndex client that passes requests to remote index located
+/// at \p Address. The client allows synchronous RPC calls.
+///
+/// This method attempts to resolve the address and establish the connection.
+///
+/// \returns nullptr if the address is not resolved during the function call or
+/// if the project was compiled without Remote Index support.
+std::unique_ptr<clangd::SymbolIndex> getClient(llvm::StringRef Address);
+
+} // namespace remote
+} // namespace clangd
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_REMOTE_INDEX_H
diff --git a/clang-tools-extra/clangd/index/remote/Index.proto b/clang-tools-extra/clangd/index/remote/Index.proto
index 399036ed72b7..0cd9738db58c 100644
--- a/clang-tools-extra/clangd/index/remote/Index.proto
+++ b/clang-tools-extra/clangd/index/remote/Index.proto
@@ -10,10 +10,60 @@ syntax = "proto3";
package clang.clangd.remote;
-service Index {
+service SymbolIndex {
rpc Lookup(LookupRequest) returns (stream LookupReply) {}
+
+ rpc FuzzyFind(FuzzyFindRequest) returns (stream FuzzyFindReply) {}
+
+ rpc Refs(RefsRequest) returns (stream RefsReply) {}
+}
+
+message LookupRequest { repeated string ids = 1; }
+
+// The response is a stream of symbol messages and the terminating message
+// indicating the end of stream.
+message LookupReply {
+ oneof kind {
+ Symbol stream_result = 1;
+ bool final_result = 2;
+ }
+}
+
+message FuzzyFindRequest {
+ string query = 1;
+ repeated string scopes = 2;
+ bool any_scope = 3;
+ uint32 limit = 4;
+ bool resricted_for_code_completion = 5;
+ repeated string proximity_paths = 6;
+ repeated string preferred_types = 7;
+}
+
+// The response is a stream of symbol messages, and one terminating has_more
+// message.
+message FuzzyFindReply {
+ oneof kind {
+ Symbol stream_result = 1;
+ bool final_result = 2; // HasMore
+ }
}
-message LookupRequest { string id = 1; }
+message RefsRequest {
+ repeated string ids = 1;
+ uint32 filter = 2;
+ uint32 limit = 3;
+}
+
+// The response is a stream of reference messages, and one terminating has_more
+// message.
+message RefsReply {
+ oneof kind {
+ Ref stream_result = 1;
+ bool final_result = 2; // HasMore
+ }
+}
-message LookupReply { string symbol_yaml = 1; }
+// FIXME(kirillbobyrev): Properly serialize symbols and refs instead of passing
+// YAML.
+message Ref { string yaml_serialization = 1; }
+message Symbol { string yaml_serialization = 1; }
diff --git a/clang-tools-extra/clangd/index/remote/client/CMakeLists.txt b/clang-tools-extra/clangd/index/remote/client/CMakeLists.txt
deleted file mode 100644
index 18bca1b04436..000000000000
--- a/clang-tools-extra/clangd/index/remote/client/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-set(LLVM_LINK_COMPONENTS
- LineEditor
- Support
- )
-add_clang_executable(clangd-index-client
- Client.cpp
- )
-target_compile_definitions(clangd-index-client PRIVATE -DGOOGLE_PROTOBUF_NO_RTTI=1)
-clang_target_link_libraries(clangd-index-client
- PRIVATE
- clangDaemon
- )
-target_link_libraries(clangd-index-client
- PRIVATE
- RemoteIndexProtos
-
- protobuf
- grpc++
- )
diff --git a/clang-tools-extra/clangd/index/remote/client/Client.cpp b/clang-tools-extra/clangd/index/remote/client/Client.cpp
deleted file mode 100644
index 5e888c5e0fa7..000000000000
--- a/clang-tools-extra/clangd/index/remote/client/Client.cpp
+++ /dev/null
@@ -1,91 +0,0 @@
-//===--- Client.cpp - Remote Index Client -----------------------*- C++ -*-===//
-//
-// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-// See https://llvm.org/LICENSE.txt for license information.
-// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-//
-//===----------------------------------------------------------------------===//
-//
-// This file implements a simple interactive tool which can be used to manually
-// evaluate symbol search quality of Clangd index.
-//
-//===----------------------------------------------------------------------===//
-
-#include "SourceCode.h"
-#include "index/Serialization.h"
-#include "index/dex/Dex.h"
-#include "llvm/ADT/ScopeExit.h"
-#include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/StringSwitch.h"
-#include "llvm/LineEditor/LineEditor.h"
-#include "llvm/Support/CommandLine.h"
-#include "llvm/Support/Signals.h"
-
-#include "grpcpp/grpcpp.h"
-
-#include "Index.grpc.pb.h"
-
-namespace clang {
-namespace clangd {
-namespace {
-
-llvm::cl::opt<std::string>
- ServerAddress("server-address",
- llvm::cl::desc("Address of remote index server to use."),
- llvm::cl::init("0.0.0.0:50051"));
-
-static const std::string Overview = R"(
-This is an **experimental** interactive tool to process user-provided search
-queries over given symbol collection obtained via clangd-indexer with the help
-of remote index server. The client will connect to remote index server and pass
-it lookup queries.
-)";
-
-class RemoteIndexClient {
-public:
- RemoteIndexClient(std::shared_ptr<grpc::Channel> Channel)
- : Stub(remote::Index::NewStub(Channel)) {}
-
- void lookup(llvm::StringRef ID) {
- llvm::outs() << "Lookup of symbol with ID " << ID << '\n';
- remote::LookupRequest Proto;
- Proto.set_id(ID.str());
-
- grpc::ClientContext Context;
- remote::LookupReply Reply;
- std::unique_ptr<grpc::ClientReader<remote::LookupReply>> Reader(
- Stub->Lookup(&Context, Proto));
- while (Reader->Read(&Reply)) {
- llvm::outs() << Reply.symbol_yaml();
- }
- grpc::Status Status = Reader->Finish();
- if (Status.ok()) {
- llvm::outs() << "lookupRequest rpc succeeded.\n";
- } else {
- llvm::outs() << "lookupRequest rpc failed.\n";
- }
- }
-
-private:
- std::unique_ptr<remote::Index::Stub> Stub;
-};
-
-} // namespace
-} // namespace clangd
-} // namespace clang
-
-int main(int argc, const char *argv[]) {
- using namespace clang::clangd;
-
- llvm::cl::ParseCommandLineOptions(argc, argv, Overview);
- llvm::cl::ResetCommandLineParser(); // We reuse it for REPL commands.
- llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
-
- RemoteIndexClient IndexClient(
- grpc::CreateChannel(ServerAddress, grpc::InsecureChannelCredentials()));
-
- llvm::LineEditor LE("remote-index-client");
- while (llvm::Optional<std::string> Request = LE.readLine())
- IndexClient.lookup(std::move(*Request));
-}
diff --git a/clang-tools-extra/clangd/index/remote/marshalling/CMakeLists.txt b/clang-tools-extra/clangd/index/remote/marshalling/CMakeLists.txt
new file mode 100644
index 000000000000..4789a728951c
--- /dev/null
+++ b/clang-tools-extra/clangd/index/remote/marshalling/CMakeLists.txt
@@ -0,0 +1,9 @@
+add_clang_library(clangdRemoteMarshalling
+ Marshalling.cpp
+
+ LINK_LIBS
+ RemoteIndexProtos
+
+ protobuf
+ clangDaemon
+ )
diff --git a/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp b/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp
new file mode 100644
index 000000000000..d2ec07136fa5
--- /dev/null
+++ b/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp
@@ -0,0 +1,99 @@
+//===--- Marshalling.cpp -----------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Marshalling.h"
+#include "Logger.h"
+#include "index/Serialization.h"
+
+namespace clang {
+namespace clangd {
+namespace remote {
+
+clangd::FuzzyFindRequest fromProtobuf(const FuzzyFindRequest *Request) {
+ clangd::FuzzyFindRequest Result;
+ Result.Query = Request->query();
+ for (const auto &Scope : Request->scopes())
+ Result.Scopes.push_back(Scope);
+ Result.AnyScope = Request->any_scope();
+ if (Request->limit())
+ Result.Limit = Request->limit();
+ Result.RestrictForCodeCompletion = Request->resricted_for_code_completion();
+ for (const auto &Path : Request->proximity_paths())
+ Result.ProximityPaths.push_back(Path);
+ for (const auto &Type : Request->preferred_types())
+ Result.ProximityPaths.push_back(Type);
+ return Result;
+}
+
+llvm::Optional<clangd::Symbol> fromProtobuf(const Symbol &Message,
+ llvm::UniqueStringSaver *Strings) {
+ auto Result = symbolFromYAML(Message.yaml_serialization(), Strings);
+ if (!Result) {
+ elog("Cannot convert Symbol from Protobuf: {}", Result.takeError());
+ return llvm::None;
+ }
+ return *Result;
+}
+llvm::Optional<clangd::Ref> fromProtobuf(const Ref &Message,
+ llvm::UniqueStringSaver *Strings) {
+ auto Result = refFromYAML(Message.yaml_serialization(), Strings);
+ if (!Result) {
+ elog("Cannot convert Ref from Protobuf: {}", Result.takeError());
+ return llvm::None;
+ }
+ return *Result;
+}
+
+LookupRequest toProtobuf(const clangd::LookupRequest &From) {
+ LookupRequest RPCRequest;
+ for (const auto &SymbolID : From.IDs)
+ RPCRequest.add_ids(SymbolID.str());
+ return RPCRequest;
+}
+
+FuzzyFindRequest toProtobuf(const clangd::FuzzyFindRequest &From) {
+ FuzzyFindRequest RPCRequest;
+ RPCRequest.set_query(From.Query);
+ for (const auto &Scope : From.Scopes)
+ RPCRequest.add_scopes(Scope);
+ RPCRequest.set_any_scope(From.AnyScope);
+ if (From.Limit)
+ RPCRequest.set_limit(*From.Limit);
+ RPCRequest.set_resricted_for_code_completion(From.RestrictForCodeCompletion);
+ for (const auto &Path : From.ProximityPaths)
+ RPCRequest.add_proximity_paths(Path);
+ for (const auto &Type : From.PreferredTypes)
+ RPCRequest.add_preferred_types(Type);
+ return RPCRequest;
+}
+
+RefsRequest toProtobuf(const clangd::RefsRequest &From) {
+ RefsRequest RPCRequest;
+ for (const auto &ID : From.IDs)
+ RPCRequest.add_ids(ID.str());
+ RPCRequest.set_filter(static_cast<uint32_t>(From.Filter));
+ if (From.Limit)
+ RPCRequest.set_limit(*From.Limit);
+ return RPCRequest;
+}
+
+Symbol toProtobuf(const clangd::Symbol &From) {
+ Symbol Result;
+ Result.set_yaml_serialization(toYAML(From));
+ return Result;
+}
+
+Ref toProtobuf(const clangd::Ref &From) {
+ Ref Result;
+ Result.set_yaml_serialization(toYAML(From));
+ return Result;
+}
+
+} // namespace remote
+} // namespace clangd
+} // namespace clang
diff --git a/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.h b/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.h
new file mode 100644
index 000000000000..ae58318e3dbb
--- /dev/null
+++ b/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.h
@@ -0,0 +1,41 @@
+//===--- Marshalling.h -------------------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// Transformations between native Clangd types and Protobuf-generated classes.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_REMOTE_MARSHALLING_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_REMOTE_MARSHALLING_H
+
+#include "Index.grpc.pb.h"
+#include "index/Index.h"
+#include "llvm/Support/StringSaver.h"
+
+namespace clang {
+namespace clangd {
+namespace remote {
+
+clangd::FuzzyFindRequest fromProtobuf(const FuzzyFindRequest *Request);
+llvm::Optional<clangd::Symbol> fromProtobuf(const Symbol &Message,
+ llvm::UniqueStringSaver *Strings);
+llvm::Optional<clangd::Ref> fromProtobuf(const Ref &Message,
+ llvm::UniqueStringSaver *Strings);
+
+LookupRequest toProtobuf(const clangd::LookupRequest &From);
+FuzzyFindRequest toProtobuf(const clangd::FuzzyFindRequest &From);
+RefsRequest toProtobuf(const clangd::RefsRequest &From);
+
+Ref toProtobuf(const clangd::Ref &From);
+Symbol toProtobuf(const clangd::Symbol &From);
+
+} // namespace remote
+} // namespace clangd
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_REMOTE_MARSHALLING_H
diff --git a/clang-tools-extra/clangd/index/remote/server/CMakeLists.txt b/clang-tools-extra/clangd/index/remote/server/CMakeLists.txt
index 7493be1a444f..378ea2946839 100644
--- a/clang-tools-extra/clangd/index/remote/server/CMakeLists.txt
+++ b/clang-tools-extra/clangd/index/remote/server/CMakeLists.txt
@@ -5,7 +5,7 @@ set(LLVM_LINK_COMPONENTS
add_clang_executable(clangd-index-server
Server.cpp
)
-target_compile_definitions(clangd-index-server PRIVATE -DGOOGLE_PROTOBUF_NO_RTTI=1)
+target_compile_definitions(clangd-index-server PRIVATE -D GOOGLE_PROTOBUF_NO_RTTI=1)
clang_target_link_libraries(clangd-index-server
PRIVATE
clangDaemon
@@ -14,7 +14,5 @@ target_link_libraries(clangd-index-server
PRIVATE
RemoteIndexProtos
- protobuf
- grpc++
- clangDaemon
+ clangdRemoteMarshalling
)
diff --git a/clang-tools-extra/clangd/index/remote/server/Server.cpp b/clang-tools-extra/clangd/index/remote/server/Server.cpp
index b7a54b79b6c3..ca35ff7715f0 100644
--- a/clang-tools-extra/clangd/index/remote/server/Server.cpp
+++ b/clang-tools-extra/clangd/index/remote/server/Server.cpp
@@ -8,6 +8,7 @@
#include "index/Index.h"
#include "index/Serialization.h"
+#include "index/remote/marshalling/Marshalling.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/LineEditor/LineEditor.h"
@@ -16,13 +17,14 @@
#include "llvm/Support/Path.h"
#include "llvm/Support/Signals.h"
-#include "grpcpp/grpcpp.h"
-#include "grpcpp/health_check_service_interface.h"
+#include <grpcpp/grpcpp.h>
+#include <grpcpp/health_check_service_interface.h>
#include "Index.grpc.pb.h"
namespace clang {
namespace clangd {
+namespace remote {
namespace {
static const std::string Overview = R"(
@@ -33,42 +35,80 @@ awaits gRPC lookup requests from the client.
llvm::cl::opt<std::string> IndexPath(llvm::cl::desc("<INDEX FILE>"),
llvm::cl::Positional, llvm::cl::Required);
-llvm::cl::opt<std::string> ServerAddress("server-address",
- llvm::cl::init("0.0.0.0:50051"));
+llvm::cl::opt<std::string> ServerAddress(
+ "server-address", llvm::cl::init("0.0.0.0:50051"),
+ llvm::cl::desc("Address of the invoked server. Defaults to 0.0.0.0:50051"));
-std::unique_ptr<SymbolIndex> openIndex(llvm::StringRef Index) {
+std::unique_ptr<clangd::SymbolIndex> openIndex(llvm::StringRef Index) {
return loadIndex(Index, /*UseIndex=*/true);
}
-class RemoteIndexServer final : public remote::Index::Service {
+class RemoteIndexServer final : public SymbolIndex::Service {
public:
- RemoteIndexServer(std::unique_ptr<SymbolIndex> Index)
+ RemoteIndexServer(std::unique_ptr<clangd::SymbolIndex> Index)
: Index(std::move(Index)) {}
private:
grpc::Status Lookup(grpc::ServerContext *Context,
- const remote::LookupRequest *Request,
- grpc::ServerWriter<remote::LookupReply> *Reply) override {
- llvm::outs() << "Lookup of symbol with ID " << Request->id() << '\n';
- LookupRequest Req;
- auto SID = SymbolID::fromStr(Request->id());
- if (!SID) {
- llvm::outs() << llvm::toString(SID.takeError()) << "\n";
- return grpc::Status::CANCELLED;
+ const LookupRequest *Request,
+ grpc::ServerWriter<LookupReply> *Reply) override {
+ clangd::LookupRequest Req;
+ for (const auto &ID : Request->ids()) {
+ auto SID = SymbolID::fromStr(StringRef(ID));
+ if (!SID)
+ return grpc::Status::CANCELLED;
+ Req.IDs.insert(*SID);
}
- Req.IDs.insert(*SID);
- Index->lookup(Req, [&](const Symbol &Sym) {
- remote::LookupReply NextSymbol;
- NextSymbol.set_symbol_yaml(toYAML(Sym));
- Reply->Write(NextSymbol);
+ Index->lookup(Req, [&](const clangd::Symbol &Sym) {
+ LookupReply NextMessage;
+ *NextMessage.mutable_stream_result() = toProtobuf(Sym);
+ Reply->Write(NextMessage);
});
+ LookupReply LastMessage;
+ LastMessage.set_final_result(true);
+ Reply->Write(LastMessage);
return grpc::Status::OK;
}
- std::unique_ptr<SymbolIndex> Index;
+ grpc::Status FuzzyFind(grpc::ServerContext *Context,
+ const FuzzyFindRequest *Request,
+ grpc::ServerWriter<FuzzyFindReply> *Reply) override {
+ const auto Req = fromProtobuf(Request);
+ bool HasMore = Index->fuzzyFind(Req, [&](const clangd::Symbol &Sym) {
+ FuzzyFindReply NextMessage;
+ *NextMessage.mutable_stream_result() = toProtobuf(Sym);
+ Reply->Write(NextMessage);
+ });
+ FuzzyFindReply LastMessage;
+ LastMessage.set_final_result(HasMore);
+ Reply->Write(LastMessage);
+ return grpc::Status::OK;
+ }
+
+ grpc::Status Refs(grpc::ServerContext *Context, const RefsRequest *Request,
+ grpc::ServerWriter<RefsReply> *Reply) override {
+ clangd::RefsRequest Req;
+ for (const auto &ID : Request->ids()) {
+ auto SID = SymbolID::fromStr(StringRef(ID));
+ if (!SID)
+ return grpc::Status::CANCELLED;
+ Req.IDs.insert(*SID);
+ }
+ bool HasMore = Index->refs(Req, [&](const clangd::Ref &Reference) {
+ RefsReply NextMessage;
+ *NextMessage.mutable_stream_result() = toProtobuf(Reference);
+ Reply->Write(NextMessage);
+ });
+ RefsReply LastMessage;
+ LastMessage.set_final_result(HasMore);
+ Reply->Write(LastMessage);
+ return grpc::Status::OK;
+ }
+
+ std::unique_ptr<clangd::SymbolIndex> Index;
};
-void runServer(std::unique_ptr<SymbolIndex> Index,
+void runServer(std::unique_ptr<clangd::SymbolIndex> Index,
const std::string &ServerAddress) {
RemoteIndexServer Service(std::move(Index));
@@ -83,15 +123,16 @@ void runServer(std::unique_ptr<SymbolIndex> Index,
}
} // namespace
+} // namespace remote
} // namespace clangd
} // namespace clang
int main(int argc, char *argv[]) {
- using namespace clang::clangd;
- llvm::cl::ParseCommandLineOptions(argc, argv, clang::clangd::Overview);
+ using namespace clang::clangd::remote;
+ llvm::cl::ParseCommandLineOptions(argc, argv, Overview);
llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
- std::unique_ptr<SymbolIndex> Index = openIndex(IndexPath);
+ std::unique_ptr<clang::clangd::SymbolIndex> Index = openIndex(IndexPath);
if (!Index) {
llvm::outs() << "Failed to open the index.\n";
diff --git a/clang-tools-extra/clangd/index/remote/unimplemented/CMakeLists.txt b/clang-tools-extra/clangd/index/remote/unimplemented/CMakeLists.txt
new file mode 100644
index 000000000000..aebe4e674ab7
--- /dev/null
+++ b/clang-tools-extra/clangd/index/remote/unimplemented/CMakeLists.txt
@@ -0,0 +1,10 @@
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../)
+# When compiled without Remote Index support, the real implementation index
+# client is not present. Users will get a notification about this when trying
+# to connect to remote index server instance.
+add_clang_library(clangdRemoteIndex
+ UnimplementedClient.cpp
+
+ LINK_LIBS
+ clangDaemon
+ )
diff --git a/clang-tools-extra/clangd/index/remote/unimplemented/UnimplementedClient.cpp b/clang-tools-extra/clangd/index/remote/unimplemented/UnimplementedClient.cpp
new file mode 100644
index 000000000000..725f0e472c3a
--- /dev/null
+++ b/clang-tools-extra/clangd/index/remote/unimplemented/UnimplementedClient.cpp
@@ -0,0 +1,23 @@
+//===--- UnimplementedClient.cpp ---------------------------------*- C++-*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#include "Logger.h"
+#include "index/remote/Client.h"
+
+namespace clang {
+namespace clangd {
+namespace remote {
+
+std::unique_ptr<clangd::SymbolIndex> getClient(llvm::StringRef Address) {
+ elog("Can't create SymbolIndex client without Remote Index support.");
+ return nullptr;
+}
+
+} // namespace remote
+} // namespace clangd
+} // namespace clang
More information about the cfe-commits
mailing list