xref: /llvm-project/lldb/tools/lldb-dap/JSONUtils.h (revision faaf2dbf6d2c080d817c4dfe9f888e456418bc2e)
101263c6cSJonas Devlieghere //===-- JSONUtils.h ---------------------------------------------*- C++ -*-===//
201263c6cSJonas Devlieghere //
301263c6cSJonas Devlieghere // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
401263c6cSJonas Devlieghere // See https://llvm.org/LICENSE.txt for license information.
501263c6cSJonas Devlieghere // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
601263c6cSJonas Devlieghere //
701263c6cSJonas Devlieghere //===----------------------------------------------------------------------===//
801263c6cSJonas Devlieghere 
901263c6cSJonas Devlieghere #ifndef LLDB_TOOLS_LLDB_DAP_JSONUTILS_H
1001263c6cSJonas Devlieghere #define LLDB_TOOLS_LLDB_DAP_JSONUTILS_H
1101263c6cSJonas Devlieghere 
1201263c6cSJonas Devlieghere #include "DAPForward.h"
13b99d4112SJohn Harrison #include "lldb/API/SBCompileUnit.h"
14b99d4112SJohn Harrison #include "lldb/API/SBFileSpec.h"
15*faaf2dbfSJohn Harrison #include "lldb/API/SBFormat.h"
16b99d4112SJohn Harrison #include "lldb/API/SBLineEntry.h"
17b99d4112SJohn Harrison #include "lldb/API/SBType.h"
18b99d4112SJohn Harrison #include "lldb/API/SBValue.h"
19b99d4112SJohn Harrison #include "lldb/lldb-types.h"
2001263c6cSJonas Devlieghere #include "llvm/ADT/StringRef.h"
2101263c6cSJonas Devlieghere #include "llvm/Support/JSON.h"
2201263c6cSJonas Devlieghere #include <cstdint>
2301263c6cSJonas Devlieghere #include <optional>
24b99d4112SJohn Harrison #include <string>
25d4c17891SDa-Viper #include <unordered_map>
26b99d4112SJohn Harrison #include <utility>
27b99d4112SJohn Harrison #include <vector>
2801263c6cSJonas Devlieghere 
2901263c6cSJonas Devlieghere namespace lldb_dap {
3001263c6cSJonas Devlieghere 
3101263c6cSJonas Devlieghere /// Emplace a StringRef in a json::Object after enusring that the
3201263c6cSJonas Devlieghere /// string is valid UTF8. If not, first call llvm::json::fixUTF8
3301263c6cSJonas Devlieghere /// before emplacing.
3401263c6cSJonas Devlieghere ///
3501263c6cSJonas Devlieghere /// \param[in] obj
3601263c6cSJonas Devlieghere ///     A JSON object that we will attempt to emplace the value in
3701263c6cSJonas Devlieghere ///
3801263c6cSJonas Devlieghere /// \param[in] key
3901263c6cSJonas Devlieghere ///     The key to use when emplacing the value
4001263c6cSJonas Devlieghere ///
4101263c6cSJonas Devlieghere /// \param[in] str
4201263c6cSJonas Devlieghere ///     The string to emplace
4301263c6cSJonas Devlieghere void EmplaceSafeString(llvm::json::Object &obj, llvm::StringRef key,
4401263c6cSJonas Devlieghere                        llvm::StringRef str);
4501263c6cSJonas Devlieghere 
4601263c6cSJonas Devlieghere /// Extract simple values as a string.
4701263c6cSJonas Devlieghere ///
4801263c6cSJonas Devlieghere /// \param[in] value
4901263c6cSJonas Devlieghere ///     A JSON value to extract the string from.
5001263c6cSJonas Devlieghere ///
5101263c6cSJonas Devlieghere /// \return
5201263c6cSJonas Devlieghere ///     A llvm::StringRef that contains the string value, or an empty
5301263c6cSJonas Devlieghere ///     string if \a value isn't a string.
5401263c6cSJonas Devlieghere llvm::StringRef GetAsString(const llvm::json::Value &value);
5501263c6cSJonas Devlieghere 
5601263c6cSJonas Devlieghere /// Extract the string value for the specified key from the
5701263c6cSJonas Devlieghere /// specified object.
5801263c6cSJonas Devlieghere ///
5901263c6cSJonas Devlieghere /// \param[in] obj
6001263c6cSJonas Devlieghere ///     A JSON object that we will attempt to extract the value from
6101263c6cSJonas Devlieghere ///
6201263c6cSJonas Devlieghere /// \param[in] key
6301263c6cSJonas Devlieghere ///     The key to use when extracting the value
6401263c6cSJonas Devlieghere ///
6510664813SWalter Erquinigo /// \param[in] defaultValue
6610664813SWalter Erquinigo ///     The default value to return if the key is not present
6710664813SWalter Erquinigo ///
6801263c6cSJonas Devlieghere /// \return
6901263c6cSJonas Devlieghere ///     A llvm::StringRef that contains the string value for the
7010664813SWalter Erquinigo ///     specified \a key, or the default value if there is no key that
7101263c6cSJonas Devlieghere ///     matches or if the value is not a string.
7210664813SWalter Erquinigo llvm::StringRef GetString(const llvm::json::Object &obj, llvm::StringRef key,
7310664813SWalter Erquinigo                           llvm::StringRef defaultValue = {});
7410664813SWalter Erquinigo llvm::StringRef GetString(const llvm::json::Object *obj, llvm::StringRef key,
7510664813SWalter Erquinigo                           llvm::StringRef defaultValue = {});
7601263c6cSJonas Devlieghere 
7701263c6cSJonas Devlieghere /// Extract the unsigned integer value for the specified key from
7801263c6cSJonas Devlieghere /// the specified object.
7901263c6cSJonas Devlieghere ///
8001263c6cSJonas Devlieghere /// \param[in] obj
8101263c6cSJonas Devlieghere ///     A JSON object that we will attempt to extract the value from
8201263c6cSJonas Devlieghere ///
8301263c6cSJonas Devlieghere /// \param[in] key
8401263c6cSJonas Devlieghere ///     The key to use when extracting the value
8501263c6cSJonas Devlieghere ///
8601263c6cSJonas Devlieghere /// \return
8701263c6cSJonas Devlieghere ///     The unsigned integer value for the specified \a key, or
8801263c6cSJonas Devlieghere ///     \a fail_value  if there is no key that matches or if the
8901263c6cSJonas Devlieghere ///     value is not an integer.
9001263c6cSJonas Devlieghere uint64_t GetUnsigned(const llvm::json::Object &obj, llvm::StringRef key,
9101263c6cSJonas Devlieghere                      uint64_t fail_value);
9201263c6cSJonas Devlieghere uint64_t GetUnsigned(const llvm::json::Object *obj, llvm::StringRef key,
9301263c6cSJonas Devlieghere                      uint64_t fail_value);
9401263c6cSJonas Devlieghere 
9501263c6cSJonas Devlieghere /// Extract the boolean value for the specified key from the
9601263c6cSJonas Devlieghere /// specified object.
9701263c6cSJonas Devlieghere ///
9801263c6cSJonas Devlieghere /// \param[in] obj
9901263c6cSJonas Devlieghere ///     A JSON object that we will attempt to extract the value from
10001263c6cSJonas Devlieghere ///
10101263c6cSJonas Devlieghere /// \param[in] key
10201263c6cSJonas Devlieghere ///     The key to use when extracting the value
10301263c6cSJonas Devlieghere ///
10401263c6cSJonas Devlieghere /// \return
10501263c6cSJonas Devlieghere ///     The boolean value for the specified \a key, or \a fail_value
10601263c6cSJonas Devlieghere ///     if there is no key that matches or if the value is not a
10701263c6cSJonas Devlieghere ///     boolean value of an integer.
10801263c6cSJonas Devlieghere bool GetBoolean(const llvm::json::Object &obj, llvm::StringRef key,
10901263c6cSJonas Devlieghere                 bool fail_value);
11001263c6cSJonas Devlieghere bool GetBoolean(const llvm::json::Object *obj, llvm::StringRef key,
11101263c6cSJonas Devlieghere                 bool fail_value);
11201263c6cSJonas Devlieghere 
11301263c6cSJonas Devlieghere /// Extract the signed integer for the specified key from the
11401263c6cSJonas Devlieghere /// specified object.
11501263c6cSJonas Devlieghere ///
11601263c6cSJonas Devlieghere /// \param[in] obj
11701263c6cSJonas Devlieghere ///     A JSON object that we will attempt to extract the value from
11801263c6cSJonas Devlieghere ///
11901263c6cSJonas Devlieghere /// \param[in] key
12001263c6cSJonas Devlieghere ///     The key to use when extracting the value
12101263c6cSJonas Devlieghere ///
12201263c6cSJonas Devlieghere /// \return
12301263c6cSJonas Devlieghere ///     The signed integer value for the specified \a key, or
12401263c6cSJonas Devlieghere ///     \a fail_value if there is no key that matches or if the
12501263c6cSJonas Devlieghere ///     value is not an integer.
12601263c6cSJonas Devlieghere int64_t GetSigned(const llvm::json::Object &obj, llvm::StringRef key,
12701263c6cSJonas Devlieghere                   int64_t fail_value);
12801263c6cSJonas Devlieghere int64_t GetSigned(const llvm::json::Object *obj, llvm::StringRef key,
12901263c6cSJonas Devlieghere                   int64_t fail_value);
13001263c6cSJonas Devlieghere 
13101263c6cSJonas Devlieghere /// Check if the specified key exists in the specified object.
13201263c6cSJonas Devlieghere ///
13301263c6cSJonas Devlieghere /// \param[in] obj
13401263c6cSJonas Devlieghere ///     A JSON object that we will attempt to extract the value from
13501263c6cSJonas Devlieghere ///
13601263c6cSJonas Devlieghere /// \param[in] key
13701263c6cSJonas Devlieghere ///     The key to check for
13801263c6cSJonas Devlieghere ///
13901263c6cSJonas Devlieghere /// \return
14001263c6cSJonas Devlieghere ///     \b True if the key exists in the \a obj, \b False otherwise.
14101263c6cSJonas Devlieghere bool ObjectContainsKey(const llvm::json::Object &obj, llvm::StringRef key);
14201263c6cSJonas Devlieghere 
1433acb1eacSAdrian Vogelsgesang /// Encodes a memory reference
1443acb1eacSAdrian Vogelsgesang std::string EncodeMemoryReference(lldb::addr_t addr);
1453acb1eacSAdrian Vogelsgesang 
1463acb1eacSAdrian Vogelsgesang /// Decodes a memory reference
1473acb1eacSAdrian Vogelsgesang std::optional<lldb::addr_t>
1483acb1eacSAdrian Vogelsgesang DecodeMemoryReference(llvm::StringRef memoryReference);
1493acb1eacSAdrian Vogelsgesang 
15001263c6cSJonas Devlieghere /// Extract an array of strings for the specified key from an object.
15101263c6cSJonas Devlieghere ///
15201263c6cSJonas Devlieghere /// String values in the array will be extracted without any quotes
15301263c6cSJonas Devlieghere /// around them. Numbers and Booleans will be converted into
15401263c6cSJonas Devlieghere /// strings. Any NULL, array or objects values in the array will be
15501263c6cSJonas Devlieghere /// ignored.
15601263c6cSJonas Devlieghere ///
15701263c6cSJonas Devlieghere /// \param[in] obj
15801263c6cSJonas Devlieghere ///     A JSON object that we will attempt to extract the array from
15901263c6cSJonas Devlieghere ///
16001263c6cSJonas Devlieghere /// \param[in] key
16101263c6cSJonas Devlieghere ///     The key to use when extracting the value
16201263c6cSJonas Devlieghere ///
16301263c6cSJonas Devlieghere /// \return
16401263c6cSJonas Devlieghere ///     An array of string values for the specified \a key, or
16501263c6cSJonas Devlieghere ///     \a fail_value if there is no key that matches or if the
16601263c6cSJonas Devlieghere ///     value is not an array or all items in the array are not
16701263c6cSJonas Devlieghere ///     strings, numbers or booleans.
16801263c6cSJonas Devlieghere std::vector<std::string> GetStrings(const llvm::json::Object *obj,
16901263c6cSJonas Devlieghere                                     llvm::StringRef key);
17001263c6cSJonas Devlieghere 
171d4c17891SDa-Viper /// Extract an object of key value strings for the specified key from an object.
172d4c17891SDa-Viper ///
173d4c17891SDa-Viper /// String values in the object will be extracted without any quotes
174d4c17891SDa-Viper /// around them. Numbers and Booleans will be converted into
175d4c17891SDa-Viper /// strings. Any NULL, array or objects values in the array will be
176d4c17891SDa-Viper /// ignored.
177d4c17891SDa-Viper ///
178d4c17891SDa-Viper /// \param[in] obj
179d4c17891SDa-Viper ///     A JSON object that we will attempt to extract the array from
180d4c17891SDa-Viper ///
181d4c17891SDa-Viper /// \param[in] key
182d4c17891SDa-Viper ///     The key to use when extracting the value
183d4c17891SDa-Viper ///
184d4c17891SDa-Viper /// \return
185d4c17891SDa-Viper ///     An object of key value strings for the specified \a key, or
186d4c17891SDa-Viper ///     \a fail_value if there is no key that matches or if the
187d4c17891SDa-Viper ///     value is not an object or key and values in the object are not
188d4c17891SDa-Viper ///     strings, numbers or booleans.
189d4c17891SDa-Viper std::unordered_map<std::string, std::string>
190d4c17891SDa-Viper GetStringMap(const llvm::json::Object &obj, llvm::StringRef key);
191d4c17891SDa-Viper 
19201263c6cSJonas Devlieghere /// Fill a response object given the request object.
19301263c6cSJonas Devlieghere ///
19401263c6cSJonas Devlieghere /// The \a response object will get its "type" set to "response",
19501263c6cSJonas Devlieghere /// the "seq" set to zero, "response_seq" set to the "seq" value from
19601263c6cSJonas Devlieghere /// \a request, "command" set to the "command" from \a request,
19701263c6cSJonas Devlieghere /// and "success" set to true.
19801263c6cSJonas Devlieghere ///
19901263c6cSJonas Devlieghere /// \param[in] request
20001263c6cSJonas Devlieghere ///     The request object received from a call to DAP::ReadJSON().
20101263c6cSJonas Devlieghere ///
20201263c6cSJonas Devlieghere /// \param[in,out] response
20301263c6cSJonas Devlieghere ///     An empty llvm::json::Object object that will be filled
20401263c6cSJonas Devlieghere ///     in as noted in description.
20501263c6cSJonas Devlieghere void FillResponse(const llvm::json::Object &request,
20601263c6cSJonas Devlieghere                   llvm::json::Object &response);
20701263c6cSJonas Devlieghere 
20801263c6cSJonas Devlieghere /// Converts \a bp to a JSON value and appends the first valid location to the
20901263c6cSJonas Devlieghere /// \a breakpoints array.
21001263c6cSJonas Devlieghere ///
21101263c6cSJonas Devlieghere /// \param[in] bp
21201263c6cSJonas Devlieghere ///     A LLDB breakpoint object which will get the first valid location
21301263c6cSJonas Devlieghere ///     extracted and converted into a JSON object in the \a breakpoints array
21401263c6cSJonas Devlieghere ///
21501263c6cSJonas Devlieghere /// \param[in] breakpoints
21601263c6cSJonas Devlieghere ///     A JSON array that will get a llvm::json::Value for \a bp
21701263c6cSJonas Devlieghere ///     appended to it.
21801263c6cSJonas Devlieghere ///
21901263c6cSJonas Devlieghere /// \param[in] request_path
22001263c6cSJonas Devlieghere ///     An optional source path to use when creating the "Source" object of this
22101263c6cSJonas Devlieghere ///     breakpoint. If not specified, the "Source" object is created from the
22201263c6cSJonas Devlieghere ///     breakpoint's address' LineEntry. It is useful to ensure the same source
22301263c6cSJonas Devlieghere ///     paths provided by the setBreakpoints request are returned to the IDE.
22401263c6cSJonas Devlieghere ///
22501263c6cSJonas Devlieghere /// \param[in] request_line
22601263c6cSJonas Devlieghere ///     An optional line to use when creating the "Breakpoint" object to append.
22701263c6cSJonas Devlieghere ///     It is used if the breakpoint has no valid locations.
22801263c6cSJonas Devlieghere ///     It is useful to ensure the same line
22901263c6cSJonas Devlieghere ///     provided by the setBreakpoints request are returned to the IDE as a
23001263c6cSJonas Devlieghere ///     fallback.
23101263c6cSJonas Devlieghere void AppendBreakpoint(
232d58c128bSZequan Wu     BreakpointBase *bp, llvm::json::Array &breakpoints,
23301263c6cSJonas Devlieghere     std::optional<llvm::StringRef> request_path = std::nullopt,
23401263c6cSJonas Devlieghere     std::optional<uint32_t> request_line = std::nullopt);
23501263c6cSJonas Devlieghere 
23601263c6cSJonas Devlieghere /// Converts breakpoint location to a debug adaptor protocol "Breakpoint".
23701263c6cSJonas Devlieghere ///
23801263c6cSJonas Devlieghere /// \param[in] bp
23901263c6cSJonas Devlieghere ///     A LLDB breakpoint object to convert into a JSON value
24001263c6cSJonas Devlieghere ///
24101263c6cSJonas Devlieghere /// \param[in] request_path
24201263c6cSJonas Devlieghere ///     An optional source path to use when creating the "Source" object of this
24301263c6cSJonas Devlieghere ///     breakpoint. If not specified, the "Source" object is created from the
24401263c6cSJonas Devlieghere ///     breakpoint's address' LineEntry. It is useful to ensure the same source
24501263c6cSJonas Devlieghere ///     paths provided by the setBreakpoints request are returned to the IDE.
24601263c6cSJonas Devlieghere ///
24701263c6cSJonas Devlieghere /// \param[in] request_line
24801263c6cSJonas Devlieghere ///     An optional line to use when creating the resulting "Breakpoint" object.
24901263c6cSJonas Devlieghere ///     It is used if the breakpoint has no valid locations.
25001263c6cSJonas Devlieghere ///     It is useful to ensure the same line
25101263c6cSJonas Devlieghere ///     provided by the setBreakpoints request are returned to the IDE as a
25201263c6cSJonas Devlieghere ///     fallback.
25301263c6cSJonas Devlieghere ///
25401263c6cSJonas Devlieghere /// \param[in] request_column
25501263c6cSJonas Devlieghere ///     An optional column to use when creating the resulting "Breakpoint"
25601263c6cSJonas Devlieghere ///     object. It is used if the breakpoint has no valid locations. It is
25701263c6cSJonas Devlieghere ///     useful to ensure the same column provided by the setBreakpoints request
25801263c6cSJonas Devlieghere ///     are returned to the IDE as a fallback.
25901263c6cSJonas Devlieghere ///
26001263c6cSJonas Devlieghere /// \return
26101263c6cSJonas Devlieghere ///     A "Breakpoint" JSON object with that follows the formal JSON
26201263c6cSJonas Devlieghere ///     definition outlined by Microsoft.
26301263c6cSJonas Devlieghere llvm::json::Value
264d58c128bSZequan Wu CreateBreakpoint(BreakpointBase *bp,
26501263c6cSJonas Devlieghere                  std::optional<llvm::StringRef> request_path = std::nullopt,
26601263c6cSJonas Devlieghere                  std::optional<uint32_t> request_line = std::nullopt,
26701263c6cSJonas Devlieghere                  std::optional<uint32_t> request_column = std::nullopt);
26801263c6cSJonas Devlieghere 
26901263c6cSJonas Devlieghere /// Converts a LLDB module to a VS Code DAP module for use in "modules" events.
27001263c6cSJonas Devlieghere ///
271*faaf2dbfSJohn Harrison /// \param[in] target
272*faaf2dbfSJohn Harrison ///     A LLDB target object to convert into a JSON value.
273*faaf2dbfSJohn Harrison ///
27401263c6cSJonas Devlieghere /// \param[in] module
27501263c6cSJonas Devlieghere ///     A LLDB module object to convert into a JSON value
27601263c6cSJonas Devlieghere ///
27701263c6cSJonas Devlieghere /// \return
27801263c6cSJonas Devlieghere ///     A "Module" JSON object with that follows the formal JSON
27901263c6cSJonas Devlieghere ///     definition outlined by Microsoft.
280*faaf2dbfSJohn Harrison llvm::json::Value CreateModule(lldb::SBTarget &target, lldb::SBModule &module);
28101263c6cSJonas Devlieghere 
28201263c6cSJonas Devlieghere /// Create a "Event" JSON object using \a event_name as the event name
28301263c6cSJonas Devlieghere ///
28401263c6cSJonas Devlieghere /// \param[in] event_name
28501263c6cSJonas Devlieghere ///     The string value to use for the "event" key in the JSON object.
28601263c6cSJonas Devlieghere ///
28701263c6cSJonas Devlieghere /// \return
28801263c6cSJonas Devlieghere ///     A "Event" JSON object with that follows the formal JSON
28901263c6cSJonas Devlieghere ///     definition outlined by Microsoft.
29001263c6cSJonas Devlieghere llvm::json::Object CreateEventObject(const llvm::StringRef event_name);
29101263c6cSJonas Devlieghere 
29201263c6cSJonas Devlieghere /// Create a "ExceptionBreakpointsFilter" JSON object as described in
29301263c6cSJonas Devlieghere /// the debug adaptor definition.
29401263c6cSJonas Devlieghere ///
29501263c6cSJonas Devlieghere /// \param[in] bp
29601263c6cSJonas Devlieghere ///     The exception breakpoint object to use
29701263c6cSJonas Devlieghere ///
29801263c6cSJonas Devlieghere /// \return
29901263c6cSJonas Devlieghere ///     A "ExceptionBreakpointsFilter" JSON object with that follows
30001263c6cSJonas Devlieghere ///     the formal JSON definition outlined by Microsoft.
30101263c6cSJonas Devlieghere llvm::json::Value
30201263c6cSJonas Devlieghere CreateExceptionBreakpointFilter(const ExceptionBreakpoint &bp);
30301263c6cSJonas Devlieghere 
30401263c6cSJonas Devlieghere /// Create a "Scope" JSON object as described in the debug adaptor definition.
30501263c6cSJonas Devlieghere ///
30601263c6cSJonas Devlieghere /// \param[in] name
30701263c6cSJonas Devlieghere ///     The value to place into the "name" key
30801263c6cSJonas Devlieghere //
30901263c6cSJonas Devlieghere /// \param[in] variablesReference
31001263c6cSJonas Devlieghere ///     The value to place into the "variablesReference" key
31101263c6cSJonas Devlieghere //
31201263c6cSJonas Devlieghere /// \param[in] namedVariables
31301263c6cSJonas Devlieghere ///     The value to place into the "namedVariables" key
31401263c6cSJonas Devlieghere //
31501263c6cSJonas Devlieghere /// \param[in] expensive
31601263c6cSJonas Devlieghere ///     The value to place into the "expensive" key
31701263c6cSJonas Devlieghere ///
31801263c6cSJonas Devlieghere /// \return
31901263c6cSJonas Devlieghere ///     A "Scope" JSON object with that follows the formal JSON
32001263c6cSJonas Devlieghere ///     definition outlined by Microsoft.
32101263c6cSJonas Devlieghere llvm::json::Value CreateScope(const llvm::StringRef name,
32201263c6cSJonas Devlieghere                               int64_t variablesReference,
32301263c6cSJonas Devlieghere                               int64_t namedVariables, bool expensive);
32401263c6cSJonas Devlieghere 
32501263c6cSJonas Devlieghere /// Create a "Source" JSON object as described in the debug adaptor definition.
32601263c6cSJonas Devlieghere ///
3270cc2cd78SAdrian Vogelsgesang /// \param[in] file
3280cc2cd78SAdrian Vogelsgesang ///     The SBFileSpec to use when populating out the "Source" object
3290cc2cd78SAdrian Vogelsgesang ///
3300cc2cd78SAdrian Vogelsgesang /// \return
3310cc2cd78SAdrian Vogelsgesang ///     A "Source" JSON object that follows the formal JSON
3320cc2cd78SAdrian Vogelsgesang ///     definition outlined by Microsoft.
3330cc2cd78SAdrian Vogelsgesang llvm::json::Value CreateSource(const lldb::SBFileSpec &file);
3340cc2cd78SAdrian Vogelsgesang 
3350cc2cd78SAdrian Vogelsgesang /// Create a "Source" JSON object as described in the debug adaptor definition.
3360cc2cd78SAdrian Vogelsgesang ///
33701263c6cSJonas Devlieghere /// \param[in] line_entry
33801263c6cSJonas Devlieghere ///     The LLDB line table to use when populating out the "Source"
33901263c6cSJonas Devlieghere ///     object
34001263c6cSJonas Devlieghere ///
34101263c6cSJonas Devlieghere /// \return
3420cc2cd78SAdrian Vogelsgesang ///     A "Source" JSON object that follows the formal JSON
34301263c6cSJonas Devlieghere ///     definition outlined by Microsoft.
3440cc2cd78SAdrian Vogelsgesang llvm::json::Value CreateSource(const lldb::SBLineEntry &line_entry);
34501263c6cSJonas Devlieghere 
34601263c6cSJonas Devlieghere /// Create a "Source" object for a given source path.
34701263c6cSJonas Devlieghere ///
34801263c6cSJonas Devlieghere /// \param[in] source_path
34901263c6cSJonas Devlieghere ///     The path to the source to use when creating the "Source" object.
35001263c6cSJonas Devlieghere ///
35101263c6cSJonas Devlieghere /// \return
35201263c6cSJonas Devlieghere ///     A "Source" JSON object that follows the formal JSON
35301263c6cSJonas Devlieghere ///     definition outlined by Microsoft.
35401263c6cSJonas Devlieghere llvm::json::Value CreateSource(llvm::StringRef source_path);
35501263c6cSJonas Devlieghere 
35601263c6cSJonas Devlieghere /// Create a "StackFrame" object for a LLDB frame object.
35701263c6cSJonas Devlieghere ///
35801263c6cSJonas Devlieghere /// This function will fill in the following keys in the returned
35901263c6cSJonas Devlieghere /// object:
36001263c6cSJonas Devlieghere ///   "id" - the stack frame ID as an integer
36101263c6cSJonas Devlieghere ///   "name" - the function name as a string
36201263c6cSJonas Devlieghere ///   "source" - source file information as a "Source" DAP object
36301263c6cSJonas Devlieghere ///   "line" - the source file line number as an integer
36401263c6cSJonas Devlieghere ///   "column" - the source file column number as an integer
36501263c6cSJonas Devlieghere ///
36601263c6cSJonas Devlieghere /// \param[in] frame
36701263c6cSJonas Devlieghere ///     The LLDB stack frame to use when populating out the "StackFrame"
36801263c6cSJonas Devlieghere ///     object.
36901263c6cSJonas Devlieghere ///
370*faaf2dbfSJohn Harrison /// \param[in] format
371*faaf2dbfSJohn Harrison ///     The LLDB format to use when populating out the "StackFrame"
372*faaf2dbfSJohn Harrison ///     object.
373*faaf2dbfSJohn Harrison ///
37401263c6cSJonas Devlieghere /// \return
37501263c6cSJonas Devlieghere ///     A "StackFrame" JSON object with that follows the formal JSON
37601263c6cSJonas Devlieghere ///     definition outlined by Microsoft.
377*faaf2dbfSJohn Harrison llvm::json::Value CreateStackFrame(lldb::SBFrame &frame,
378*faaf2dbfSJohn Harrison                                    lldb::SBFormat &format);
37901263c6cSJonas Devlieghere 
3805b4100ccSJohn Harrison /// Create a "StackFrame" label object for a LLDB thread.
3815b4100ccSJohn Harrison ///
3825b4100ccSJohn Harrison /// This function will fill in the following keys in the returned
3835b4100ccSJohn Harrison /// object:
3845b4100ccSJohn Harrison ///   "id" - the thread ID as an integer
3855b4100ccSJohn Harrison ///   "name" - the thread name as a string which combines the LLDB
3865b4100ccSJohn Harrison ///            thread index ID along with the string name of the thread
3875b4100ccSJohn Harrison ///            from the OS if it has a name.
3885b4100ccSJohn Harrison ///   "presentationHint" - "label"
3895b4100ccSJohn Harrison ///
3905b4100ccSJohn Harrison /// \param[in] thread
3915b4100ccSJohn Harrison ///     The LLDB thread to use when populating out the "Thread"
3925b4100ccSJohn Harrison ///     object.
3935b4100ccSJohn Harrison ///
394*faaf2dbfSJohn Harrison /// \param[in] format
395*faaf2dbfSJohn Harrison ///     The configured formatter for the DAP session.
396*faaf2dbfSJohn Harrison ///
3975b4100ccSJohn Harrison /// \return
3985b4100ccSJohn Harrison ///     A "StackFrame" JSON object with that follows the formal JSON
3995b4100ccSJohn Harrison ///     definition outlined by Microsoft.
400*faaf2dbfSJohn Harrison llvm::json::Value CreateExtendedStackFrameLabel(lldb::SBThread &thread,
401*faaf2dbfSJohn Harrison                                                 lldb::SBFormat &format);
4025b4100ccSJohn Harrison 
40301263c6cSJonas Devlieghere /// Create a "Thread" object for a LLDB thread object.
40401263c6cSJonas Devlieghere ///
40501263c6cSJonas Devlieghere /// This function will fill in the following keys in the returned
40601263c6cSJonas Devlieghere /// object:
40701263c6cSJonas Devlieghere ///   "id" - the thread ID as an integer
40801263c6cSJonas Devlieghere ///   "name" - the thread name as a string which combines the LLDB
40901263c6cSJonas Devlieghere ///            thread index ID along with the string name of the thread
41001263c6cSJonas Devlieghere ///            from the OS if it has a name.
41101263c6cSJonas Devlieghere ///
41201263c6cSJonas Devlieghere /// \param[in] thread
41301263c6cSJonas Devlieghere ///     The LLDB thread to use when populating out the "Thread"
41401263c6cSJonas Devlieghere ///     object.
41501263c6cSJonas Devlieghere ///
416*faaf2dbfSJohn Harrison /// \param[in] format
417*faaf2dbfSJohn Harrison ///     The LLDB format to use when populating out the "Thread"
418*faaf2dbfSJohn Harrison ///     object.
419*faaf2dbfSJohn Harrison ///
42001263c6cSJonas Devlieghere /// \return
42101263c6cSJonas Devlieghere ///     A "Thread" JSON object with that follows the formal JSON
42201263c6cSJonas Devlieghere ///     definition outlined by Microsoft.
423*faaf2dbfSJohn Harrison llvm::json::Value CreateThread(lldb::SBThread &thread, lldb::SBFormat &format);
42401263c6cSJonas Devlieghere 
42501263c6cSJonas Devlieghere /// Create a "StoppedEvent" object for a LLDB thread object.
42601263c6cSJonas Devlieghere ///
42701263c6cSJonas Devlieghere /// This function will fill in the following keys in the returned
42801263c6cSJonas Devlieghere /// object's "body" object:
42901263c6cSJonas Devlieghere ///   "reason" - With a valid stop reason enumeration string value
43001263c6cSJonas Devlieghere ///              that Microsoft specifies
43101263c6cSJonas Devlieghere ///   "threadId" - The thread ID as an integer
43201263c6cSJonas Devlieghere ///   "description" - a stop description (like "breakpoint 12.3") as a
43301263c6cSJonas Devlieghere ///                   string
43401263c6cSJonas Devlieghere ///   "preserveFocusHint" - a boolean value that states if this thread
43501263c6cSJonas Devlieghere ///                         should keep the focus in the GUI.
43601263c6cSJonas Devlieghere ///   "allThreadsStopped" - set to True to indicate that all threads
43701263c6cSJonas Devlieghere ///                         stop when any thread stops.
43801263c6cSJonas Devlieghere ///
439*faaf2dbfSJohn Harrison /// \param[in] dap
440*faaf2dbfSJohn Harrison ///     The DAP session associated with the stopped thread.
441*faaf2dbfSJohn Harrison ///
44201263c6cSJonas Devlieghere /// \param[in] thread
44301263c6cSJonas Devlieghere ///     The LLDB thread to use when populating out the "StoppedEvent"
44401263c6cSJonas Devlieghere ///     object.
44501263c6cSJonas Devlieghere ///
446*faaf2dbfSJohn Harrison /// \param[in] stop_id
447*faaf2dbfSJohn Harrison ///     The stop id for this event.
448*faaf2dbfSJohn Harrison ///
44901263c6cSJonas Devlieghere /// \return
45001263c6cSJonas Devlieghere ///     A "StoppedEvent" JSON object with that follows the formal JSON
45101263c6cSJonas Devlieghere ///     definition outlined by Microsoft.
452*faaf2dbfSJohn Harrison llvm::json::Value CreateThreadStopped(DAP &dap, lldb::SBThread &thread,
453*faaf2dbfSJohn Harrison                                       uint32_t stop_id);
45401263c6cSJonas Devlieghere 
45501263c6cSJonas Devlieghere /// \return
45601263c6cSJonas Devlieghere ///     The variable name of \a value or a default placeholder.
457*faaf2dbfSJohn Harrison const char *GetNonNullVariableName(lldb::SBValue &value);
45801263c6cSJonas Devlieghere 
45901263c6cSJonas Devlieghere /// VSCode can't display two variables with the same name, so we need to
46001263c6cSJonas Devlieghere /// distinguish them by using a suffix.
46101263c6cSJonas Devlieghere ///
46201263c6cSJonas Devlieghere /// If the source and line information is present, we use it as the suffix.
46301263c6cSJonas Devlieghere /// Otherwise, we fallback to the variable address or register location.
464*faaf2dbfSJohn Harrison std::string CreateUniqueVariableNameForDisplay(lldb::SBValue &v,
46501263c6cSJonas Devlieghere                                                bool is_name_duplicated);
46601263c6cSJonas Devlieghere 
467ffd173baSWalter Erquinigo /// Helper struct that parses the metadata of an \a lldb::SBValue and produces
468ffd173baSWalter Erquinigo /// a canonical set of properties that can be sent to DAP clients.
469ffd173baSWalter Erquinigo struct VariableDescription {
470ffd173baSWalter Erquinigo   // The error message if SBValue.GetValue() fails.
471ffd173baSWalter Erquinigo   std::optional<std::string> error;
472ffd173baSWalter Erquinigo   // The display description to show on the IDE.
473ffd173baSWalter Erquinigo   std::string display_value;
474ffd173baSWalter Erquinigo   // The display name to show on the IDE.
475ffd173baSWalter Erquinigo   std::string name;
476ffd173baSWalter Erquinigo   // The variable path for this variable.
477ffd173baSWalter Erquinigo   std::string evaluate_name;
478ffd173baSWalter Erquinigo   // The output of SBValue.GetValue() if it doesn't fail. It might be empty.
479ffd173baSWalter Erquinigo   std::string value;
480ffd173baSWalter Erquinigo   // The summary string of this variable. It might be empty.
481ffd173baSWalter Erquinigo   std::string summary;
482ffd173baSWalter Erquinigo   // The auto summary if using `enableAutoVariableSummaries`.
483ffd173baSWalter Erquinigo   std::optional<std::string> auto_summary;
484ffd173baSWalter Erquinigo   // The type of this variable.
485ffd173baSWalter Erquinigo   lldb::SBType type_obj;
486ffd173baSWalter Erquinigo   // The display type name of this variable.
487ffd173baSWalter Erquinigo   std::string display_type_name;
488ffd173baSWalter Erquinigo   /// The SBValue for this variable.
489ffd173baSWalter Erquinigo   lldb::SBValue v;
490ffd173baSWalter Erquinigo 
491*faaf2dbfSJohn Harrison   VariableDescription(lldb::SBValue v, bool auto_variable_summaries,
492*faaf2dbfSJohn Harrison                       bool format_hex = false, bool is_name_duplicated = false,
493ffd173baSWalter Erquinigo                       std::optional<std::string> custom_name = {});
494ffd173baSWalter Erquinigo 
495ffd173baSWalter Erquinigo   /// Create a JSON object that represents these extensions to the DAP variable
496ffd173baSWalter Erquinigo   /// response.
497ffd173baSWalter Erquinigo   llvm::json::Object GetVariableExtensionsJSON();
49840a361acSJohn Harrison 
49940a361acSJohn Harrison   /// Returns a description of the value appropriate for the specified context.
50040a361acSJohn Harrison   std::string GetResult(llvm::StringRef context);
501ffd173baSWalter Erquinigo };
502ffd173baSWalter Erquinigo 
5039f8ae784SAdrian Vogelsgesang /// Does the given variable have an associated value location?
5049f8ae784SAdrian Vogelsgesang bool ValuePointsToCode(lldb::SBValue v);
5059f8ae784SAdrian Vogelsgesang 
5069f8ae784SAdrian Vogelsgesang /// Pack a location into a single integer which we can send via
5079f8ae784SAdrian Vogelsgesang /// the debug adapter protocol.
5089f8ae784SAdrian Vogelsgesang int64_t PackLocation(int64_t var_ref, bool is_value_location);
5099f8ae784SAdrian Vogelsgesang 
5109f8ae784SAdrian Vogelsgesang /// Reverse of `PackLocation`
5119f8ae784SAdrian Vogelsgesang std::pair<int64_t, bool> UnpackLocation(int64_t location_id);
5129f8ae784SAdrian Vogelsgesang 
51301263c6cSJonas Devlieghere /// Create a "Variable" object for a LLDB thread object.
51401263c6cSJonas Devlieghere ///
51501263c6cSJonas Devlieghere /// This function will fill in the following keys in the returned
51601263c6cSJonas Devlieghere /// object:
51701263c6cSJonas Devlieghere ///   "name" - the name of the variable
51801263c6cSJonas Devlieghere ///   "value" - the value of the variable as a string
51901263c6cSJonas Devlieghere ///   "type" - the typename of the variable as a string
52001263c6cSJonas Devlieghere ///   "id" - a unique identifier for a value in case there are multiple
52101263c6cSJonas Devlieghere ///          variables with the same name. Other parts of the DAP
52201263c6cSJonas Devlieghere ///          protocol refer to values by name so this can help
52301263c6cSJonas Devlieghere ///          disambiguate such cases if a IDE passes this "id" value
52401263c6cSJonas Devlieghere ///          back down.
52501263c6cSJonas Devlieghere ///   "variablesReference" - Zero if the variable has no children,
52601263c6cSJonas Devlieghere ///          non-zero integer otherwise which can be used to expand
52701263c6cSJonas Devlieghere ///          the variable.
52801263c6cSJonas Devlieghere ///   "evaluateName" - The name of the variable to use in expressions
52901263c6cSJonas Devlieghere ///                    as a string.
53001263c6cSJonas Devlieghere ///
53101263c6cSJonas Devlieghere /// \param[in] v
53201263c6cSJonas Devlieghere ///     The LLDB value to use when populating out the "Variable"
53301263c6cSJonas Devlieghere ///     object.
53401263c6cSJonas Devlieghere ///
5350cc2cd78SAdrian Vogelsgesang /// \param[in] var_ref
5360cc2cd78SAdrian Vogelsgesang ///     The variable reference. Used to identify the value, e.g.
5370cc2cd78SAdrian Vogelsgesang ///     in the `variablesReference` or `declarationLocationReference`
5380cc2cd78SAdrian Vogelsgesang ///     properties.
53901263c6cSJonas Devlieghere ///
54001263c6cSJonas Devlieghere /// \param[in] format_hex
541*faaf2dbfSJohn Harrison ///     If set to true the variable will be formatted as hex in
54201263c6cSJonas Devlieghere ///     the "value" key value pair for the value of the variable.
54301263c6cSJonas Devlieghere ///
544*faaf2dbfSJohn Harrison /// \param[in] auto_variable_summaries
545*faaf2dbfSJohn Harrison ///     IF set to true the variable will create an automatic variable summary.
546*faaf2dbfSJohn Harrison ///
54701263c6cSJonas Devlieghere /// \param[in] is_name_duplicated
54801263c6cSJonas Devlieghere ///     Whether the same variable name appears multiple times within the same
54901263c6cSJonas Devlieghere ///     context (e.g. locals). This can happen due to shadowed variables in
55001263c6cSJonas Devlieghere ///     nested blocks.
55101263c6cSJonas Devlieghere ///
55201263c6cSJonas Devlieghere ///     As VSCode doesn't render two of more variables with the same name, we
55301263c6cSJonas Devlieghere ///     apply a suffix to distinguish duplicated variables.
55401263c6cSJonas Devlieghere ///
55501263c6cSJonas Devlieghere /// \param[in] custom_name
55601263c6cSJonas Devlieghere ///     A provided custom name that is used instead of the SBValue's when
55701263c6cSJonas Devlieghere ///     creating the JSON representation.
55801263c6cSJonas Devlieghere ///
55901263c6cSJonas Devlieghere /// \return
56001263c6cSJonas Devlieghere ///     A "Variable" JSON object with that follows the formal JSON
56101263c6cSJonas Devlieghere ///     definition outlined by Microsoft.
5620cc2cd78SAdrian Vogelsgesang llvm::json::Value CreateVariable(lldb::SBValue v, int64_t var_ref,
563*faaf2dbfSJohn Harrison                                  bool format_hex, bool auto_variable_summaries,
564*faaf2dbfSJohn Harrison                                  bool synthetic_child_debugging,
56501263c6cSJonas Devlieghere                                  bool is_name_duplicated = false,
56601263c6cSJonas Devlieghere                                  std::optional<std::string> custom_name = {});
56701263c6cSJonas Devlieghere 
568*faaf2dbfSJohn Harrison llvm::json::Value CreateCompileUnit(lldb::SBCompileUnit &unit);
56901263c6cSJonas Devlieghere 
57001263c6cSJonas Devlieghere /// Create a runInTerminal reverse request object
57101263c6cSJonas Devlieghere ///
57201263c6cSJonas Devlieghere /// \param[in] launch_request
57301263c6cSJonas Devlieghere ///     The original launch_request object whose fields are used to construct
57401263c6cSJonas Devlieghere ///     the reverse request object.
57501263c6cSJonas Devlieghere ///
57601263c6cSJonas Devlieghere /// \param[in] debug_adaptor_path
57701263c6cSJonas Devlieghere ///     Path to the current debug adaptor. It will be used to delegate the
57801263c6cSJonas Devlieghere ///     launch of the target.
57901263c6cSJonas Devlieghere ///
58001263c6cSJonas Devlieghere /// \param[in] comm_file
58101263c6cSJonas Devlieghere ///     The fifo file used to communicate the with the target launcher.
58201263c6cSJonas Devlieghere ///
58301263c6cSJonas Devlieghere /// \param[in] debugger_pid
58401263c6cSJonas Devlieghere ///     The PID of the lldb-dap instance that will attach to the target. The
58501263c6cSJonas Devlieghere ///     launcher uses it on Linux tell the kernel that it should allow the
58601263c6cSJonas Devlieghere ///     debugger process to attach.
58701263c6cSJonas Devlieghere ///
58801263c6cSJonas Devlieghere /// \return
58901263c6cSJonas Devlieghere ///     A "runInTerminal" JSON object that follows the specification outlined by
59001263c6cSJonas Devlieghere ///     Microsoft.
59101263c6cSJonas Devlieghere llvm::json::Object
59201263c6cSJonas Devlieghere CreateRunInTerminalReverseRequest(const llvm::json::Object &launch_request,
59301263c6cSJonas Devlieghere                                   llvm::StringRef debug_adaptor_path,
59401263c6cSJonas Devlieghere                                   llvm::StringRef comm_file,
59501263c6cSJonas Devlieghere                                   lldb::pid_t debugger_pid);
59601263c6cSJonas Devlieghere 
59701263c6cSJonas Devlieghere /// Create a "Terminated" JSON object that contains statistics
59801263c6cSJonas Devlieghere ///
59901263c6cSJonas Devlieghere /// \return
60001263c6cSJonas Devlieghere ///     A body JSON object with debug info and breakpoint info
601*faaf2dbfSJohn Harrison llvm::json::Object CreateTerminatedEventObject(lldb::SBTarget &target);
60201263c6cSJonas Devlieghere 
60301263c6cSJonas Devlieghere /// Convert a given JSON object to a string.
60401263c6cSJonas Devlieghere std::string JSONToString(const llvm::json::Value &json);
60501263c6cSJonas Devlieghere 
60601263c6cSJonas Devlieghere } // namespace lldb_dap
60701263c6cSJonas Devlieghere 
60801263c6cSJonas Devlieghere #endif
609