openrtb-core/src/main/java/com/google/openrtb/json/OpenRtbJsonUtils.java
public static String readCsvString(JsonParser par) throws IOException {
    JsonToken currentToken = par.getCurrentToken();
    if (currentToken == JsonToken.START_ARRAY) {
      StringBuilder keywords = new StringBuilder();
      for (startArray(par); endArray(par); par.nextToken()) {
        if (keywords.length() != 0) {
          keywords.append(',');
        }
        keywords.append(par.getText());
      }
      return keywords.toString();
    } else if (currentToken == JsonToken.VALUE_STRING) {
      return par.getText();
    } else {
      throw new JsonParseException(par, "Expected string or array");
    }
  }
public static String readCsvString(JsonParser par) throws IOException {
    JsonToken currentToken = par.getCurrentToken();
    if (currentToken == JsonToken.START_ARRAY) {
      StringBuilder keywords = new StringBuilder();
      for (startArray(par); endArray(par); par.nextToken()) {
        if (keywords.length() != 0) {
          keywords.append(',');
        }
        keywords.append(par.getText());
      }
      return keywords.toString();
    } else if (currentToken == JsonToken.VALUE_STRING) {
      return par.getText();
    } else {
      throw new JsonParseException(par, "Expected string or array");
    }
  }
Reads from either a JSON Value String (containing CSV) or a JSON Array.
The dual input format is needed because some fields (e.g. keywords) were allowed
to be of either type in OpenRTB 2.2; now in 2.3 they are all CSV strings only.
TODO: Simplify this to only accept CSV strings after 2.2 compatibility is dropped.