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