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