private void parseField(
      List<String> fieldNames,
      List<ColumnMetaData.Rep> fieldTypes,
      Row.RowBuilder rowBuilder,
      JsonParser parser)
      throws IOException {
    final String fieldName = parser.getCurrentName();

    // Move to next token, which is name's value
    JsonToken token = parser.nextToken();
    int i = fieldNames.indexOf(fieldName);
    if (i < 0) {
      return;
    }
    ColumnMetaData.Rep type = fieldTypes.get(i);
    switch (token) {
      case VALUE_NUMBER_INT:
        if (type == null) {
          type = ColumnMetaData.Rep.INTEGER;
        }
        // fall through
      case VALUE_NUMBER_FLOAT:
        if (type == null) {
          type = ColumnMetaData.Rep.FLOAT;
        }
        switch (type) {
          case BYTE:
            rowBuilder.set(i, parser.getByteValue());
            break;
          case SHORT:
            rowBuilder.set(i, parser.getShortValue());
            break;
          case INTEGER:
            rowBuilder.set(i, parser.getIntValue());
            break;
          case LONG:
            rowBuilder.set(i, parser.getLongValue());
            break;
          case FLOAT:
            rowBuilder.set(i, parser.getFloatValue());
            break;
          case DOUBLE:
            rowBuilder.set(i, parser.getDoubleValue());
            break;
        }
        break;
      case VALUE_TRUE:
        rowBuilder.set(i, true);
        break;
      case VALUE_FALSE:
        rowBuilder.set(i, false);
        break;
      case VALUE_NULL:
        break;
      case VALUE_STRING:
      default:
        if (type == ColumnMetaData.Rep.JAVA_SQL_TIMESTAMP) {
          try {
            final Date parse = UTC_TIMESTAMP_FORMAT.parse(parser.getText());
            rowBuilder.set(i, parse.getTime());
          } catch (ParseException e) {
            // ignore bad value
          }
        } else {
          rowBuilder.set(i, parser.getText());
        }
        break;
    }
  }