execute method

Map<String, Object?> execute(
  1. Map<String, Object?> request
)

Implementation

Map<String, Object?> execute(Map<String, Object?> request) {
  final totalTimer = Stopwatch()..start();
  final session = request['session']! as String;
  final revision = request['revision']! as int;
  final grammarName = request['grammar']! as String;
  final fullSnapshot =
      request.containsKey('source') || request.containsKey('sourceChunks');
  final sameGrammar =
      !fullSnapshot && _sessionGrammars[session] == grammarName;
  final sourceTimer = Stopwatch()..start();
  final resolved = _sourceFor(request, session, revision);
  sourceTimer.stop();
  final source = resolved.source;
  final grammar = _grammars[grammarName];
  if (grammar == null) {
    throw StateError('Grammar $grammarName has not been loaded.');
  }
  final parser = _parserForSession(session, grammarName, grammar);
  // Every mutation follows Tree-sitter's normal incremental path. Empty,
  // one-character, and whole-document replacements are not separate parser
  // modes: the edit is applied to the persistent tree just like any other
  // replacement, allowing subsequent rapid edits to retain one coherent
  // session base.
  final previous = sameGrammar ? _trees[session] : null;
  final previousSpans = sameGrammar ? _spanCaches[session] : null;
  final treeEdits = resolved.edits;
  final parseTimer = Stopwatch()..start();
  final parsed = parser.parse(
    source,
    oldTree: previous,
    edits: treeEdits,
    annotateLocals: grammar.highlightsQuery.requiresLocalProperties,
  );
  parseTimer.stop();
  _trees[session] = parsed;
  _sessionGrammars[session] = grammarName;
  final rangeTimer = Stopwatch()..start();
  final highlightRange = previousSpans == null
      ? null
      : _incrementalHighlightRange(source, parsed, resolved.edits);
  rangeTimer.stop();
  final queryTimer = Stopwatch()..start();
  final spans = _highlightGrammar(
    grammarName,
    grammar,
    _grammars,
    parsed.rootNode,
    source,
    highlightRange,
  );
  queryTimer.stop();
  final spliceTimer = Stopwatch()..start();
  final queriedSpans = spans;
  final workerSpans = previousSpans == null || highlightRange == null
      ? queriedSpans
      : _spliceIncrementalSpans(
          previousSpans,
          queriedSpans,
          resolved.edits,
          highlightRange,
        );
  spliceTimer.stop();
  final patchTimer = Stopwatch()..start();
  final patch = _spanPatch(previousSpans, workerSpans);
  patchTimer.stop();
  _spanCaches[session] = workerSpans;
  final scopes = <String>[];
  final scopeIds = <String, int>{};
  final packedSpans = Uint32List(patch.inserted.length * 5);
  for (var index = 0; index < patch.inserted.length; index++) {
    final span = patch.inserted[index];
    final scope = scopeIds.putIfAbsent(span.scope, () {
      scopes.add(span.scope);
      return scopes.length - 1;
    });
    final output = index * 5;
    packedSpans[output] = span.start;
    packedSpans[output + 1] = span.end;
    packedSpans[output + 2] = scope;
    packedSpans[output + 3] = span.priority;
    packedSpans[output + 4] = span.order;
  }
  final changedLinesTimer = Stopwatch()..start();
  final changedLines = Uint32List.fromList(
    _changedLines(source, previous, parsed),
  );
  changedLinesTimer.stop();
  totalTimer.stop();
  return <String, Object?>{
    'revision': revision,
    'sourceLength': source.length,
    'rootKind': parsed.rootNode.kind,
    'rootStartByte': parsed.rootNode.startByte,
    'rootEndByte': parsed.rootNode.endByte,
    'rootHasError': parsed.rootNode.hasError,
    'reusedNodeCount': parsed.reusedNodeCount,
    'lexedTokenCount': parsed.generatedTree?.lexedTokenCount ?? 0,
    'parsePassCount': parsed.generatedTree?.parsePassCount ?? 0,
    'parserInstanceId': _parserInstanceIds[(session, grammarName)],
    'parserCreationCount': _parserCreationCounts[session],
    'lexedBytes': parsed.lexedBytes,
    'reusedBytes': parsed.reusedBytes,
    'parseActionCount': parsed.parseActionCount,
    'reuseCursorVisitCount': parsed.reuseCursorVisitCount,
    'firstLexedByte': parsed.generatedTree?.firstLexedByte,
    'lastLexedByte': parsed.generatedTree?.lastLexedByte,
    'reuseRejections': parsed.generatedTree?.reuseRejections ?? const {},
    'queriedUtf16Length': highlightRange?.length ?? source.length,
    'scopes': scopes,
    'packedSpans': packedSpans,
    'spanPatchStart': patch.start,
    'spanPatchRemove': patch.removeCount,
    'spanPatchSuffixShift': patch.suffixShift,
    'isSpanPatch': previousSpans != null,
    'changedLines': changedLines,
    'phaseTimingsMicros': <String, int>{
      'source': sourceTimer.elapsedMicroseconds,
      'parseAndConvert': parseTimer.elapsedMicroseconds,
      'range': rangeTimer.elapsedMicroseconds,
      'queryAndSort': queryTimer.elapsedMicroseconds,
      'splice': spliceTimer.elapsedMicroseconds,
      'patch': patchTimer.elapsedMicroseconds,
      'changedLines': changedLinesTimer.elapsedMicroseconds,
      'total': totalTimer.elapsedMicroseconds,
      for (final entry in parsed.phaseTimingsMicros.entries)
        'parse.${entry.key}': entry.value,
    },
  };
}