protected override void HandleInitializeRequestAsync()

in src/OpenDebugAD7/AD7DebugSession.cs [770:928]


        protected override void HandleInitializeRequestAsync(IRequestResponder<InitializeArguments, InitializeResponse> responder)
        {
            InitializeArguments arguments = responder.Arguments;

            m_engineConfiguration = EngineConfiguration.TryGet(arguments.AdapterID);

            m_engine = (IDebugEngine2)m_engineConfiguration.LoadEngine();

            TypeInfo engineType = m_engine.GetType().GetTypeInfo();
            HostTelemetry.InitializeTelemetry(SendTelemetryEvent, engineType, m_engineConfiguration.AdapterId);
            DebuggerTelemetry.InitializeTelemetry(Protocol.SendEvent, engineType, typeof(Host).GetTypeInfo(), m_engineConfiguration.AdapterId);

            HostOutputWindow.InitializeLaunchErrorCallback((error) => m_logger.WriteLine(LoggingCategory.DebuggerError, error));

            m_engineLaunch = (IDebugEngineLaunch2)m_engine;
            m_engine.SetRegistryRoot(m_engineConfiguration.AdapterId);
            m_port = new AD7Port(this);
            m_disconnectedOrTerminated = new ManualResetEvent(false);
            m_firstStoppingEvent = 0;

            if (m_engine is IDebugEngine110 engine110)
            {
                // MIEngine generally gets the radix from IDebugSettingsCallback110 rather than using the radix passed to individual
                //  APIs.  To support this mechanism outside of VS, provide a fake settings callback here that we can use to control
                //  the radix.
                m_settingsCallback = new DebugSettingsCallback();
                engine110.SetMainThreadSettingsCallback110(m_settingsCallback);
            }

            m_pathConverter.ClientLinesStartAt1 = arguments.LinesStartAt1.GetValueOrDefault(true);

            // Default is that they are URIs
            m_pathConverter.ClientPathsAreURI = !(arguments.PathFormat.GetValueOrDefault(InitializeArguments.PathFormatValue.Unknown) == InitializeArguments.PathFormatValue.Path);

            string clientId = responder.Arguments.ClientID;
            if (clientId == "visualstudio")
            {
                m_clientId = ClientId.VisualStudio;
            }
            else if (clientId == "vscode")
            {
                m_clientId = ClientId.VsCode;
            }
            else if (clientId == "liveshare-server-host")
            {
                m_clientId = ClientId.LiveshareServerHost;
            }
            else
            {
                m_clientId = ClientId.Unknown;
            }

            // If the UI supports RunInTerminal, then register the callback.
            // NOTE: Currently we don't support using the RunInTerminal request with VS or Windows Codespaces.
            //       This is because: (1) they don't support 'Integrated' terminal, and (2) for MIEngine, we don't ship WindowsDebugLauncher.exe.
            if (!IsClientVS && arguments.SupportsRunInTerminalRequest.GetValueOrDefault(false))
            {
                HostRunInTerminal.RegisterRunInTerminalCallback((title, cwd, useExternalConsole, commandArgs, env, success, error) =>
                {
                    RunInTerminalRequest request = new RunInTerminalRequest()
                    {
                        Arguments = commandArgs.ToList<string>(),
                        Kind = useExternalConsole ? RunInTerminalArguments.KindValue.External : RunInTerminalArguments.KindValue.Integrated,
                        Title = title,
                        Cwd = cwd,
                        Env = env
                    };

                    Protocol.SendClientRequest(
                        request,
                        (args, responseBody) =>
                        {
                            // responseBody can be null
                            success(responseBody?.ProcessId);
                        },
                        (args, exception) =>
                        {
                            new OutputEvent() { Category = OutputEvent.CategoryValue.Stderr, Output = exception.ToString() };
                            Protocol.SendEvent(new TerminatedEvent());
                            error(exception.ToString());
                        });
                });
            }

            List<ColumnDescriptor> additionalModuleColumns = null;

            if (IsClientVS)
            {
                additionalModuleColumns = new List<ColumnDescriptor>();
                additionalModuleColumns.Add(new ColumnDescriptor(){
                    AttributeName = "vsLoadAddress",
                    Label = "Load Address",
                    Format = "string",
                    Type = ColumnDescriptor.TypeValue.String
                });
                additionalModuleColumns.Add(new ColumnDescriptor(){
                    AttributeName = "vsPreferredLoadAddress",
                    Label = "Preferred Load Address",
                    Format = "string",
                    Type = ColumnDescriptor.TypeValue.String
                });
                additionalModuleColumns.Add(new ColumnDescriptor(){
                    AttributeName = "vsModuleSize",
                    Label = "Module Size",
                    Format = "string",
                    Type = ColumnDescriptor.TypeValue.Number
                });
                additionalModuleColumns.Add(new ColumnDescriptor(){
                    AttributeName = "vsLoadOrder",
                    Label = "Order",
                    Format = "string",
                    Type = ColumnDescriptor.TypeValue.Number
                });
                additionalModuleColumns.Add(new ColumnDescriptor(){
                    AttributeName = "vsTimestampUTC",
                    Label = "Timestamp",
                    Format = "string",
                    Type = ColumnDescriptor.TypeValue.UnixTimestampUTC
                });
                additionalModuleColumns.Add(new ColumnDescriptor(){
                    AttributeName = "vsIs64Bit",
                    Label = "64-bit",
                    Format = "string",
                    Type = ColumnDescriptor.TypeValue.Boolean
                });
            }

            // -catch-throw is not supported in lldb-mi
            List<ExceptionBreakpointsFilter> filters = new List<ExceptionBreakpointsFilter>();
            if (!Utilities.IsOSX())
            {
                filters = m_engineConfiguration.ExceptionSettings.ExceptionBreakpointFilters.Select(item => new ExceptionBreakpointsFilter() { Default = item.@default, Filter = item.filter, Label = item.label, SupportsCondition = item.supportsCondition, ConditionDescription = item.conditionDescription }).ToList();
            }

            InitializeResponse initializeResponse = new InitializeResponse()
            {
                SupportsConfigurationDoneRequest = true,
                SupportsCompletionsRequest = m_engine is IDebugProgramDAP,
                SupportsEvaluateForHovers = true,
                SupportsSetVariable = true,
                SupportsFunctionBreakpoints = m_engineConfiguration.FunctionBP,
                SupportsConditionalBreakpoints = m_engineConfiguration.ConditionalBP,
                SupportsDataBreakpoints = m_engineConfiguration.DataBP,
                ExceptionBreakpointFilters = filters,
                SupportsExceptionFilterOptions = filters.Any(),
                SupportsClipboardContext = m_engineConfiguration.ClipboardContext,
                SupportsLogPoints = true,
                SupportsReadMemoryRequest = m_engine is IDebugMemoryBytesDAP, // TODO: Read from configuration or query engine for capabilities.
                SupportsModulesRequest = true,
                AdditionalModuleColumns = additionalModuleColumns,
                SupportsGotoTargetsRequest = true,
                SupportsDisassembleRequest = m_engine is IDebugMemoryBytesDAP,
                SupportsValueFormattingOptions = true,
                SupportsSteppingGranularity = true,
                SupportsInstructionBreakpoints = m_engine is IDebugMemoryBytesDAP
            };

            responder.SetResponse(initializeResponse);
        }