public ParsedLine parse(byte[] lineBytes, int length) throws BadTsvLineException {
      // Enumerate separator offsets
      ArrayList<Integer> tabOffsets = new ArrayList<>(maxColumnCount);
      for (int i = 0; i < length; i++) {
        if (lineBytes[i] == separatorByte) {
          tabOffsets.add(i);
        }
      }
      if (tabOffsets.isEmpty()) {
        throw new BadTsvLineException("No delimiter");
      }

      tabOffsets.add(length);

      if (tabOffsets.size() > maxColumnCount) {
        throw new BadTsvLineException("Excessive columns");
      } else if (tabOffsets.size() <= getRowKeyColumnIndex()) {
        throw new BadTsvLineException("No row key");
      } else if (hasTimestamp() && tabOffsets.size() <= getTimestampKeyColumnIndex()) {
        throw new BadTsvLineException("No timestamp");
      } else if (hasAttributes() && tabOffsets.size() <= getAttributesKeyColumnIndex()) {
        throw new BadTsvLineException("No attributes specified");
      } else if (hasCellVisibility() && tabOffsets.size() <= getCellVisibilityColumnIndex()) {
        throw new BadTsvLineException("No cell visibility specified");
      } else if (hasCellTTL() && tabOffsets.size() <= getCellTTLColumnIndex()) {
        throw new BadTsvLineException("No cell TTL specified");
      }
      return new ParsedLine(tabOffsets, lineBytes);
    }
@param columnsSpecification the list of columns to parser out, comma separated. The row key
                            should be the special token TsvParser.ROWKEY_COLUMN_SPEC
hbase-mapreduce/src/main/java/org/apache/hadoop/hbase/mapreduce/ImportTsv.java