code: private void extractFromFunctionNode(Builder builder, Node node)
        throws MalformedException {
      Set<String> phNames = new HashSet<>();
  
      for (Node fnChild : node.children()) {
        switch (fnChild.getToken()) {
          case NAME:
            // This is okay. The function has a name, but it is empty.
            break;
          case PARAM_LIST:
            // Parse the placeholder names from the function argument list.
            for (Node argumentNode : fnChild.children()) {
              if (argumentNode.isName()) {
                String phName = argumentNode.getString();
                if (phNames.contains(phName)) {
                  throw new MalformedException("Duplicate placeholder name: "
                      + phName, argumentNode);
                } else {
                  phNames.add(phName);
                }
              }
            }
            break;
          case BLOCK:
            // Build the message's value by examining the return statement
            Node returnNode = fnChild.getFirstChild();
            if (!returnNode.isReturn()) {
              throw new MalformedException(
                  "RETURN node expected; found: " + returnNode.getToken(), returnNode);
            }
            for (Node child : returnNode.children()) {
              extractFromReturnDescendant(builder, child);
            }
  
            // Check that all placeholders from the message text have appropriate
            // object literal keys
            for (String phName : builder.getPlaceholders()) {
              if (!phNames.contains(phName)) {
                throw new MalformedException(
                    "Unrecognized message placeholder referenced: " + phName,
                    returnNode);
              }
            }
            break;
          default:
            throw new MalformedException(
                "NAME, PARAM_LIST, or BLOCK node expected; found: " + node, fnChild);
        }
      }
    }
docs: Initializes a message builder from a FUNCTION node.
  <p>
  <pre>
  The tree should look something like:
  
  function
  |-- name
  |-- lp
  |   |-- name <arg1>
  |    -- name <arg2>
  -- block
  |
  --return
  |
  --add
  |-- string foo
  -- name <arg1>
  </pre>
  
  @param builder the message builder
  @param node the function node that contains a message
  @throws MalformedException if the parsed message is invalid