|
7 | 7 | */ |
8 | 8 |
|
9 | 9 | #include "glean/client/swift/GlassAccess.h" |
| 10 | +#include <folly/ExceptionString.h> |
| 11 | +#include <folly/String.h> |
| 12 | +#include <folly/coro/BlockingWait.h> |
| 13 | +#include <glog/logging.h> |
| 14 | +#include "servicerouter/client/cpp2/ServiceRouter.h" |
| 15 | + |
| 16 | +using namespace facebook; |
| 17 | +using apache::thrift::RpcOptions; |
| 18 | + |
| 19 | +const auto GlassTimeoutMs = 900; |
| 20 | + |
| 21 | +GlassAccess::GlassAccess() { |
| 22 | + auto params = facebook::servicerouter::ClientParams().setProcessingTimeoutMs( |
| 23 | + std::chrono::milliseconds(10000)); |
| 24 | + |
| 25 | + std::string connectionTier = "glean.glass"; |
| 26 | + client = |
| 27 | + servicerouter::cpp2::getClientFactory() |
| 28 | + .getSRClientUnique<apache::thrift::Client<::glean::GlassService>>( |
| 29 | + connectionTier, params); |
| 30 | +} |
10 | 31 |
|
11 | 32 | std::optional<protocol::LocationList> GlassAccess::usrToDefinition( |
12 | 33 | const std::string& usr) { |
13 | | - // Default implementation - always returns nullopt |
14 | | - return std::nullopt; |
| 34 | + std::string msg; |
| 35 | + |
| 36 | + // Create USRToDefinitionRequest |
| 37 | + ::glean::USRToDefinitionRequest request; |
| 38 | + request.usr_ref() = usr; |
| 39 | + request.repo_name_ref() = "fbsource"; |
| 40 | + |
| 41 | + // Call the Glass service to get symbol definition |
| 42 | + const auto result = this->runGlassMethod<::glean::USRSymbolDefinition>( |
| 43 | + "usrToDefinition", |
| 44 | + msg, |
| 45 | + [&]() -> folly::coro::Task<::glean::USRSymbolDefinition> { |
| 46 | + ::glean::RequestOptions ro; |
| 47 | + RpcOptions rpcOptions; |
| 48 | + rpcOptions.setTimeout(std::chrono::milliseconds(GlassTimeoutMs)); |
| 49 | + co_return co_await client->co_usrToDefinition(rpcOptions, request, ro); |
| 50 | + }); |
| 51 | + |
| 52 | + if (!result.has_value()) { |
| 53 | + return std::nullopt; |
| 54 | + } |
| 55 | + |
| 56 | + // Convert Glass result to protocol::LocationList |
| 57 | + protocol::LocationList locations; |
| 58 | + const auto& definition = result.value(); |
| 59 | + |
| 60 | + // Extract location from USRSymbolDefinition |
| 61 | + const auto& gleanLocation = definition.location_ref().value(); |
| 62 | + |
| 63 | + // Convert glean::LocationRange to protocol::Location |
| 64 | + // Access the range fields directly |
| 65 | + const auto& range = gleanLocation.range_ref().value(); |
| 66 | + |
| 67 | + protocol::Position start( |
| 68 | + static_cast<int>(range.lineBegin_ref().value()), |
| 69 | + static_cast<int>(range.columnBegin_ref().value())); |
| 70 | + protocol::Position end( |
| 71 | + static_cast<int>(range.lineEnd_ref().value()), |
| 72 | + static_cast<int>(range.columnEnd_ref().value())); |
| 73 | + protocol::Range protocolRange(start, end); |
| 74 | + |
| 75 | + // Create URI from repository and filepath using URI escaping |
| 76 | + std::string filepath = gleanLocation.filepath_ref().value(); |
| 77 | + std::string uri = "file://" + folly::uriEscape<std::string>(filepath); |
| 78 | + protocol::Location location(uri, protocolRange); |
| 79 | + |
| 80 | + locations.push_back(location); |
| 81 | + |
| 82 | + return locations; |
| 83 | +} |
| 84 | + |
| 85 | +template <typename T> |
| 86 | +std::optional<T> GlassAccess::runGlassMethod( |
| 87 | + const std::string& method, |
| 88 | + std::string& msg, |
| 89 | + folly::Function<folly::coro::Task<T>()> f) { |
| 90 | + try { |
| 91 | + return std::make_optional(folly::coro::blockingWait(f())); |
| 92 | + } catch (::glean::ServerException& ex) { |
| 93 | + msg += "::glean::ServerException(" + ex.message().value() + ");"; |
| 94 | + LOG(ERROR) << "EXCEPTION searching " << msg << "\n"; |
| 95 | + } catch (std::exception& ex) { |
| 96 | + msg += folly::exceptionStr(ex) + ";"; |
| 97 | + LOG(ERROR) << "EXCEPTION running " << method << ":" << ex.what() << ":" |
| 98 | + << msg << "\n"; |
| 99 | + } |
| 100 | + return {}; |
15 | 101 | } |
0 commit comments