collect method

Implementation

TreeSitterCollectedInput collect() {
  final codePoints = <int>[];
  final sourceBytes = BytesBuilder(copy: false);
  final decodedByteOffsets = <int>[0];
  final encodedByteOffsets = <int>[0];
  final decodedUtf16Offsets = <int>[0];
  final encodedPoints = <TreeSitterPoint>[const TreeSitterPoint(0, 0)];
  var byteOffset = 0;
  var decodedByteOffset = 0;
  var decodedUtf16Offset = 0;
  var point = const TreeSitterPoint(0, 0);
  while (true) {
    final values = read(byteOffset, point);
    if (values.isEmpty) break;
    for (final value in values) {
      if (value < 0 || value > 0xff) {
        throw RangeError.range(value, 0, 0xff, 'encoded input byte');
      }
    }
    var chunkOffset = 0;
    while (chunkOffset < values.length) {
      final result = decode(values.sublist(chunkOffset));
      if (result.bytesConsumed == 0) {
        return TreeSitterCollectedInput(
          source: String.fromCharCodes(codePoints),
          byteLength: byteOffset,
          endPoint: point,
          sourceBytes: sourceBytes.takeBytes(),
          decodedMap: TreeSitterDecodedInputMap._(
            decodedByteOffsets: decodedByteOffsets,
            encodedByteOffsets: encodedByteOffsets,
            decodedUtf16Offsets: decodedUtf16Offsets,
            encodedPoints: encodedPoints,
          ),
        );
      }
      if (result.bytesConsumed < 0 ||
          result.bytesConsumed > values.length - chunkOffset) {
        throw StateError(
          'Custom decoder consumed ${result.bytesConsumed} bytes from a '
          '${values.length - chunkOffset}-byte input.',
        );
      }
      if (result.codePoint < 0 || result.codePoint > 0x10ffff) {
        throw RangeError.range(
          result.codePoint,
          0,
          0x10ffff,
          'decoded code point',
        );
      }
      codePoints.add(result.codePoint);
      sourceBytes.add(
        Uint8List.fromList(
          values.sublist(chunkOffset, chunkOffset + result.bytesConsumed),
        ),
      );
      chunkOffset += result.bytesConsumed;
      byteOffset += result.bytesConsumed;
      decodedByteOffset += utf8
          .encode(String.fromCharCode(result.codePoint))
          .length;
      decodedUtf16Offset += result.codePoint > 0xffff ? 2 : 1;
      point = result.codePoint == 0x0a
          ? TreeSitterPoint(point.row + 1, 0)
          : TreeSitterPoint(point.row, point.column + result.bytesConsumed);
      decodedByteOffsets.add(decodedByteOffset);
      encodedByteOffsets.add(byteOffset);
      decodedUtf16Offsets.add(decodedUtf16Offset);
      encodedPoints.add(point);
    }
  }
  return TreeSitterCollectedInput(
    source: String.fromCharCodes(codePoints),
    byteLength: byteOffset,
    endPoint: point,
    sourceBytes: sourceBytes.takeBytes(),
    decodedMap: TreeSitterDecodedInputMap._(
      decodedByteOffsets: decodedByteOffsets,
      encodedByteOffsets: encodedByteOffsets,
      decodedUtf16Offsets: decodedUtf16Offsets,
      encodedPoints: encodedPoints,
    ),
  );
}