private async resolveAndValidateDebugConfiguration()

in src/configurationProvider.ts [190:389]


    private async resolveAndValidateDebugConfiguration(folder: vscode.WorkspaceFolder | undefined, config: vscode.DebugConfiguration,
                                                       token?: vscode.CancellationToken) {
        let progressReporter = progressProvider.getProgressReporter(config.__progressId);
        if (!progressReporter && config.__progressId) {
            return undefined;
        } else if (!progressReporter) {
            progressReporter = progressProvider.createProgressReporter(config.noDebug ? "Run" : "Debug");
        }

        progressReporter.observe(token);
        if (progressReporter.isCancelled()) {
            return undefined;
        }

        try {
            const isOnStandardMode = await utility.waitForStandardMode(progressReporter);
            if (!isOnStandardMode || progressReporter.isCancelled()) {
                return undefined;
            }

            if (this.isUserSettingsDirty) {
                this.isUserSettingsDirty = false;
                await updateDebugSettings();
            }

            // If no debug configuration is provided, then generate one in memory.
            if (this.isEmptyConfig(config)) {
                config.type = "java";
                config.name = "Java Debug";
                config.request = "launch";
            }

            if (config.request === "launch") {
                this.mergeEnvFile(config);

                // If the user doesn't specify 'vmArgs' in launch.json, use the global setting to get the default vmArgs.
                if (config.vmArgs === undefined) {
                    const debugSettings: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("java.debug.settings");
                    config.vmArgs = debugSettings.vmArgs;
                }
                // If the user doesn't specify 'console' in launch.json, use the global setting to get the launch console.
                if (!config.console) {
                    const debugSettings: vscode.WorkspaceConfiguration = vscode.workspace.getConfiguration("java.debug.settings");
                    config.console = debugSettings.console;
                }
                // If the console is integratedTerminal, don't auto switch the focus to DEBUG CONSOLE.
                if (config.console === "integratedTerminal" && !config.internalConsoleOptions) {
                    config.internalConsoleOptions = "neverOpen";
                }

                if (needsBuildWorkspace()) {
                    progressReporter.report("Compiling...");
                    const proceed = await buildWorkspace(progressReporter);
                    if (!proceed) {
                        return undefined;
                    }
                }

                if (progressReporter.isCancelled()) {
                    return undefined;
                }
                if (!config.mainClass) {
                    progressReporter.report("Resolving main class...");
                } else {
                    progressReporter.report("Resolving launch configuration...");
                }
                const mainClassOption = await this.resolveAndValidateMainClass(folder && folder.uri, config, progressReporter);
                if (!mainClassOption || !mainClassOption.mainClass) { // Exit silently if the user cancels the prompt fix by ESC.
                    // Exit the debug session.
                    return undefined;
                }

                progressReporter.report("Resolving launch configuration...");
                config.mainClass = mainClassOption.mainClass;
                config.projectName = mainClassOption.projectName;

                if (progressReporter.isCancelled()) {
                    return undefined;
                }

                if (_.isEmpty(config.classPaths) && _.isEmpty(config.modulePaths)) {
                    const result = <any[]>(await lsPlugin.resolveClasspath(config.mainClass, config.projectName));
                    config.modulePaths = result[0];
                    config.classPaths = result[1];
                } else {
                    config.modulePaths = await this.resolvePath(folder, config.modulePaths, config.mainClass,
                        config.projectName, true /*isModulePath*/);
                    config.classPaths = await this.resolvePath(folder, config.classPaths, config.mainClass,
                        config.projectName, false /*isModulePath*/);
                }
                if (_.isEmpty(config.classPaths) && _.isEmpty(config.modulePaths)) {
                    throw new utility.UserError({
                        message: "Cannot resolve the modulepaths/classpaths automatically, please specify the value in the launch.json.",
                        type: Type.USAGEERROR,
                    });
                }

                config.javaExec = await lsPlugin.resolveJavaExecutable(config.mainClass, config.projectName);
                // Add the default launch options to the config.
                config.cwd = config.cwd || _.get(folder, "uri.fsPath");
                if (Array.isArray(config.args)) {
                    config.args = this.concatArgs(config.args);
                }

                if (Array.isArray(config.vmArgs)) {
                    config.vmArgs = this.concatArgs(config.vmArgs);
                }

                if (progressReporter.isCancelled()) {
                    return undefined;
                }
                // Populate the class filters to the debug configuration.
                await populateStepFilters(config);

                const targetJavaVersion: number = await getJavaVersion(config.javaExec);
                // Auto add '--enable-preview' vmArgs if the java project enables COMPILER_PB_ENABLE_PREVIEW_FEATURES flag.
                if (await lsPlugin.detectPreviewFlag(config.mainClass, config.projectName)) {
                    config.vmArgs = (config.vmArgs || "") + " --enable-preview";
                    validateRuntimeCompatibility(targetJavaVersion);
                }

                // Add more helpful vmArgs.
                await addMoreHelpfulVMArgs(config, targetJavaVersion);

                if (!config.shortenCommandLine || config.shortenCommandLine === "auto") {
                    config.shortenCommandLine = await getShortenApproachForCLI(config, targetJavaVersion);
                }

                // VS Code internal console uses UTF-8 to display output by default.
                if (config.console === "internalConsole" && !config.encoding) {
                    config.encoding = "UTF-8";
                }
            } else if (config.request === "attach") {
                if (config.hostName && config.port && Number.isInteger(Number(config.port))) {
                    config.port = Number(config.port);
                    config.processId = undefined;
                    // Continue if the hostName and port are configured.
                } else if (config.processId !== undefined) {
                    // tslint:disable-next-line
                    if (config.processId === "${command:PickJavaProcess}") {
                        return undefined;
                    }

                    const pid: number = Number(config.processId);
                    if (Number.isNaN(pid)) {
                        vscode.window.showErrorMessage(`The processId config '${config.processId}' is not a valid process id.`);
                        return undefined;
                    }

                    const javaProcess = await resolveJavaProcess(pid);
                    if (!javaProcess) {
                        vscode.window.showErrorMessage(`Attach to process: pid '${config.processId}' is not a debuggable Java process. `
                            + `Please make sure the process has turned on debug mode using vmArgs like `
                            + `'-agentlib:jdwp=transport=dt_socket,server=y,address=5005.'`);
                        return undefined;
                    }

                    config.processId = undefined;
                    config.hostName = javaProcess.hostName;
                    config.port = javaProcess.debugPort;
                } else {
                    throw new utility.UserError({
                        message: "Please specify the hostName/port directly, or provide the processId of the remote debuggee in the launch.json.",
                        type: Type.USAGEERROR,
                        anchor: anchor.ATTACH_CONFIG_ERROR,
                    });
                }

                // Populate the class filters to the debug configuration.
                await populateStepFilters(config);
            } else {
                throw new utility.UserError({
                    message: `Request type "${config.request}" is not supported. Only "launch" and "attach" are supported.`,
                    type: Type.USAGEERROR,
                    anchor: anchor.REQUEST_TYPE_NOT_SUPPORTED,
                });
            }

            if (token?.isCancellationRequested || progressReporter.isCancelled()) {
                return undefined;
            }

            delete config.__progressId;
            return config;
        } catch (ex) {
            if (ex instanceof utility.JavaExtensionNotEnabledError) {
                utility.guideToInstallJavaExtension();
                return undefined;
            }
            if (ex instanceof utility.UserError) {
                utility.showErrorMessageWithTroubleshooting(ex.context);
                return undefined;
            }

            utility.showErrorMessageWithTroubleshooting(utility.convertErrorToMessage(ex));
            return undefined;
        } finally {
            progressReporter.done();
        }
    }