clang-tools  11.0.0
Client.cpp
Go to the documentation of this file.
1 //===--- Client.cpp ----------------------------------------------*- C++-*-===//
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 <grpc++/grpc++.h>
10 
11 #include "Client.h"
12 #include "Index.grpc.pb.h"
13 #include "index/Index.h"
14 #include "index/Serialization.h"
16 #include "support/Logger.h"
17 #include "support/Trace.h"
18 #include "llvm/ADT/StringRef.h"
19 
20 #include <chrono>
21 
22 namespace clang {
23 namespace clangd {
24 namespace remote {
25 namespace {
26 
27 class IndexClient : public clangd::SymbolIndex {
28  template <typename RequestT, typename ReplyT>
29  using StreamingCall = std::unique_ptr<grpc::ClientReader<ReplyT>> (
30  remote::SymbolIndex::Stub::*)(grpc::ClientContext *, const RequestT &);
31 
32  template <typename ClangdRequestT, typename RequestT>
33  RequestT serializeRequest(ClangdRequestT Request) const {
34  return toProtobuf(Request);
35  }
36 
37  template <>
38  FuzzyFindRequest serializeRequest(clangd::FuzzyFindRequest Request) const {
39  return toProtobuf(Request, ProjectRoot);
40  }
41 
42  template <typename RequestT, typename ReplyT, typename ClangdRequestT,
43  typename CallbackT>
44  bool streamRPC(ClangdRequestT Request,
45  StreamingCall<RequestT, ReplyT> RPCCall,
46  CallbackT Callback) const {
47  bool FinalResult = false;
48  trace::Span Tracer(RequestT::descriptor()->name());
49  const auto RPCRequest = serializeRequest<ClangdRequestT, RequestT>(Request);
50  grpc::ClientContext Context;
51  std::chrono::system_clock::time_point Deadline =
52  std::chrono::system_clock::now() + DeadlineWaitingTime;
53  Context.set_deadline(Deadline);
54  auto Reader = (Stub.get()->*RPCCall)(&Context, RPCRequest);
55  llvm::BumpPtrAllocator Arena;
56  llvm::UniqueStringSaver Strings(Arena);
57  ReplyT Reply;
58  while (Reader->Read(&Reply)) {
59  if (!Reply.has_stream_result()) {
60  FinalResult = Reply.final_result();
61  continue;
62  }
63  auto Response =
64  fromProtobuf(Reply.stream_result(), &Strings, ProjectRoot);
65  if (!Response)
66  elog("Received invalid {0}", ReplyT::descriptor()->name());
67  Callback(*Response);
68  }
69  SPAN_ATTACH(Tracer, "status", Reader->Finish().ok());
70  return FinalResult;
71  }
72 
73 public:
74  IndexClient(
75  std::shared_ptr<grpc::Channel> Channel, llvm::StringRef ProjectRoot,
76  std::chrono::milliseconds DeadlineTime = std::chrono::milliseconds(1000))
77  : Stub(remote::SymbolIndex::NewStub(Channel)), ProjectRoot(ProjectRoot),
78  DeadlineWaitingTime(DeadlineTime) {}
79 
80  void lookup(const clangd::LookupRequest &Request,
81  llvm::function_ref<void(const clangd::Symbol &)> Callback) const {
82  streamRPC(Request, &remote::SymbolIndex::Stub::Lookup, Callback);
83  }
84 
85  bool
86  fuzzyFind(const clangd::FuzzyFindRequest &Request,
87  llvm::function_ref<void(const clangd::Symbol &)> Callback) const {
88  return streamRPC(Request, &remote::SymbolIndex::Stub::FuzzyFind, Callback);
89  }
90 
91  bool refs(const clangd::RefsRequest &Request,
92  llvm::function_ref<void(const clangd::Ref &)> Callback) const {
93  return streamRPC(Request, &remote::SymbolIndex::Stub::Refs, Callback);
94  }
95 
96  // FIXME(kirillbobyrev): Implement this.
97  void
98  relations(const clangd::RelationsRequest &,
99  llvm::function_ref<void(const SymbolID &, const clangd::Symbol &)>)
100  const {}
101 
102  // IndexClient does not take any space since the data is stored on the
103  // server.
104  size_t estimateMemoryUsage() const { return 0; }
105 
106 private:
107  std::unique_ptr<remote::SymbolIndex::Stub> Stub;
108  std::string ProjectRoot;
109  // Each request will be terminated if it takes too long.
110  std::chrono::milliseconds DeadlineWaitingTime;
111 };
112 
113 } // namespace
114 
115 std::unique_ptr<clangd::SymbolIndex> getClient(llvm::StringRef Address,
116  llvm::StringRef ProjectRoot) {
117  const auto Channel =
118  grpc::CreateChannel(Address.str(), grpc::InsecureChannelCredentials());
119  Channel->GetState(true);
120  return std::unique_ptr<clangd::SymbolIndex>(
121  new IndexClient(Channel, ProjectRoot));
122 }
123 
124 } // namespace remote
125 } // namespace clangd
126 } // namespace clang
Client.h
Refs
RefSlab Refs
Definition: SymbolCollectorTests.cpp:296
Tracer
std::unique_ptr< trace::EventTracer > Tracer
Definition: TraceTests.cpp:163
Index.h
Marshalling.h
clang::clangd::remote::fromProtobuf
clangd::FuzzyFindRequest fromProtobuf(const FuzzyFindRequest *Request, llvm::StringRef IndexRoot)
Definition: Marshalling.cpp:126
Trace.h
clang::clangd::FuzzyFindRequest
Definition: Index.h:26
clang::clangd::Deadline
A point in time we can wait for.
Definition: Threading.h:58
lit.name
name
Definition: test/lit.cfg.py:6
Logger.h
clang::clangd::Symbol
The class presents a C++ symbol, e.g.
Definition: Symbol.h:36
clang::clangd::remote::toProtobuf
LookupRequest toProtobuf(const clangd::LookupRequest &From)
Definition: Marshalling.cpp:208
SPAN_ATTACH
#define SPAN_ATTACH(S, Name, Expr)
Attach a key-value pair to a Span event.
Definition: Trace.h:154
clang::clangd::remote::getClient
std::unique_ptr< clangd::SymbolIndex > getClient(llvm::StringRef Address, llvm::StringRef ProjectRoot)
Returns an SymbolIndex client that passes requests to remote index located at Address.
Definition: Client.cpp:115
Serialization.h
clang::clangd::lookup
std::vector< std::string > lookup(const SymbolIndex &I, llvm::ArrayRef< SymbolID > IDs)
Definition: TestIndex.cpp:106
clang::clangd::SymbolIndex
Interface for symbol indexes that can be used for searching or matching symbols among a set of symbol...
Definition: Index.h:85
clang::clangd::LookupRequest
Definition: Index.h:63
Strings
std::vector< llvm::StringRef > Strings
Definition: Serialization.cpp:195
clang::clangd::Ref
Represents a symbol occurrence in the source file.
Definition: Ref.h:87
clang
===– Representation.cpp - ClangDoc Representation --------—*- C++ -*-===//
Definition: ApplyReplacements.h:27
Arena
llvm::BumpPtrAllocator Arena
Definition: Serialization.cpp:194
clang::clangd::Callback
llvm::unique_function< void(llvm::Expected< T >)> Callback
A Callback<T> is a void function that accepts Expected<T>.
Definition: Function.h:28
clang::clangd::RelationsRequest
Definition: Index.h:76
clang::clangd::elog
void elog(const char *Fmt, Ts &&... Vals)
Definition: Logger.h:56
clang::clangd::SymbolID
Definition: SymbolID.h:31
clang::clangd::RefsRequest
Definition: Index.h:67
clang::clangd::Context
A context is an immutable container for per-request data that must be propagated through layers that ...
Definition: Context.h:69
clang::clangd::trace::Span
Records an event whose duration is the lifetime of the Span object.
Definition: Trace.h:135