public CompletableFuture handle()

in com.microsoft.java.debug.core/src/main/java/com/microsoft/java/debug/core/adapter/handler/SetBreakpointsRequestHandler.java [83:161]


    public CompletableFuture<Response> handle(Command command, Arguments arguments, Response response, IDebugAdapterContext context) {
        if (context.getDebugSession() == null) {
            return AdapterUtils.createAsyncErrorResponse(response, ErrorCode.EMPTY_DEBUG_SESSION, "Empty debug session.");
        }

        if (!registered) {
            registered = true;
            registerBreakpointHandler(context);
        }

        SetBreakpointArguments bpArguments = (SetBreakpointArguments) arguments;
        String clientPath = bpArguments.source.path;
        if (AdapterUtils.isWindows()) {
            // VSCode may send drive letters with inconsistent casing which will mess up the key
            // in the BreakpointManager. See https://github.com/Microsoft/vscode/issues/6268
            // Normalize the drive letter casing. Note that drive letters
            // are not localized so invariant is safe here.
            String drivePrefix = FilenameUtils.getPrefix(clientPath);
            if (drivePrefix != null && drivePrefix.length() >= 2
                    && Character.isLowerCase(drivePrefix.charAt(0)) && drivePrefix.charAt(1) == ':') {
                drivePrefix = drivePrefix.substring(0, 2); // d:\ is an illegal regex string, convert it to d:
                clientPath = clientPath.replaceFirst(drivePrefix, drivePrefix.toUpperCase());
            }
        }
        String sourcePath = clientPath;
        if (bpArguments.source.sourceReference != 0 && context.getSourceUri(bpArguments.source.sourceReference) != null) {
            sourcePath = context.getSourceUri(bpArguments.source.sourceReference);
        } else if (StringUtils.isNotBlank(clientPath)) {
            // See the bug https://github.com/Microsoft/vscode/issues/30996
            // Source.path in the SetBreakpointArguments could be a file system path or uri.
            sourcePath = AdapterUtils.convertPath(clientPath, AdapterUtils.isUri(clientPath), context.isDebuggerPathsAreUri());
        }

        // When breakpoint source path is null or an invalid file path, send an ErrorResponse back.
        if (StringUtils.isBlank(sourcePath)) {
            throw AdapterUtils.createCompletionException(
                String.format("Failed to setBreakpoint. Reason: '%s' is an invalid path.", bpArguments.source.path),
                ErrorCode.SET_BREAKPOINT_FAILURE);
        }

        try {
            List<Types.Breakpoint> res = new ArrayList<>();
            IBreakpoint[] toAdds = this.convertClientBreakpointsToDebugger(sourcePath, bpArguments.breakpoints, context);
            // See the VSCode bug https://github.com/Microsoft/vscode/issues/36471.
            // The source uri sometimes is encoded by VSCode, the debugger will decode it to keep the uri consistent.
            IBreakpoint[] added = context.getBreakpointManager()
                                         .setBreakpoints(AdapterUtils.decodeURIComponent(sourcePath), toAdds, bpArguments.sourceModified);
            for (int i = 0; i < bpArguments.breakpoints.length; i++) {
                // For newly added breakpoint, should install it to debuggee first.
                if (toAdds[i] == added[i] && added[i].className() != null) {
                    added[i].install().thenAccept(bp -> {
                        Events.BreakpointEvent bpEvent = new Events.BreakpointEvent("new", this.convertDebuggerBreakpointToClient(bp, context));
                        context.getProtocolServer().sendEvent(bpEvent);
                    });
                } else if (added[i].className() != null) {
                    if (toAdds[i].getHitCount() != added[i].getHitCount()) {
                        // Update hitCount condition.
                        added[i].setHitCount(toAdds[i].getHitCount());
                    }

                    if (!StringUtils.equals(toAdds[i].getLogMessage(), added[i].getLogMessage())) {
                        added[i].setLogMessage(toAdds[i].getLogMessage());
                    }

                    if (!StringUtils.equals(toAdds[i].getCondition(), added[i].getCondition())) {
                        added[i].setCondition(toAdds[i].getCondition());
                    }

                }
                res.add(this.convertDebuggerBreakpointToClient(added[i], context));
            }
            response.body = new Responses.SetBreakpointsResponseBody(res);
            return CompletableFuture.completedFuture(response);
        } catch (DebugException e) {
            throw AdapterUtils.createCompletionException(
                String.format("Failed to setBreakpoint. Reason: '%s'", e.toString()),
                ErrorCode.SET_BREAKPOINT_FAILURE);
        }
    }