class CsvParser {

    public Tuple2<Boolean, Row> parse(String line) {
        Row output = new Row(this.parsers.length);
        for (int i = 0; i < output.getArity(); i++) {
            output.setField(i, null);
        }
        if (line == null || line.isEmpty()) {
            return Tuple2.of(false, output);
        }
        int startPos = 0;
        boolean succ = true;
        final int limit = line.length();
        for (int i = 0; i < output.getArity(); i++) {
            if (startPos > limit) {
                succ = false;
                break;
            }
            boolean isStringCol = isString[i];
            int delimPos = findNextDelimPos(line, startPos, limit, isStringCol);
            if (delimPos < 0) {
                delimPos = limit;
            }
            String token = line.substring(startPos, delimPos);
            if (!token.isEmpty()) {
                Tuple2<Boolean, Object> parsed = parseField(parsers[i], token, isStringCol);
                if (!parsed.f0) {
                    succ = false;
                }
                output.setField(i, parsed.f1);
            }
            startPos = delimPos + this.lenFieldDelim;
        }
        return Tuple2.of(succ, output);
    }

    public  CsvParser(TypeInformation[] types, String fieldDelim, @Nullable Character quoteChar);

}