private Message parseMessage()

in lang/java/avro/src/main/java/org/apache/avro/Protocol.java [599:684]


  private Message parseMessage(String messageName, JsonNode json) {
    String doc = parseDocNode(json);

    Map<String, JsonNode> mProps = new LinkedHashMap<>();
    for (Iterator<String> i = json.fieldNames(); i.hasNext();) {
      String p = i.next(); // add non-reserved as props
      if (!MESSAGE_RESERVED.contains(p))
        mProps.put(p, json.get(p));
    }

    JsonNode requestNode = json.get("request");
    if (requestNode == null || !requestNode.isArray())
      throw new SchemaParseException("No request specified: " + json);
    List<Field> fields = new ArrayList<>();
    for (JsonNode field : requestNode) {
      JsonNode fieldNameNode = field.get("name");
      if (fieldNameNode == null)
        throw new SchemaParseException("No param name: " + field);
      JsonNode fieldTypeNode = field.get("type");
      if (fieldTypeNode == null)
        throw new SchemaParseException("No param type: " + field);
      String name = fieldNameNode.textValue();
      String fieldDoc = null;
      JsonNode fieldDocNode = field.get("doc");
      if (fieldDocNode != null)
        fieldDoc = fieldDocNode.textValue();
      Field newField = new Field(name, Schema.parse(fieldTypeNode, context, namespace), fieldDoc, field.get("default"),
          true, Order.ASCENDING);
      Set<String> aliases = Schema.parseAliases(field);
      if (aliases != null) { // add aliases
        for (String alias : aliases)
          newField.addAlias(alias);
      }

      Iterator<String> i = field.fieldNames();
      while (i.hasNext()) { // add properties
        String prop = i.next();
        if (!FIELD_RESERVED.contains(prop)) // ignore reserved
          newField.addProp(prop, field.get(prop));
      }
      fields.add(newField);
    }
    Schema request = Schema.createRecord(null, null, null, false, fields);

    boolean oneWay = false;
    JsonNode oneWayNode = json.get("one-way");
    if (oneWayNode != null) {
      if (!oneWayNode.isBoolean())
        throw new SchemaParseException("one-way must be boolean: " + json);
      oneWay = oneWayNode.booleanValue();
    }

    JsonNode responseNode = json.get("response");
    if (!oneWay && responseNode == null)
      throw new SchemaParseException("No response specified: " + json);

    JsonNode decls = json.get("errors");

    if (oneWay) {
      if (decls != null)
        throw new SchemaParseException("one-way can't have errors: " + json);
      if (responseNode != null && Schema.parse(responseNode, context, namespace).getType() != Schema.Type.NULL)
        throw new SchemaParseException("One way response must be null: " + json);
      return new Message(messageName, doc, mProps, request);
    }

    Schema response = Schema.parse(responseNode, context, namespace);

    List<Schema> errs = new ArrayList<>();
    errs.add(SYSTEM_ERROR); // every method can throw
    if (decls != null) {
      if (!decls.isArray())
        throw new SchemaParseException("Errors not an array: " + json);
      for (JsonNode decl : decls) {
        String name = decl.textValue();
        Schema schema = this.context.find(name, namespace);
        if (schema == null)
          throw new SchemaParseException("Undefined error: " + name);
        if (!schema.isError())
          throw new SchemaParseException("Not an error: " + name);
        errs.add(schema);
      }
    }

    return new TwoWayMessage(messageName, doc, mProps, request, response, Schema.createUnion(errs));
  }