1 //===--- PathMapping.h - apply path mappings to LSP messages -===// 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 #include "llvm/ADT/Optional.h" 9 #include "llvm/ADT/StringRef.h" 10 #include "llvm/Support/Error.h" 11 #include "llvm/Support/JSON.h" 12 #include "llvm/Support/raw_ostream.h" 13 #include <memory> 14 #include <string> 15 #include <vector> 16 17 namespace clang { 18 namespace clangd { 19 20 class Transport; 21 22 /// PathMappings are a collection of paired client and server paths. 23 /// These pairs are used to alter file:// URIs appearing in inbound and outbound 24 /// LSP messages, as the client's environment may have source files or 25 /// dependencies at different locations than the server. Therefore, both 26 /// paths are stored as they appear in file URI bodies, e.g. /usr/include or 27 /// /C:/config 28 /// 29 /// For example, if the mappings were {{"/home/user", "/workarea"}}, then 30 /// a client-to-server LSP message would have file:///home/user/foo.cpp 31 /// remapped to file:///workarea/foo.cpp, and the same would happen for replies 32 /// (in the opposite order). 33 struct PathMapping { 34 std::string ClientPath; 35 std::string ServerPath; 36 enum class Direction { ClientToServer, ServerToClient }; 37 }; 38 using PathMappings = std::vector<PathMapping>; 39 40 llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const PathMapping &M); 41 42 /// Parse the command line \p RawPathMappings (e.g. "/client=/server") into 43 /// pairs. Returns an error if the mappings are malformed, i.e. not absolute or 44 /// not a proper pair. 45 llvm::Expected<PathMappings> parsePathMappings(llvm::StringRef RawPathMappings); 46 47 /// Returns a modified \p S with the first matching path in \p Mappings 48 /// substituted, if applicable 49 llvm::Optional<std::string> doPathMapping(llvm::StringRef S, 50 PathMapping::Direction Dir, 51 const PathMappings &Mappings); 52 53 /// Applies the \p Mappings to all the file:// URIs in \p Params. 54 /// NOTE: The first matching mapping will be applied, otherwise \p Params will 55 /// be untouched. 56 void applyPathMappings(llvm::json::Value &Params, PathMapping::Direction Dir, 57 const PathMappings &Mappings); 58 59 /// Creates a wrapping transport over \p Transp that applies the \p Mappings to 60 /// all inbound and outbound LSP messages. All calls are then delegated to the 61 /// regular transport (e.g. XPC, JSON). 62 std::unique_ptr<Transport> 63 createPathMappingTransport(std::unique_ptr<Transport> Transp, 64 PathMappings Mappings); 65 66 } // namespace clangd 67 } // namespace clang 68