void _delegateRequest()

in pkg/vm_service/lib/src/vm_service.dart [1324:1726]


  void _delegateRequest(Map<String, Object?> request) async {
    try {
      var id = request['id'];
      // Check if this is actually a response to a pending request.
      if (_pendingServiceExtensionRequests.containsKey(id)) {
        final pending = _pendingServiceExtensionRequests[id]!;
        pending.complete(Map<String, Object?>.of(request));
        return;
      }
      final method = request['method'] as String?;
      if (method == null) {
        throw RPCError(
            null, RPCError.kInvalidRequest, 'Invalid Request', request);
      }
      final params = request['params'] as Map<String, dynamic>?;
      late Response response;

      switch (method) {
        case 'registerService':
          _serviceExtensionRegistry.registerExtension(params!['service'], this);
          response = Success();
          break;
        case 'addBreakpoint':
          response = await _serviceImplementation.addBreakpoint(
            params!['isolateId'],
            params['scriptId'],
            params['line'],
            column: params['column'],
          );
          break;
        case 'addBreakpointWithScriptUri':
          response = await _serviceImplementation.addBreakpointWithScriptUri(
            params!['isolateId'],
            params['scriptUri'],
            params['line'],
            column: params['column'],
          );
          break;
        case 'addBreakpointAtEntry':
          response = await _serviceImplementation.addBreakpointAtEntry(
            params!['isolateId'],
            params['functionId'],
          );
          break;
        case 'clearCpuSamples':
          response = await _serviceImplementation.clearCpuSamples(
            params!['isolateId'],
          );
          break;
        case 'clearVMTimeline':
          response = await _serviceImplementation.clearVMTimeline();
          break;
        case 'invoke':
          response = await _serviceImplementation.invoke(
            params!['isolateId'],
            params['targetId'],
            params['selector'],
            List<String>.from(params['argumentIds'] ?? []),
            disableBreakpoints: params['disableBreakpoints'],
          );
          break;
        case 'evaluate':
          response = await _serviceImplementation.evaluate(
            params!['isolateId'],
            params['targetId'],
            params['expression'],
            scope: params['scope']?.cast<String, String>(),
            disableBreakpoints: params['disableBreakpoints'],
          );
          break;
        case 'evaluateInFrame':
          response = await _serviceImplementation.evaluateInFrame(
            params!['isolateId'],
            params['frameIndex'],
            params['expression'],
            scope: params['scope']?.cast<String, String>(),
            disableBreakpoints: params['disableBreakpoints'],
          );
          break;
        case 'getAllocationProfile':
          response = await _serviceImplementation.getAllocationProfile(
            params!['isolateId'],
            reset: params['reset'],
            gc: params['gc'],
          );
          break;
        case 'getAllocationTraces':
          response = await _serviceImplementation.getAllocationTraces(
            params!['isolateId'],
            timeOriginMicros: params['timeOriginMicros'],
            timeExtentMicros: params['timeExtentMicros'],
            classId: params['classId'],
          );
          break;
        case 'getClassList':
          response = await _serviceImplementation.getClassList(
            params!['isolateId'],
          );
          break;
        case 'getCpuSamples':
          response = await _serviceImplementation.getCpuSamples(
            params!['isolateId'],
            params['timeOriginMicros'],
            params['timeExtentMicros'],
          );
          break;
        case 'getFlagList':
          response = await _serviceImplementation.getFlagList();
          break;
        case 'getInboundReferences':
          response = await _serviceImplementation.getInboundReferences(
            params!['isolateId'],
            params['targetId'],
            params['limit'],
          );
          break;
        case 'getInstances':
          response = await _serviceImplementation.getInstances(
            params!['isolateId'],
            params['objectId'],
            params['limit'],
          );
          break;
        case 'getIsolate':
          response = await _serviceImplementation.getIsolate(
            params!['isolateId'],
          );
          break;
        case 'getIsolateGroup':
          response = await _serviceImplementation.getIsolateGroup(
            params!['isolateGroupId'],
          );
          break;
        case 'getMemoryUsage':
          response = await _serviceImplementation.getMemoryUsage(
            params!['isolateId'],
          );
          break;
        case 'getIsolateGroupMemoryUsage':
          response = await _serviceImplementation.getIsolateGroupMemoryUsage(
            params!['isolateGroupId'],
          );
          break;
        case 'getScripts':
          response = await _serviceImplementation.getScripts(
            params!['isolateId'],
          );
          break;
        case 'getObject':
          response = await _serviceImplementation.getObject(
            params!['isolateId'],
            params['objectId'],
            offset: params['offset'],
            count: params['count'],
          );
          break;
        case 'getPorts':
          response = await _serviceImplementation.getPorts(
            params!['isolateId'],
          );
          break;
        case 'getRetainingPath':
          response = await _serviceImplementation.getRetainingPath(
            params!['isolateId'],
            params['targetId'],
            params['limit'],
          );
          break;
        case 'getProcessMemoryUsage':
          response = await _serviceImplementation.getProcessMemoryUsage();
          break;
        case 'getStack':
          response = await _serviceImplementation.getStack(
            params!['isolateId'],
            limit: params['limit'],
          );
          break;
        case 'getSupportedProtocols':
          response = await _serviceImplementation.getSupportedProtocols();
          break;
        case 'getSourceReport':
          response = await _serviceImplementation.getSourceReport(
            params!['isolateId'],
            List<String>.from(params['reports'] ?? []),
            scriptId: params['scriptId'],
            tokenPos: params['tokenPos'],
            endTokenPos: params['endTokenPos'],
            forceCompile: params['forceCompile'],
            reportLines: params['reportLines'],
          );
          break;
        case 'getVersion':
          response = await _serviceImplementation.getVersion();
          break;
        case 'getVM':
          response = await _serviceImplementation.getVM();
          break;
        case 'getVMTimeline':
          response = await _serviceImplementation.getVMTimeline(
            timeOriginMicros: params!['timeOriginMicros'],
            timeExtentMicros: params['timeExtentMicros'],
          );
          break;
        case 'getVMTimelineFlags':
          response = await _serviceImplementation.getVMTimelineFlags();
          break;
        case 'getVMTimelineMicros':
          response = await _serviceImplementation.getVMTimelineMicros();
          break;
        case 'pause':
          response = await _serviceImplementation.pause(
            params!['isolateId'],
          );
          break;
        case 'kill':
          response = await _serviceImplementation.kill(
            params!['isolateId'],
          );
          break;
        case 'lookupResolvedPackageUris':
          response = await _serviceImplementation.lookupResolvedPackageUris(
            params!['isolateId'],
            List<String>.from(params['uris'] ?? []),
          );
          break;
        case 'lookupPackageUris':
          response = await _serviceImplementation.lookupPackageUris(
            params!['isolateId'],
            List<String>.from(params['uris'] ?? []),
          );
          break;
        case 'reloadSources':
          response = await _serviceImplementation.reloadSources(
            params!['isolateId'],
            force: params['force'],
            pause: params['pause'],
            rootLibUri: params['rootLibUri'],
            packagesUri: params['packagesUri'],
          );
          break;
        case 'removeBreakpoint':
          response = await _serviceImplementation.removeBreakpoint(
            params!['isolateId'],
            params['breakpointId'],
          );
          break;
        case 'requestHeapSnapshot':
          response = await _serviceImplementation.requestHeapSnapshot(
            params!['isolateId'],
          );
          break;
        case 'resume':
          response = await _serviceImplementation.resume(
            params!['isolateId'],
            step: params['step'],
            frameIndex: params['frameIndex'],
          );
          break;
        case 'setBreakpointState':
          response = await _serviceImplementation.setBreakpointState(
            params!['isolateId'],
            params['breakpointId'],
            params['enable'],
          );
          break;
        case 'setExceptionPauseMode':
          // ignore: deprecated_member_use_from_same_package
          response = await _serviceImplementation.setExceptionPauseMode(
            params!['isolateId'],
            params['mode'],
          );
          break;
        case 'setIsolatePauseMode':
          response = await _serviceImplementation.setIsolatePauseMode(
            params!['isolateId'],
            exceptionPauseMode: params['exceptionPauseMode'],
            shouldPauseOnExit: params['shouldPauseOnExit'],
          );
          break;
        case 'setFlag':
          response = await _serviceImplementation.setFlag(
            params!['name'],
            params['value'],
          );
          break;
        case 'setLibraryDebuggable':
          response = await _serviceImplementation.setLibraryDebuggable(
            params!['isolateId'],
            params['libraryId'],
            params['isDebuggable'],
          );
          break;
        case 'setName':
          response = await _serviceImplementation.setName(
            params!['isolateId'],
            params['name'],
          );
          break;
        case 'setTraceClassAllocation':
          response = await _serviceImplementation.setTraceClassAllocation(
            params!['isolateId'],
            params['classId'],
            params['enable'],
          );
          break;
        case 'setVMName':
          response = await _serviceImplementation.setVMName(
            params!['name'],
          );
          break;
        case 'setVMTimelineFlags':
          response = await _serviceImplementation.setVMTimelineFlags(
            List<String>.from(params!['recordedStreams'] ?? []),
          );
          break;
        case 'streamCancel':
          var id = params!['streamId'];
          var existing = _streamSubscriptions.remove(id);
          if (existing == null) {
            throw RPCError.withDetails(
              'streamCancel',
              104,
              'Stream not subscribed',
              details: "The stream '$id' is not subscribed",
            );
          }
          await existing.cancel();
          response = Success();
          break;
        case 'streamCpuSamplesWithUserTag':
          response = await _serviceImplementation.streamCpuSamplesWithUserTag(
            List<String>.from(params!['userTags'] ?? []),
          );
          break;
        case 'streamListen':
          var id = params!['streamId'];
          if (_streamSubscriptions.containsKey(id)) {
            throw RPCError.withDetails(
              'streamListen',
              103,
              'Stream already subscribed',
              details: "The stream '$id' is already subscribed",
            );
          }

          var stream = id == 'Service'
              ? _serviceExtensionRegistry.onExtensionEvent
              : _serviceImplementation.onEvent(id);
          _streamSubscriptions[id] = stream.listen((e) {
            _responseSink.add({
              'jsonrpc': '2.0',
              'method': 'streamNotify',
              'params': {
                'streamId': id,
                'event': e.toJson(),
              },
            });
          });
          response = Success();
          break;
        default:
          final registeredClient = _serviceExtensionRegistry.clientFor(method);
          if (registeredClient != null) {
            // Check for any client which has registered this extension, if we
            // have one then delegate the request to that client.
            _responseSink.add(await registeredClient
                ._forwardServiceExtensionRequest(request));
            // Bail out early in this case, we are just acting as a proxy and
            // never get a `Response` instance.
            return;
          } else if (method.startsWith('ext.')) {
            // Remaining methods with `ext.` are assumed to be registered via
            // dart:developer, which the service implementation handles.
            final args =
                params == null ? null : Map<String, dynamic>.of(params);
            final isolateId = args?.remove('isolateId');
            response = await _serviceImplementation.callServiceExtension(method,
                isolateId: isolateId, args: args);
          } else {
            throw RPCError(
                method, RPCError.kMethodNotFound, 'Method not found', request);
          }
      }
      _responseSink.add({
        'jsonrpc': '2.0',
        'id': id,
        'result': response.toJson(),
      });
    } catch (e, st) {
      final error = e is RPCError
          ? e.toMap()
          : {
              'code': RPCError.kInternalError,
              'message': '${request['method']}: $e',
              'data': {'details': '$st'},
            };
      _responseSink.add({
        'jsonrpc': '2.0',
        'id': request['id'],
        'error': error,
      });
    }
  }