kbobyrev updated this revision to Diff 259604.
kbobyrev added a comment.

Implement (B) for now


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D78521/new/

https://reviews.llvm.org/D78521

Files:
  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/Client.h
  clang-tools-extra/clangd/index/remote/Index.cpp
  clang-tools-extra/clangd/index/remote/Index.proto
  clang-tools-extra/clangd/index/remote/Marshalling.cpp
  clang-tools-extra/clangd/index/remote/Marshalling.h
  clang-tools-extra/clangd/index/remote/client/CMakeLists.txt
  clang-tools-extra/clangd/index/remote/client/Client.cpp
  clang-tools-extra/clangd/index/remote/server/CMakeLists.txt
  clang-tools-extra/clangd/index/remote/server/Server.cpp

Index: clang-tools-extra/clangd/index/remote/server/Server.cpp
===================================================================
--- clang-tools-extra/clangd/index/remote/server/Server.cpp
+++ 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.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/LineEditor/LineEditor.h"
@@ -23,6 +24,7 @@
 
 namespace clang {
 namespace clangd {
+namespace remote {
 namespace {
 
 static const std::string Overview = R"(
@@ -33,42 +35,78 @@
 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<Symbol> *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));
+    Index->lookup(Req, [&](const clangd::Symbol &Sym) {
+      Symbol NextSymbol;
+      NextSymbol.set_yaml_serializatiton(toYAML(Sym));
       Reply->Write(NextSymbol);
     });
     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()->set_yaml_serializatiton(toYAML(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()->set_yaml_serializatiton(
+          toYAML(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 +121,16 @@
 }
 
 } // 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";
Index: clang-tools-extra/clangd/index/remote/server/CMakeLists.txt
===================================================================
--- clang-tools-extra/clangd/index/remote/server/CMakeLists.txt
+++ clang-tools-extra/clangd/index/remote/server/CMakeLists.txt
@@ -5,7 +5,7 @@
 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 @@
   PRIVATE
   RemoteIndexProtos
 
-  protobuf
-  grpc++
-  clangDaemon
+  clangdRemoteIndex
   )
Index: clang-tools-extra/clangd/index/remote/client/Client.cpp
===================================================================
--- 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));
-}
Index: clang-tools-extra/clangd/index/remote/client/CMakeLists.txt
===================================================================
--- 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++
-  )
Index: clang-tools-extra/clangd/index/remote/Marshalling.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clangd/index/remote/Marshalling.h
@@ -0,0 +1,38 @@
+//===--- 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::Expected<clangd::Symbol> fromProtobuf(const Symbol &Message,
+                                            llvm::UniqueStringSaver *Strings);
+llvm::Expected<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);
+
+} // namespace remote
+} // namespace clangd
+} // namespace clang
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANGD_INDEX_REMOTE_MARSHALLING_H
Index: clang-tools-extra/clangd/index/remote/Marshalling.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clangd/index/remote/Marshalling.cpp
@@ -0,0 +1,76 @@
+//===--- 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 "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::Expected<clangd::Symbol> fromProtobuf(const Symbol &Message,
+                                            llvm::UniqueStringSaver *Strings) {
+  return symbolFromYAML(Message.yaml_serializatiton(), Strings);
+}
+llvm::Expected<clangd::Ref> fromProtobuf(const Ref &Message,
+                                         llvm::UniqueStringSaver *Strings) {
+  return refFromYAML(Message.yaml_serializatiton(), Strings);
+}
+
+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;
+}
+
+} // namespace remote
+} // namespace clangd
+} // namespace clang
Index: clang-tools-extra/clangd/index/remote/Index.proto
===================================================================
--- clang-tools-extra/clangd/index/remote/Index.proto
+++ clang-tools-extra/clangd/index/remote/Index.proto
@@ -10,10 +10,52 @@
 
 package clang.clangd.remote;
 
-service Index {
-  rpc Lookup(LookupRequest) returns (stream LookupReply) {}
+service SymbolIndex {
+  rpc Lookup(LookupRequest) returns (stream Symbol) {}
+
+  rpc FuzzyFind(FuzzyFindRequest) returns (stream FuzzyFindReply) {}
+
+  rpc Refs(RefsRequest) returns (stream RefsReply) {}
+}
+
+message LookupRequest { repeated string ids = 1; }
+
+// FIXME(kirillbobyrev): Properly serialize symbol instead of passing YAML.
+message Symbol { string yaml_serializatiton = 1; }
+
+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;
 }
 
-message LookupRequest { string id = 1; }
+// 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 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 reference instead of passing YAML.
+message Ref { string yaml_serializatiton = 1; }
Index: clang-tools-extra/clangd/index/remote/Index.cpp
===================================================================
--- /dev/null
+++ clang-tools-extra/clangd/index/remote/Index.cpp
@@ -0,0 +1,120 @@
+//===--- Index.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 "Client.h"
+#include "Index.grpc.pb.h"
+#include "Logger.h"
+#include "Marshalling.h"
+#include "Trace.h"
+#include "grpcpp/grpcpp.h"
+#include "index/Serialization.h"
+#include "llvm/Support/YAMLTraits.h"
+
+namespace clang {
+namespace clangd {
+namespace remote {
+namespace {
+
+// FIXME(kirillbobyrev): Set deadlines for requests.
+template <typename RPCRequestT, typename ReplyT, typename ClangdRequestT>
+void streamRPC(
+    llvm::StringRef SpanName, SymbolIndex::Stub *Stub, ClangdRequestT Request,
+    std::function<std::unique_ptr<grpc::ClientReader<ReplyT>>(
+        SymbolIndex::Stub *, grpc::ClientContext *, const RPCRequestT &)>
+        RPCCall,
+    llvm::function_ref<void(ReplyT, llvm::UniqueStringSaver *)> Callback) {
+  trace::Span Tracer(SpanName);
+  const auto RPCRequest = toProtobuf(Request);
+  grpc::ClientContext Context;
+  auto Reader = RPCCall(Stub, &Context, RPCRequest);
+  llvm::BumpPtrAllocator Arena;
+  llvm::UniqueStringSaver Strings(Arena);
+  ReplyT Reply;
+  while (Reader->Read(&Reply))
+    Callback(Reply, &Strings);
+  SPAN_ATTACH(Tracer, "status", Reader->Finish().ok());
+}
+
+class IndexClient : public clangd::SymbolIndex {
+public:
+  IndexClient(llvm::StringRef Address)
+      : Stub(remote::SymbolIndex::NewStub(grpc::CreateChannel(
+            Address.str(), grpc::InsecureChannelCredentials()))) {}
+
+  void lookup(const clangd::LookupRequest &Request,
+              llvm::function_ref<void(const clangd::Symbol &)> Callback) const {
+    streamRPC<LookupRequest, Symbol>(
+        "Lookup RPC", Stub.get(), Request, &remote::SymbolIndex::Stub::Lookup,
+        [&](const Symbol &Message, llvm::UniqueStringSaver *Strings) {
+          auto Sym = fromProtobuf(Message, Strings);
+          if (!Sym)
+            elog("YAML parsing error: {0}", Sym.takeError());
+          Callback(*Sym);
+        });
+  }
+
+  bool
+  fuzzyFind(const clangd::FuzzyFindRequest &Request,
+            llvm::function_ref<void(const clangd::Symbol &)> Callback) const {
+    bool HasMore = false;
+    streamRPC<FuzzyFindRequest, FuzzyFindReply>(
+        "FuzzyFind RPC", Stub.get(), Request,
+        &remote::SymbolIndex::Stub::FuzzyFind,
+        [&](const FuzzyFindReply &Message, llvm::UniqueStringSaver *Strings) {
+          if (!Message.has_stream_result()) {
+            HasMore = Message.final_result();
+            return;
+          }
+          auto Sym = fromProtobuf(Message.stream_result(), Strings);
+          if (!Sym)
+            elog("YAML parsing error: {0}", Sym.takeError());
+          Callback(*Sym);
+        });
+    return HasMore;
+  }
+
+  bool refs(const clangd::RefsRequest &Request,
+            llvm::function_ref<void(const clangd::Ref &)> Callback) const {
+    bool HasMore = false;
+    streamRPC<RefsRequest, RefsReply>(
+        "Refs RPC", Stub.get(), Request, &remote::SymbolIndex::Stub::Refs,
+        [&](const RefsReply &Message, llvm::UniqueStringSaver *Strings) {
+          if (!Message.has_stream_result()) {
+            HasMore = Message.final_result();
+            return;
+          }
+          auto Reference = fromProtobuf(Message.stream_result(), Strings);
+          if (!Reference)
+            elog("YAML parsing error: {0}", Reference.takeError());
+          Callback(*Reference);
+        });
+    return HasMore;
+  }
+
+  // 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) {
+  return std::unique_ptr<clangd::SymbolIndex>(new IndexClient(Address));
+}
+
+} // namespace remote
+} // namespace clangd
+} // namespace clang
Index: clang-tools-extra/clangd/index/remote/Client.h
===================================================================
--- /dev/null
+++ clang-tools-extra/clangd/index/remote/Client.h
@@ -0,0 +1,37 @@
+//===--- Index.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
+//
+//===----------------------------------------------------------------------===//
+
+#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.
+///
+/// Caller is not blocked upon SymbolIndex request, the actual connection must
+/// happen upon the first request. RPCs have no timeout.
+///
+/// \returns nullptr if the address is not resolved during the function call.
+///
+/// NOTES:
+/// * Without remote index support (CLANGD_ENABLE_REMOTE=On in CMake) this
+///   function's implementation will not be compiled.
+/// * Even though the address is resolved during the function call, the server
+///   availability is only required during RPC calls.
+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
Index: clang-tools-extra/clangd/index/remote/CMakeLists.txt
===================================================================
--- clang-tools-extra/clangd/index/remote/CMakeLists.txt
+++ clang-tools-extra/clangd/index/remote/CMakeLists.txt
@@ -1,7 +1,21 @@
 generate_grpc_protos(RemoteIndexProtos "Index.proto")
-
-include_directories("${CMAKE_CURRENT_BINARY_DIR}")
+include_directories(${CMAKE_CURRENT_BINARY_DIR})
 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../)
 
-add_subdirectory(client)
+# 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_clang_library(clangdRemoteIndex
+  Index.cpp
+  Marshalling.cpp
+
+  LINK_LIBS
+  RemoteIndexProtos
+
+  protobuf
+  grpc++
+  clangDaemon
+  )
+
 add_subdirectory(server)
Index: clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp
===================================================================
--- clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp
+++ clang-tools-extra/clangd/index/dex/dexp/Dexp.cpp
@@ -11,9 +11,11 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "Features.inc.in"
 #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"
@@ -22,16 +24,27 @@
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/Signals.h"
 
+#ifdef CLANGD_ENABLE_REMOTE
+#include "Index.grpc.pb.h"
+#endif
+
 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("<INDEX LOCATION>"),
+                                         llvm::cl::Positional);
 
 llvm::cl::opt<std::string>
     ExecCommand("c", llvm::cl::desc("Command to execute and then exit"));
 
+#ifdef CLANGD_REMOTE
+// FIXME(kirillbobyrev): This is not working properly for some reason.
+llvm::cl::opt<bool>
+    RemoteMode("remote",
+               llvm::cl::desc("Connect to <INDEX LOCATION> remote index"));
+#endif
+
 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. The
@@ -150,7 +163,7 @@
     }
     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;
@@ -266,12 +279,17 @@
     {"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>},
 };
 
-std::unique_ptr<SymbolIndex> openIndex(llvm::StringRef Index) {
+std::unique_ptr<SymbolIndex> openIndex(llvm::StringRef Index,
+                                       bool ConnectToServer) {
+#ifdef CLANGD_REMOTE
+  return ConnectToServer ? remote::getClient(Index)
+                         : loadIndex(Index, /*UseDex=*/true);
+#else
   return loadIndex(Index, /*UseDex=*/true);
+#endif
 }
 
 bool runCommand(std::string Request, const SymbolIndex &Index) {
@@ -310,13 +328,15 @@
   using namespace clang::clangd;
 
   llvm::cl::ParseCommandLineOptions(argc, argv, Overview);
+  // Need to save RemoteMode because it will be reset to defaul by
+  // llvm::cl::ResettCommandLineParser().
+  const bool ConnectToServer = RemoteMode;
   llvm::cl::ResetCommandLineParser(); // We reuse it for REPL commands.
   llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
 
   std::unique_ptr<SymbolIndex> Index;
-  reportTime("Dex build", [&]() {
-    Index = openIndex(IndexPath);
-  });
+  reportTime("Dex build",
+             [&]() { Index = openIndex(IndexLocation, ConnectToServer); });
 
   if (!Index) {
     llvm::outs() << "Failed to open the index.\n";
Index: clang-tools-extra/clangd/index/dex/dexp/CMakeLists.txt
===================================================================
--- clang-tools-extra/clangd/index/dex/dexp/CMakeLists.txt
+++ clang-tools-extra/clangd/index/dex/dexp/CMakeLists.txt
@@ -17,3 +17,10 @@
   PRIVATE
   clangDaemon
   )
+
+if (CLANGD_ENABLE_REMOTE)
+  target_link_libraries(dexp
+    PRIVATE
+    clangdRemoteIndex
+    )
+endif()
Index: clang-tools-extra/clangd/index/YAMLSerialization.cpp
===================================================================
--- clang-tools-extra/clangd/index/YAMLSerialization.cpp
+++ clang-tools-extra/clangd/index/YAMLSerialization.cpp
@@ -418,5 +418,40 @@
   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 Ref from YAML: {0}", YAML),
+        llvm::inconvertibleErrorCode());
+  YAMLInput >> Deserialized;
+  return Deserialized;
+}
+
 } // namespace clangd
 } // namespace clang
Index: clang-tools-extra/clangd/index/Serialization.h
===================================================================
--- clang-tools-extra/clangd/index/Serialization.h
+++ clang-tools-extra/clangd/index/Serialization.h
@@ -77,6 +77,13 @@
 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.
Index: clang-tools-extra/clangd/Features.inc.in
===================================================================
--- clang-tools-extra/clangd/Features.inc.in
+++ clang-tools-extra/clangd/Features.inc.in
@@ -1 +1,2 @@
 #define CLANGD_BUILD_XPC @CLANGD_BUILD_XPC@
+#define CLANGD_REMOTE @CLANGD_ENABLE_REMOTE@
Index: clang-tools-extra/clangd/CMakeLists.txt
===================================================================
--- clang-tools-extra/clangd/CMakeLists.txt
+++ clang-tools-extra/clangd/CMakeLists.txt
@@ -140,7 +140,6 @@
 endif()
 add_subdirectory(tool)
 add_subdirectory(indexer)
-add_subdirectory(index/dex/dexp)
 
 if (LLVM_INCLUDE_BENCHMARKS)
   add_subdirectory(benchmarks)
@@ -162,3 +161,4 @@
   include(FindGRPC)
   add_subdirectory(index/remote)
 endif()
+add_subdirectory(index/dex/dexp)
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to