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,
});
}
}