class DEBUGGER__::Session

def process_protocol_result args

def process_protocol_result args
  type, req, result = args
  case type
  when :backtrace
    result[:callFrames].each.with_index do |frame, i|
      frame_id = frame[:callFrameId]
      @frame_map[frame_id] = i
      path = frame[:url]
      unless s_id = @scr_id_map[path]
        s_id = (@scr_id_map.size + 1).to_s
        @scr_id_map[path] = s_id
        lineno = 0
        src = ''
        if path && File.exist?(path)
          src = File.read(path)
          @src_map[s_id] = src
          lineno = src.lines.count
        end
        @ui.fire_event 'Debugger.scriptParsed',
                      scriptId: s_id,
                      url: path,
                      startLine: 0,
                      startColumn: 0,
                      endLine: lineno,
                      endColumn: 0,
                      executionContextId: 1,
                      hash: src.hash.inspect
      end
      frame[:location][:scriptId] = s_id
      frame[:functionLocation][:scriptId] = s_id
      frame[:scopeChain].each {|s|
        oid = s.dig(:object, :objectId)
        @obj_map[oid] = [s[:type], frame_id]
      }
    end
    if oid = result.dig(:data, :objectId)
      @obj_map[oid] = ['properties']
    end
    @ui.fire_event 'Debugger.paused', **result
  when :evaluate
    message = result.delete :message
    if message
      fail_response req,
                    code: INVALID_PARAMS,
                    message: message
    else
      src = req.dig('params', 'expression')
      s_id = (@src_map.size + 1).to_s
      @src_map[s_id] = src
      lineno = src.lines.count
      @ui.fire_event 'Debugger.scriptParsed',
                        scriptId: s_id,
                        url: '',
                        startLine: 0,
                        startColumn: 0,
                        endLine: lineno,
                        endColumn: 0,
                        executionContextId: 1,
                        hash: src.hash.inspect
      if exc = result.dig(:response, :exceptionDetails)
        exc[:stackTrace][:callFrames].each{|frame|
          if frame[:url].empty?
            frame[:scriptId] = s_id
          else
            path = frame[:url]
            unless s_id = @scr_id_map[path]
              s_id = (@scr_id_map.size + 1).to_s
              @scr_id_map[path] = s_id
            end
            frame[:scriptId] = s_id
          end
        }
        if oid = exc[:exception][:objectId]
          @obj_map[oid] = ['exception']
        end
      end
      rs = result.dig(:response, :result)
      [rs].each{|obj|
        if oid = obj[:objectId]
          @obj_map[oid] = ['properties']
        end
      }
      @ui.respond req, **result[:response]
      out = result[:output]
      if out && !out.empty?
        @ui.fire_event 'Runtime.consoleAPICalled',
                        type: 'log',
                        args: [
                          type: out.class,
                          value: out
                        ],
                        executionContextId: 1, # Change this number if something goes wrong.
                        timestamp: Time.now.to_f
      end
    end
  when :scope
    result.each{|obj|
      if oid = obj.dig(:value, :objectId)
        @obj_map[oid] = ['properties']
      end
    }
    @ui.respond req, result: result
  when :properties
    result.each_value{|v|
      v.each{|obj|
        if oid = obj.dig(:value, :objectId)
          @obj_map[oid] = ['properties']
        end
      }
    }
    @ui.respond req, **result
  when :exception
    @ui.respond req, **result
  end
end