public void startReadSplitFromFile(
      FileSplit split, boolean[] splitIncludes, StripeData slice) throws IOException {
    boolean maySplitTheSplit = slice == null;
    ReaderWithOffsets offsetReader = null;
    @SuppressWarnings("rawtypes")
    RecordReader sourceReader = sourceInputFormat.getRecordReader(split, jobConf, reporter);
    Path path = split.getPath().getFileSystem(daemonConf).makeQualified(split.getPath());
    PartitionDesc partDesc = HiveFileFormatUtils.getFromPathRecursively(parts, path, null);
    try {
      offsetReader = createOffsetReader(sourceReader, partDesc.getTableDesc(), split);
      sourceReader = null;
    } finally {
      if (sourceReader != null) {
        try {
          sourceReader.close();
        } catch (Exception ex) {
          LlapIoImpl.LOG.error("Failed to close source reader", ex);
        }
      }
    }
    maySplitTheSplit = maySplitTheSplit && offsetReader.hasOffsets();

    try {
      StructObjectInspector originalOi = (StructObjectInspector)getOiFromSerDe();
      List<Integer> splitColumnIds = OrcInputFormat.genIncludedColumnsReverse(
          schema, splitIncludes, false);
      // fileread writes to the writer, which writes to orcWriter, which writes to cacheWriter
      EncodingWriter writer = VectorDeserializeOrcWriter.create(
          sourceInputFormat, sourceSerDe, parts, daemonConf, jobConf, split.getPath(), originalOi,
          splitColumnIds, splitIncludes, allocSize, encodeExecutor);
      // TODO: move this into ctor? EW would need to create CacheWriter then
      List<Integer> cwColIds = writer.isOnlyWritingIncludedColumns() ? splitColumnIds : columnIds;
      writer.init(new CacheWriter(bufferManager, cwColIds, splitIncludes,
          writer.isOnlyWritingIncludedColumns(), bufferFactory, isStopped), daemonConf, split.getPath());
      if (writer instanceof VectorDeserializeOrcWriter) {
        VectorDeserializeOrcWriter asyncWriter = (VectorDeserializeOrcWriter)writer;
        asyncWriter.startAsync(new AsyncCacheDataCallback());
        this.asyncWriters.add(asyncWriter);
      }
      currentFileRead = new FileReaderYieldReturn(
          offsetReader, split, writer, maySplitTheSplit, targetSliceRowCount);
    } finally {
      // Assignment is the last thing in the try, so if it happen we assume success.
      if (currentFileRead != null) return;
      if (offsetReader == null) return;
      try {
        offsetReader.close();
      } catch (Exception ex) {
        LlapIoImpl.LOG.error("Failed to close source reader", ex);
      }
    }
  }
This class only exists because Java doesn't have yield return. The original method
before this change only needed yield return-s sprinkled here and there; however,
Java developers are usually paid by class, so here we go.
llap-server/src/java/org/apache/hadoop/hive/llap/io/encoded/SerDeEncodedDataReader.java