clang-tools  11.0.0
Server.cpp
Go to the documentation of this file.
1 //===--- Server.cpp - gRPC-based Remote Index Server ---------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "index/Index.h"
10 #include "index/Serialization.h"
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/Support/CommandLine.h"
14 #include "llvm/Support/Path.h"
15 #include "llvm/Support/Signals.h"
16 
17 #include <grpc++/grpc++.h>
18 #include <grpc++/health_check_service_interface.h>
19 
20 #include "Index.grpc.pb.h"
21 
22 namespace clang {
23 namespace clangd {
24 namespace remote {
25 namespace {
26 
27 static constexpr char Overview[] = R"(
28 This is an experimental remote index implementation. The server opens Dex and
29 awaits gRPC lookup requests from the client.
30 )";
31 
32 llvm::cl::opt<std::string> IndexPath(llvm::cl::desc("<INDEX FILE>"),
33  llvm::cl::Positional, llvm::cl::Required);
34 
35 llvm::cl::opt<std::string> IndexRoot(llvm::cl::desc("<PROJECT ROOT>"),
36  llvm::cl::Positional, llvm::cl::Required);
37 
38 llvm::cl::opt<std::string> ServerAddress(
39  "server-address", llvm::cl::init("0.0.0.0:50051"),
40  llvm::cl::desc("Address of the invoked server. Defaults to 0.0.0.0:50051"));
41 
42 std::unique_ptr<clangd::SymbolIndex> openIndex(llvm::StringRef Index) {
43  return loadIndex(Index, /*UseIndex=*/true);
44 }
45 
46 class RemoteIndexServer final : public SymbolIndex::Service {
47 public:
48  RemoteIndexServer(std::unique_ptr<clangd::SymbolIndex> Index,
49  llvm::StringRef IndexRoot)
50  : Index(std::move(Index)) {
51  llvm::SmallString<256> NativePath = IndexRoot;
52  llvm::sys::path::native(NativePath);
53  IndexedProjectRoot = std::string(NativePath);
54  }
55 
56 private:
57  grpc::Status Lookup(grpc::ServerContext *Context,
58  const LookupRequest *Request,
59  grpc::ServerWriter<LookupReply> *Reply) override {
60  clangd::LookupRequest Req;
61  for (const auto &ID : Request->ids()) {
62  auto SID = SymbolID::fromStr(StringRef(ID));
63  if (!SID)
64  return grpc::Status::CANCELLED;
65  Req.IDs.insert(*SID);
66  }
67  Index->lookup(Req, [&](const clangd::Symbol &Sym) {
68  LookupReply NextMessage;
69  *NextMessage.mutable_stream_result() =
70  toProtobuf(Sym, IndexedProjectRoot);
71  Reply->Write(NextMessage);
72  });
73  LookupReply LastMessage;
74  LastMessage.set_final_result(true);
75  Reply->Write(LastMessage);
76  return grpc::Status::OK;
77  }
78 
79  grpc::Status FuzzyFind(grpc::ServerContext *Context,
80  const FuzzyFindRequest *Request,
81  grpc::ServerWriter<FuzzyFindReply> *Reply) override {
82  const auto Req = fromProtobuf(Request, IndexedProjectRoot);
83  bool HasMore = Index->fuzzyFind(Req, [&](const clangd::Symbol &Sym) {
84  FuzzyFindReply NextMessage;
85  *NextMessage.mutable_stream_result() =
86  toProtobuf(Sym, IndexedProjectRoot);
87  Reply->Write(NextMessage);
88  });
89  FuzzyFindReply LastMessage;
90  LastMessage.set_final_result(HasMore);
91  Reply->Write(LastMessage);
92  return grpc::Status::OK;
93  }
94 
95  grpc::Status Refs(grpc::ServerContext *Context, const RefsRequest *Request,
96  grpc::ServerWriter<RefsReply> *Reply) override {
97  clangd::RefsRequest Req;
98  for (const auto &ID : Request->ids()) {
99  auto SID = SymbolID::fromStr(StringRef(ID));
100  if (!SID)
101  return grpc::Status::CANCELLED;
102  Req.IDs.insert(*SID);
103  }
104  bool HasMore = Index->refs(Req, [&](const clangd::Ref &Reference) {
105  RefsReply NextMessage;
106  *NextMessage.mutable_stream_result() = toProtobuf(Reference, IndexRoot);
107  Reply->Write(NextMessage);
108  });
109  RefsReply LastMessage;
110  LastMessage.set_final_result(HasMore);
111  Reply->Write(LastMessage);
112  return grpc::Status::OK;
113  }
114 
115  std::unique_ptr<clangd::SymbolIndex> Index;
116  std::string IndexedProjectRoot;
117 };
118 
119 void runServer(std::unique_ptr<clangd::SymbolIndex> Index,
120  const std::string &ServerAddress) {
121  RemoteIndexServer Service(std::move(Index), IndexRoot);
122 
123  grpc::EnableDefaultHealthCheckService(true);
124  grpc::ServerBuilder Builder;
125  Builder.AddListeningPort(ServerAddress, grpc::InsecureServerCredentials());
126  Builder.RegisterService(&Service);
127  std::unique_ptr<grpc::Server> Server(Builder.BuildAndStart());
128  llvm::outs() << "Server listening on " << ServerAddress << '\n';
129 
130  Server->Wait();
131 }
132 
133 } // namespace
134 } // namespace remote
135 } // namespace clangd
136 } // namespace clang
137 
138 int main(int argc, char *argv[]) {
139  using namespace clang::clangd::remote;
140  llvm::cl::ParseCommandLineOptions(argc, argv, Overview);
141  llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
142 
143  if (!llvm::sys::path::is_absolute(IndexRoot)) {
144  llvm::outs() << "Index root should be an absolute path.\n";
145  return -1;
146  }
147 
148  std::unique_ptr<clang::clangd::SymbolIndex> Index = openIndex(IndexPath);
149 
150  if (!Index) {
151  llvm::outs() << "Failed to open the index.\n";
152  return -1;
153  }
154 
155  runServer(std::move(Index), ServerAddress);
156 }
Refs
RefSlab Refs
Definition: SymbolCollectorTests.cpp:296
Index.h
Marshalling.h
clang::clangd::remote::fromProtobuf
clangd::FuzzyFindRequest fromProtobuf(const FuzzyFindRequest *Request, llvm::StringRef IndexRoot)
Definition: Marshalling.cpp:126
clang::clangd::remote
Definition: Client.cpp:24
Builder
CodeCompletionBuilder Builder
Definition: CodeCompletionStringsTests.cpp:35
clang::clangd::loadIndex
std::unique_ptr< SymbolIndex > loadIndex(llvm::StringRef SymbolFilename, bool UseDex)
Definition: Serialization.cpp:668
clang::clangd::remote::toProtobuf
LookupRequest toProtobuf(const clangd::LookupRequest &From)
Definition: Marshalling.cpp:208
Serialization.h
Index
const SymbolIndex * Index
Definition: Dexp.cpp:95
clang::clangd::SymbolID::fromStr
static llvm::Expected< SymbolID > fromStr(llvm::StringRef)
Definition: SymbolID.cpp:35
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
main
int main(int argc, char *argv[])
Definition: Server.cpp:138