private async Task DispatchAsync()

in libraries/Microsoft.Bot.Builder.Dialogs.Debugging/DialogDebugAdapter.cs [430:692]


        private async Task<Message> DispatchAsync(Message message, CancellationToken cancellationToken)
        {
            if (message is Request request)
            {
                if (message is Request<Initialize> initialize)
                {
                    var body = MakeCapabilities();
                    var response = Response.From(NextSeq, initialize, body);
                    await SendAsync(response, cancellationToken).ConfigureAwait(false);
                    return Event.From(NextSeq, "initialized", new { });
                }

                if (message is Request<Launch> launch)
                {
                    _options = launch.Arguments;
                    return Response.From(NextSeq, launch, new { });
                }

                if (message is Request<Attach> attach)
                {
                    _options = attach.Arguments;
                    return Response.From(NextSeq, attach, new { });
                }

                if (message is Request<SetBreakpoints> setBreakpoints)
                {
                    var arguments = setBreakpoints.Arguments;
                    var file = Path.GetFileName(arguments.Source.Path);
                    await OutputAsync($"Set breakpoints for {file}", null, null, cancellationToken).ConfigureAwait(false);

                    var breakpoints = _breakpoints.SetBreakpoints(arguments.Source, arguments.Breakpoints);
                    foreach (var breakpoint in breakpoints)
                    {
                        if (breakpoint.Verified)
                        {
                            var item = _breakpoints.ItemFor(breakpoint);
                            await OutputAsync($"Set breakpoint at {_codeModel.NameFor(item)}", item, null, cancellationToken).ConfigureAwait(false);
                        }
                    }

                    return Response.From(NextSeq, setBreakpoints, new { breakpoints });
                }

                if (message is Request<SetFunctionBreakpoints> setFunctionBreakpoints)
                {
                    var arguments = setFunctionBreakpoints.Arguments;
                    await OutputAsync("Set function breakpoints.", null, null, cancellationToken).ConfigureAwait(false);
                    var breakpoints = _breakpoints.SetBreakpoints(arguments.Breakpoints);
                    foreach (var breakpoint in breakpoints)
                    {
                        if (breakpoint.Verified)
                        {
                            var item = _breakpoints.ItemFor(breakpoint);
                            await OutputAsync($"Set breakpoint at {_codeModel.NameFor(item)}", item, null, cancellationToken).ConfigureAwait(false);
                        }
                    }

                    return Response.From(NextSeq, setFunctionBreakpoints, new { breakpoints });
                }

                if (message is Request<SetExceptionBreakpoints> setExceptionBreakpoints)
                {
                    var arguments = setExceptionBreakpoints.Arguments;
                    _events.Reset(arguments.Filters);

                    return Response.From(NextSeq, setExceptionBreakpoints, new { });
                }

                if (message is Request<Threads> threads)
                {
                    var body = new
                    {
                        threads = _threads.Select(t => new
                        {
                            id = t.Key,
                            name = t.Value.Name
                        }).ToArray()
                    };

                    return Response.From(NextSeq, threads, body);
                }

                if (message is Request<StackTrace> stackTrace)
                {
                    var arguments = stackTrace.Arguments;
                    var thread = _threads[arguments.ThreadId];

                    var frames = thread.Frames;
                    var stackFrames = new List<StackFrame>();
                    foreach (var frame in frames)
                    {
                        var stackFrame = new StackFrame
                        {
                            Id = EncodeFrame(thread, frame),
                            Name = frame.Name
                        };

                        var item = _codeModel.NameFor(frame.Item);
                        DebuggerSourceMap.Assign(stackFrame, item, frame.More);

                        if (_sourceMap.TryGetValue(frame.Item, out var range))
                        {
                            DebuggerSourceMap.Assign(stackFrame, range);
                        }

                        stackFrames.Add(stackFrame);
                    }

                    return Response.From(NextSeq, stackTrace, new { stackFrames });
                }

                if (message is Request<Scopes> scopes)
                {
                    var arguments = scopes.Arguments;
                    DecodeFrame(arguments.FrameId, out var thread, out var frame);
                    const bool expensive = false;

                    var body = new
                    {
                        scopes = new[]
                        {
                            new
                            {
                                expensive,
                                name = frame.Name,
                                variablesReference = EncodeValue(thread, frame.Data)
                            }
                        }
                    };

                    return Response.From(NextSeq, scopes, body);
                }

                if (message is Request<Variables> vars)
                {
                    var arguments = vars.Arguments;
                    DecodeValue(arguments.VariablesReference, out var arena, out var context);

                    var names = _dataModel.Names(context);

                    var body = new
                    {
                        variables = (from name in names
                                     let value = _dataModel[context, name]
                                     let variablesReference = EncodeValue(arena, value)
                                     select new
                                     {
                                         name = _dataModel.ToString(name),
                                         value = _dataModel.ToString(value),
                                         variablesReference
                                     })
                            .ToArray()
                    };

                    return Response.From(NextSeq, vars, body);
                }

                if (message is Request<SetVariable> setVariable)
                {
                    var arguments = setVariable.Arguments;
                    DecodeValue(arguments.VariablesReference, out var arena, out var context);

                    var value = _dataModel[context, arguments.Name] = JToken.Parse(arguments.Value);

                    var body = new
                    {
                        value = _dataModel.ToString(value),
                        variablesReference = EncodeValue(arena, value)
                    };

                    return Response.From(NextSeq, setVariable, body);
                }

                if (message is Request<Evaluate> evaluate)
                {
                    var arguments = evaluate.Arguments;
                    DecodeFrame(arguments.FrameId, out var thread, out var frame);
                    var expression = arguments.Expression.Trim('"');

                    try
                    {
                        var result = frame.Evaluate(expression);
                        var body = new
                        {
                            result = _dataModel.ToString(result),
                            variablesReference = EncodeValue(thread, result),
                        };

                        return Response.From(NextSeq, evaluate, body);
                    }
#pragma warning disable CA1031 // Do not catch general exception types (catch any exception and return it)
                    catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
                    {
                        return Response.Fail(NextSeq, evaluate, ex.Message);
                    }
                }

                Response Post<TBody>(PerThread perThread, Phase phase, TBody body)
                {
                    // "constructing the response" and "posting to the thread" have side-effects
                    // for extra determinism, construct the response before signaling the thread
                    var response = Response.From(NextSeq, request, body);

                    var found = _threads.TryGetValue(perThread.ThreadId, out var thread);
                    if (found)
                    {
                        thread.Run.Post(phase);
                    }

                    return response;
                }

                if (message is Request<Continue> cont)
                {
                    return Post(cont.Arguments, Phase.Continue, new { allThreadsContinued = false });
                }

                if (message is Request<Pause> pause)
                {
                    return Post(pause.Arguments, Phase.Pause, new { });
                }

                if (message is Request<Next> next)
                {
                    return Post(next.Arguments, Phase.Next, new { });
                }

                if (message is Request<Terminate> terminate)
                {
                    if (_terminate != null)
                    {
                        _terminate();
                    }

                    return Response.From(NextSeq, terminate, new { });
                }

                if (message is Request<Disconnect> disconnect)
                {
                    var arguments = disconnect.Arguments;
                    if (arguments.TerminateDebuggee && _terminate != null)
                    {
                        _terminate();
                    }
                    else
                    {
                        ResetOnDisconnect();
                    }

                    return Response.From(NextSeq, disconnect, new { });
                }

                return Response.From(NextSeq, request, new { });
            }

            if (message is Event @event)
            {
                throw new NotImplementedException();
            }

            throw new NotImplementedException();
        }