1//===-- Request.h ---------------------------------------------------------===//
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 LLDB_TOOLS_LLDB_DAP_HANDLER_HANDLER_H
10#define LLDB_TOOLS_LLDB_DAP_HANDLER_HANDLER_H
11
12#include "DAP.h"
13#include "DAPError.h"
14#include "DAPLog.h"
15#include "Protocol/ProtocolBase.h"
16#include "Protocol/ProtocolRequests.h"
17#include "Protocol/ProtocolTypes.h"
18#include "llvm/ADT/DenseSet.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/Support/Error.h"
21#include "llvm/Support/JSON.h"
22#include <optional>
23#include <type_traits>
24#include <variant>
25#include <vector>
26
27template <typename T> struct is_optional : std::false_type {};
28
29template <typename T> struct is_optional<std::optional<T>> : std::true_type {};
30
31template <typename T>
32inline constexpr bool is_optional_v = is_optional<T>::value;
33
34namespace lldb_dap {
35struct DAP;
36
37/// Base class for request handlers. Do not extend this directly: Extend
38/// the RequestHandler template subclass instead.
39class BaseRequestHandler {
40public:
41 BaseRequestHandler(DAP &dap) : dap(dap) {}
42
43 /// BaseRequestHandler are not copyable.
44 /// @{
45 BaseRequestHandler(const BaseRequestHandler &) = delete;
46 BaseRequestHandler &operator=(const BaseRequestHandler &) = delete;
47 /// @}
48
49 virtual ~BaseRequestHandler() = default;
50
51 void Run(const protocol::Request &);
52
53 virtual void operator()(const protocol::Request &request) const = 0;
54
55 using FeatureSet = llvm::SmallDenseSet<AdapterFeature, 1>;
56 virtual FeatureSet GetSupportedFeatures() const { return {}; }
57
58protected:
59 /// Helpers used by multiple request handlers.
60 /// FIXME: Move these into the DAP class?
61 /// @{
62
63 /// Prints a welcome message on the editor if the preprocessor variable
64 /// LLDB_DAP_WELCOME_MESSAGE is defined.
65 void PrintWelcomeMessage() const;
66
67 // Takes a LaunchRequest object and launches the process, also handling
68 // runInTerminal if applicable. It doesn't do any of the additional
69 // initialization and bookkeeping stuff that is needed for `request_launch`.
70 // This way we can reuse the process launching logic for RestartRequest too.
71 llvm::Error
72 LaunchProcess(const protocol::LaunchRequestArguments &request) const;
73
74 // Check if the step-granularity is `instruction`.
75 bool HasInstructionGranularity(const llvm::json::Object &request) const;
76
77 /// @}
78
79 DAP &dap;
80};
81
82/// FIXME: Migrate callers to typed RequestHandler for improved type handling.
83class LegacyRequestHandler : public BaseRequestHandler {
84 using BaseRequestHandler::BaseRequestHandler;
85 virtual void operator()(const llvm::json::Object &request) const = 0;
86 void operator()(const protocol::Request &request) const override {
87 auto req = toJSON(request);
88 (*this)(*req.getAsObject());
89 }
90};
91
92template <typename Args>
93llvm::Expected<Args> parseArgs(const protocol::Request &request) {
94 if (!is_optional_v<Args> && !request.arguments)
95 return llvm::make_error<DAPError>(
96 Args: llvm::formatv(Fmt: "arguments required for command '{0}' "
97 "but none received",
98 Vals: request.command)
99 .str());
100
101 Args arguments;
102 llvm::json::Path::Root root("arguments");
103 if (request.arguments && !fromJSON(*request.arguments, arguments, root)) {
104 std::string parse_failure;
105 llvm::raw_string_ostream OS(parse_failure);
106 OS << "invalid arguments for request '" << request.command
107 << "': " << llvm::toString(E: root.getError()) << "\n";
108 root.printErrorContext(*request.arguments, OS);
109 return llvm::make_error<DAPError>(Args&: parse_failure);
110 }
111
112 return arguments;
113}
114template <>
115inline llvm::Expected<protocol::EmptyArguments>
116parseArgs(const protocol::Request &request) {
117 return std::nullopt;
118}
119
120/// Base class for handling DAP requests. Handlers should declare their
121/// arguments and response body types like:
122///
123/// class MyRequestHandler : public RequestHandler<Arguments, Response> {
124/// ....
125/// };
126template <typename Args, typename Resp>
127class RequestHandler : public BaseRequestHandler {
128 using BaseRequestHandler::BaseRequestHandler;
129
130 void operator()(const protocol::Request &request) const override {
131 protocol::Response response;
132 response.request_seq = request.seq;
133 response.command = request.command;
134
135 llvm::Expected<Args> arguments = parseArgs<Args>(request);
136 if (llvm::Error err = arguments.takeError()) {
137 HandleErrorResponse(err: std::move(err), response);
138 dap.Send(message: response);
139 return;
140 }
141
142 if constexpr (std::is_same_v<Resp, llvm::Error>) {
143 if (llvm::Error err = Run(*arguments)) {
144 HandleErrorResponse(err: std::move(err), response);
145 } else {
146 response.success = true;
147 }
148 } else {
149 Resp body = Run(*arguments);
150 if (llvm::Error err = body.takeError()) {
151 HandleErrorResponse(err: std::move(err), response);
152 } else {
153 response.success = true;
154 response.body = std::move(*body);
155 }
156 }
157
158 // Mark the request as 'cancelled' if the debugger was interrupted while
159 // evaluating this handler.
160 if (dap.debugger.InterruptRequested()) {
161 dap.debugger.CancelInterruptRequest();
162 response.success = false;
163 response.message = protocol::eResponseMessageCancelled;
164 response.body = std::nullopt;
165 }
166
167 dap.Send(message: response);
168
169 PostRun();
170 };
171
172 virtual Resp Run(const Args &) const = 0;
173
174 /// A hook for a request handler to run additional operations after the
175 /// request response is sent but before the next request handler.
176 ///
177 /// *NOTE*: PostRun will be invoked even if the `Run` operation returned an
178 /// error.
179 virtual void PostRun() const {};
180
181 void HandleErrorResponse(llvm::Error err,
182 protocol::Response &response) const {
183 response.success = false;
184 llvm::handleAllErrors(
185 std::move(err),
186 [&](const NotStoppedError &err) {
187 response.message = lldb_dap::protocol::eResponseMessageNotStopped;
188 },
189 [&](const DAPError &err) {
190 protocol::ErrorMessage error_message;
191 error_message.sendTelemetry = false;
192 error_message.format = err.getMessage();
193 error_message.showUser = err.getShowUser();
194 error_message.id = err.convertToErrorCode().value();
195 error_message.url = err.getURL();
196 error_message.urlLabel = err.getURLLabel();
197 protocol::ErrorResponseBody body;
198 body.error = error_message;
199 response.body = body;
200 },
201 [&](const llvm::ErrorInfoBase &err) {
202 protocol::ErrorMessage error_message;
203 error_message.showUser = true;
204 error_message.sendTelemetry = false;
205 error_message.format = err.message();
206 error_message.id = err.convertToErrorCode().value();
207 protocol::ErrorResponseBody body;
208 body.error = error_message;
209 response.body = body;
210 });
211 }
212};
213
214class AttachRequestHandler
215 : public RequestHandler<protocol::AttachRequestArguments,
216 protocol::AttachResponse> {
217public:
218 using RequestHandler::RequestHandler;
219 static llvm::StringLiteral GetCommand() { return "attach"; }
220 llvm::Error Run(const protocol::AttachRequestArguments &args) const override;
221 void PostRun() const override;
222};
223
224class BreakpointLocationsRequestHandler
225 : public RequestHandler<
226 protocol::BreakpointLocationsArguments,
227 llvm::Expected<protocol::BreakpointLocationsResponseBody>> {
228public:
229 using RequestHandler::RequestHandler;
230 static llvm::StringLiteral GetCommand() { return "breakpointLocations"; }
231 FeatureSet GetSupportedFeatures() const override {
232 return {protocol::eAdapterFeatureBreakpointLocationsRequest};
233 }
234 llvm::Expected<protocol::BreakpointLocationsResponseBody>
235 Run(const protocol::BreakpointLocationsArguments &args) const override;
236
237 std::vector<std::pair<uint32_t, uint32_t>>
238 GetSourceBreakpointLocations(std::string path, uint32_t start_line,
239 uint32_t start_column, uint32_t end_line,
240 uint32_t end_column) const;
241 std::vector<std::pair<uint32_t, uint32_t>>
242 GetAssemblyBreakpointLocations(int64_t source_reference, uint32_t start_line,
243 uint32_t end_line) const;
244};
245
246class CompletionsRequestHandler : public LegacyRequestHandler {
247public:
248 using LegacyRequestHandler::LegacyRequestHandler;
249 static llvm::StringLiteral GetCommand() { return "completions"; }
250 FeatureSet GetSupportedFeatures() const override {
251 return {protocol::eAdapterFeatureCompletionsRequest};
252 }
253 void operator()(const llvm::json::Object &request) const override;
254};
255
256class ContinueRequestHandler
257 : public RequestHandler<protocol::ContinueArguments,
258 llvm::Expected<protocol::ContinueResponseBody>> {
259public:
260 using RequestHandler::RequestHandler;
261 static llvm::StringLiteral GetCommand() { return "continue"; }
262 llvm::Expected<protocol::ContinueResponseBody>
263 Run(const protocol::ContinueArguments &args) const override;
264};
265
266class ConfigurationDoneRequestHandler
267 : public RequestHandler<protocol::ConfigurationDoneArguments,
268 protocol::ConfigurationDoneResponse> {
269public:
270 using RequestHandler::RequestHandler;
271 static llvm::StringLiteral GetCommand() { return "configurationDone"; }
272 FeatureSet GetSupportedFeatures() const override {
273 return {protocol::eAdapterFeatureConfigurationDoneRequest};
274 }
275 protocol::ConfigurationDoneResponse
276 Run(const protocol::ConfigurationDoneArguments &) const override;
277};
278
279class DisconnectRequestHandler
280 : public RequestHandler<std::optional<protocol::DisconnectArguments>,
281 protocol::DisconnectResponse> {
282public:
283 using RequestHandler::RequestHandler;
284 static llvm::StringLiteral GetCommand() { return "disconnect"; }
285 FeatureSet GetSupportedFeatures() const override {
286 return {protocol::eAdapterFeatureTerminateDebuggee};
287 }
288 llvm::Error
289 Run(const std::optional<protocol::DisconnectArguments> &args) const override;
290};
291
292class EvaluateRequestHandler : public LegacyRequestHandler {
293public:
294 using LegacyRequestHandler::LegacyRequestHandler;
295 static llvm::StringLiteral GetCommand() { return "evaluate"; }
296 void operator()(const llvm::json::Object &request) const override;
297 FeatureSet GetSupportedFeatures() const override {
298 return {protocol::eAdapterFeatureEvaluateForHovers};
299 }
300};
301
302class ExceptionInfoRequestHandler : public LegacyRequestHandler {
303public:
304 using LegacyRequestHandler::LegacyRequestHandler;
305 static llvm::StringLiteral GetCommand() { return "exceptionInfo"; }
306 FeatureSet GetSupportedFeatures() const override {
307 return {protocol::eAdapterFeatureExceptionInfoRequest};
308 }
309 void operator()(const llvm::json::Object &request) const override;
310};
311
312class InitializeRequestHandler
313 : public RequestHandler<protocol::InitializeRequestArguments,
314 llvm::Expected<protocol::InitializeResponse>> {
315public:
316 using RequestHandler::RequestHandler;
317 static llvm::StringLiteral GetCommand() { return "initialize"; }
318 llvm::Expected<protocol::InitializeResponse>
319 Run(const protocol::InitializeRequestArguments &args) const override;
320};
321
322class LaunchRequestHandler
323 : public RequestHandler<protocol::LaunchRequestArguments,
324 protocol::LaunchResponse> {
325public:
326 using RequestHandler::RequestHandler;
327 static llvm::StringLiteral GetCommand() { return "launch"; }
328 llvm::Error
329 Run(const protocol::LaunchRequestArguments &arguments) const override;
330 void PostRun() const override;
331};
332
333class RestartRequestHandler : public LegacyRequestHandler {
334public:
335 using LegacyRequestHandler::LegacyRequestHandler;
336 static llvm::StringLiteral GetCommand() { return "restart"; }
337 void operator()(const llvm::json::Object &request) const override;
338};
339
340class NextRequestHandler
341 : public RequestHandler<protocol::NextArguments, protocol::NextResponse> {
342public:
343 using RequestHandler::RequestHandler;
344 static llvm::StringLiteral GetCommand() { return "next"; }
345 llvm::Error Run(const protocol::NextArguments &args) const override;
346};
347
348class StepInRequestHandler : public RequestHandler<protocol::StepInArguments,
349 protocol::StepInResponse> {
350public:
351 using RequestHandler::RequestHandler;
352 static llvm::StringLiteral GetCommand() { return "stepIn"; }
353 llvm::Error Run(const protocol::StepInArguments &args) const override;
354};
355
356class StepInTargetsRequestHandler
357 : public RequestHandler<
358 protocol::StepInTargetsArguments,
359 llvm::Expected<protocol::StepInTargetsResponseBody>> {
360public:
361 using RequestHandler::RequestHandler;
362 static llvm::StringLiteral GetCommand() { return "stepInTargets"; }
363 llvm::Expected<protocol::StepInTargetsResponseBody>
364 Run(const protocol::StepInTargetsArguments &args) const override;
365};
366
367class StepOutRequestHandler : public RequestHandler<protocol::StepOutArguments,
368 protocol::StepOutResponse> {
369public:
370 using RequestHandler::RequestHandler;
371 static llvm::StringLiteral GetCommand() { return "stepOut"; }
372 llvm::Error Run(const protocol::StepOutArguments &args) const override;
373};
374
375class SetBreakpointsRequestHandler
376 : public RequestHandler<
377 protocol::SetBreakpointsArguments,
378 llvm::Expected<protocol::SetBreakpointsResponseBody>> {
379public:
380 using RequestHandler::RequestHandler;
381 static llvm::StringLiteral GetCommand() { return "setBreakpoints"; }
382 FeatureSet GetSupportedFeatures() const override {
383 return {protocol::eAdapterFeatureConditionalBreakpoints,
384 protocol::eAdapterFeatureHitConditionalBreakpoints};
385 }
386 llvm::Expected<protocol::SetBreakpointsResponseBody>
387 Run(const protocol::SetBreakpointsArguments &args) const override;
388};
389
390class SetExceptionBreakpointsRequestHandler
391 : public RequestHandler<
392 protocol::SetExceptionBreakpointsArguments,
393 llvm::Expected<protocol::SetExceptionBreakpointsResponseBody>> {
394public:
395 using RequestHandler::RequestHandler;
396 static llvm::StringLiteral GetCommand() { return "setExceptionBreakpoints"; }
397 FeatureSet GetSupportedFeatures() const override {
398 /// Prefer the `filterOptions` feature over the `exceptionOptions`.
399 /// exceptionOptions is not supported in VSCode, while `filterOptions` is
400 /// supported.
401 return {protocol::eAdapterFeatureExceptionFilterOptions};
402 }
403 llvm::Expected<protocol::SetExceptionBreakpointsResponseBody>
404 Run(const protocol::SetExceptionBreakpointsArguments &args) const override;
405};
406
407class SetFunctionBreakpointsRequestHandler
408 : public RequestHandler<
409 protocol::SetFunctionBreakpointsArguments,
410 llvm::Expected<protocol::SetFunctionBreakpointsResponseBody>> {
411public:
412 using RequestHandler::RequestHandler;
413 static llvm::StringLiteral GetCommand() { return "setFunctionBreakpoints"; }
414 FeatureSet GetSupportedFeatures() const override {
415 return {protocol::eAdapterFeatureFunctionBreakpoints};
416 }
417 llvm::Expected<protocol::SetFunctionBreakpointsResponseBody>
418 Run(const protocol::SetFunctionBreakpointsArguments &args) const override;
419};
420
421class DataBreakpointInfoRequestHandler
422 : public RequestHandler<
423 protocol::DataBreakpointInfoArguments,
424 llvm::Expected<protocol::DataBreakpointInfoResponseBody>> {
425public:
426 using RequestHandler::RequestHandler;
427 static llvm::StringLiteral GetCommand() { return "dataBreakpointInfo"; }
428 llvm::Expected<protocol::DataBreakpointInfoResponseBody>
429 Run(const protocol::DataBreakpointInfoArguments &args) const override;
430};
431
432class SetDataBreakpointsRequestHandler
433 : public RequestHandler<
434 protocol::SetDataBreakpointsArguments,
435 llvm::Expected<protocol::SetDataBreakpointsResponseBody>> {
436public:
437 using RequestHandler::RequestHandler;
438 static llvm::StringLiteral GetCommand() { return "setDataBreakpoints"; }
439 FeatureSet GetSupportedFeatures() const override {
440 return {protocol::eAdapterFeatureDataBreakpoints};
441 }
442 llvm::Expected<protocol::SetDataBreakpointsResponseBody>
443 Run(const protocol::SetDataBreakpointsArguments &args) const override;
444};
445
446class SetInstructionBreakpointsRequestHandler
447 : public RequestHandler<
448 protocol::SetInstructionBreakpointsArguments,
449 llvm::Expected<protocol::SetInstructionBreakpointsResponseBody>> {
450public:
451 using RequestHandler::RequestHandler;
452 static llvm::StringLiteral GetCommand() {
453 return "setInstructionBreakpoints";
454 }
455 FeatureSet GetSupportedFeatures() const override {
456 return {protocol::eAdapterFeatureInstructionBreakpoints};
457 }
458 llvm::Expected<protocol::SetInstructionBreakpointsResponseBody>
459 Run(const protocol::SetInstructionBreakpointsArguments &args) const override;
460};
461
462class CompileUnitsRequestHandler : public LegacyRequestHandler {
463public:
464 using LegacyRequestHandler::LegacyRequestHandler;
465 static llvm::StringLiteral GetCommand() { return "compileUnits"; }
466 void operator()(const llvm::json::Object &request) const override;
467};
468
469class ModulesRequestHandler final
470 : public RequestHandler<std::optional<protocol::ModulesArguments>,
471 llvm::Expected<protocol::ModulesResponseBody>> {
472public:
473 using RequestHandler::RequestHandler;
474 static llvm::StringLiteral GetCommand() { return "modules"; }
475 FeatureSet GetSupportedFeatures() const override {
476 return {protocol::eAdapterFeatureModulesRequest};
477 }
478 llvm::Expected<protocol::ModulesResponseBody>
479 Run(const std::optional<protocol::ModulesArguments> &args) const override;
480};
481
482class PauseRequestHandler : public LegacyRequestHandler {
483public:
484 using LegacyRequestHandler::LegacyRequestHandler;
485 static llvm::StringLiteral GetCommand() { return "pause"; }
486 void operator()(const llvm::json::Object &request) const override;
487};
488
489class ScopesRequestHandler final
490 : public RequestHandler<protocol::ScopesArguments,
491 llvm::Expected<protocol::ScopesResponseBody>> {
492public:
493 using RequestHandler::RequestHandler;
494 static llvm::StringLiteral GetCommand() { return "scopes"; }
495
496 llvm::Expected<protocol::ScopesResponseBody>
497 Run(const protocol::ScopesArguments &args) const override;
498};
499
500class SetVariableRequestHandler final
501 : public RequestHandler<protocol::SetVariableArguments,
502 llvm::Expected<protocol::SetVariableResponseBody>> {
503public:
504 using RequestHandler::RequestHandler;
505 static llvm::StringLiteral GetCommand() { return "setVariable"; }
506 FeatureSet GetSupportedFeatures() const override {
507 return {protocol::eAdapterFeatureSetVariable};
508 }
509 llvm::Expected<protocol::SetVariableResponseBody>
510 Run(const protocol::SetVariableArguments &args) const override;
511};
512
513class SourceRequestHandler final
514 : public RequestHandler<protocol::SourceArguments,
515 llvm::Expected<protocol::SourceResponseBody>> {
516public:
517 using RequestHandler::RequestHandler;
518 static llvm::StringLiteral GetCommand() { return "source"; }
519 llvm::Expected<protocol::SourceResponseBody>
520 Run(const protocol::SourceArguments &args) const override;
521};
522
523class StackTraceRequestHandler : public LegacyRequestHandler {
524public:
525 using LegacyRequestHandler::LegacyRequestHandler;
526 static llvm::StringLiteral GetCommand() { return "stackTrace"; }
527 void operator()(const llvm::json::Object &request) const override;
528 FeatureSet GetSupportedFeatures() const override {
529 return {protocol::eAdapterFeatureDelayedStackTraceLoading};
530 }
531};
532
533class ThreadsRequestHandler
534 : public RequestHandler<protocol::ThreadsArguments,
535 llvm::Expected<protocol::ThreadsResponseBody>> {
536public:
537 using RequestHandler::RequestHandler;
538 static llvm::StringLiteral GetCommand() { return "threads"; }
539 llvm::Expected<protocol::ThreadsResponseBody>
540 Run(const protocol::ThreadsArguments &) const override;
541};
542
543class VariablesRequestHandler
544 : public RequestHandler<protocol::VariablesArguments,
545 llvm::Expected<protocol::VariablesResponseBody>> {
546public:
547 using RequestHandler::RequestHandler;
548 static llvm::StringLiteral GetCommand() { return "variables"; }
549 llvm::Expected<protocol::VariablesResponseBody>
550 Run(const protocol::VariablesArguments &) const override;
551};
552
553class LocationsRequestHandler : public LegacyRequestHandler {
554public:
555 using LegacyRequestHandler::LegacyRequestHandler;
556 static llvm::StringLiteral GetCommand() { return "locations"; }
557 void operator()(const llvm::json::Object &request) const override;
558};
559
560class DisassembleRequestHandler final
561 : public RequestHandler<protocol::DisassembleArguments,
562 llvm::Expected<protocol::DisassembleResponseBody>> {
563public:
564 using RequestHandler::RequestHandler;
565 static llvm::StringLiteral GetCommand() { return "disassemble"; }
566 FeatureSet GetSupportedFeatures() const override {
567 return {protocol::eAdapterFeatureDisassembleRequest};
568 }
569 llvm::Expected<protocol::DisassembleResponseBody>
570 Run(const protocol::DisassembleArguments &args) const override;
571};
572
573class ReadMemoryRequestHandler final
574 : public RequestHandler<protocol::ReadMemoryArguments,
575 llvm::Expected<protocol::ReadMemoryResponseBody>> {
576public:
577 using RequestHandler::RequestHandler;
578 static llvm::StringLiteral GetCommand() { return "readMemory"; }
579 FeatureSet GetSupportedFeatures() const override {
580 return {protocol::eAdapterFeatureReadMemoryRequest};
581 }
582 llvm::Expected<protocol::ReadMemoryResponseBody>
583 Run(const protocol::ReadMemoryArguments &args) const override;
584};
585
586class CancelRequestHandler : public RequestHandler<protocol::CancelArguments,
587 protocol::CancelResponse> {
588public:
589 using RequestHandler::RequestHandler;
590 static llvm::StringLiteral GetCommand() { return "cancel"; }
591 FeatureSet GetSupportedFeatures() const override {
592 return {protocol::eAdapterFeatureCancelRequest};
593 }
594 llvm::Error Run(const protocol::CancelArguments &args) const override;
595};
596
597/// A request used in testing to get the details on all breakpoints that are
598/// currently set in the target. This helps us to test "setBreakpoints" and
599/// "setFunctionBreakpoints" requests to verify we have the correct set of
600/// breakpoints currently set in LLDB.
601class TestGetTargetBreakpointsRequestHandler : public LegacyRequestHandler {
602public:
603 using LegacyRequestHandler::LegacyRequestHandler;
604 static llvm::StringLiteral GetCommand() {
605 return "_testGetTargetBreakpoints";
606 }
607 void operator()(const llvm::json::Object &request) const override;
608};
609
610class WriteMemoryRequestHandler final
611 : public RequestHandler<protocol::WriteMemoryArguments,
612 llvm::Expected<protocol::WriteMemoryResponseBody>> {
613public:
614 using RequestHandler::RequestHandler;
615 static llvm::StringLiteral GetCommand() { return "writeMemory"; }
616 FeatureSet GetSupportedFeatures() const override {
617 return {protocol::eAdapterFeatureWriteMemoryRequest};
618 }
619 llvm::Expected<protocol::WriteMemoryResponseBody>
620 Run(const protocol::WriteMemoryArguments &args) const override;
621};
622
623} // namespace lldb_dap
624
625#endif
626

source code of lldb/tools/lldb-dap/Handler/RequestHandler.h