code: @Override
    public void parse(Reader reader) {
      try {
        ErrorRecorder errorRecorder = new ErrorRecorder();
        CourierLexer lexer;
        try {
          lexer = new CourierLexer(new ANTLRInputStream(reader));
        } catch (IOException e) {
          ParseError error = new ParseError(new ParseErrorLocation(0, 0), e.getMessage());
          startErrorMessage(error).append(error.message).append("\n");
          return;
        }
        lexer.removeErrorListeners();
        lexer.addErrorListener(errorRecorder);
  
        CourierParser parser = new CourierParser(new CommonTokenStream(lexer));
        parser.removeErrorListeners();
        parser.addErrorListener(errorRecorder);
  
        DocumentContext antlrDocument = parser.document();
        parse(antlrDocument);
  
        if (errorRecorder.errors.size() > 0) {
          for (ParseError error : errorRecorder.errors) {
            startErrorMessage(error).append(error.message).append("\n");
          }
        }
      } catch (ParseException e) {
        startErrorMessage(e.error).append(e.getMessage()).append("\n");
      }
    }
docs: Parse a JSON representation of a schema from a {{java.io.Reader}}.
  
  The top level {{DataSchema}}'s parsed are in {{#topLevelDataSchemas}}.
  These are the types that are not defined within other types.
  Parse errors are in {{#errorMessageBuilder}} and indicated
  by {{#hasError()}}.
  
  @param reader with the JSON representation of the schema.