callServiceExtension method

  1. @override
Future<Response> callServiceExtension(
  1. String method, {
  2. String? isolateId,
  3. Map<String, dynamic>? args,
})

Invoke a specific service protocol extension method.

See https://api.dart.dev/stable/dart-developer/dart-developer-library.html.

Implementation

@override
Future<Response> callServiceExtension(
  String method, {
  String? isolateId,
  Map<String, dynamic>? args,
}) async {
  // Fixture-serving short-circuit. When a fixture is
  // configured, the binding's empty-tree observation is bypassed for
  // exactly this one method; everything else falls through to the
  // registry/extension routing below.
  final Object? fx = observationFixture;
  if (fx != null && method == _kObservationMethod) {
    final Map<String, dynamic> body =
        (fx as dynamic).body as Map<String, dynamic>;
    final Response r = Response();
    r.json = <String, dynamic>{'type': 'Observation', 'value': body};
    return r;
  }
  final Map<String, String> stringArgs = <String, String>{
    for (final MapEntry<String, dynamic> e
        in (args ?? const <String, dynamic>{}).entries)
      e.key: e.value is String ? e.value as String : jsonEncode(e.value),
  };
  // Route by registry, not by URL prefix. Extension tools (registered via
  // ExtensionContext.registerExtension) live in extensionRegistry.mergedTools()
  // keyed by '<ns>.<tool>'. Binding-owned extensions (handshake,
  // get_stable_observation, get_recent_errors, screenshot,
  // diagnostics_warnings) live in _extensionCallbacks and are reached
  // via invokeServiceExtension. The 'core.*' URL prefix is NOT a
  // routing signal — CoreExtension's per-tool extensions live in the
  // registry, not in _extensionCallbacks.
  const String prefix = 'ext.exploration.';
  if (!method.startsWith(prefix)) {
    throw RPCError(method, -32601, 'Unknown method "$method"');
  }
  final String suffix = method.substring(prefix.length);
  final String body;
  if (_binding.extensionRegistry.mergedTools().containsKey(suffix)) {
    body = await _binding.invokeExtensionTool(method, stringArgs);
  } else {
    body = await _binding.invokeServiceExtension(method, stringArgs);
  }
  final Response r = Response();
  r.json = jsonDecode(body) as Map<String, dynamic>;
  return r;
}