code: private Node replaceCallNode(JsMessage message, Node callNode)
        throws MalformedException {
      checkNode(callNode, Token.CALL);
      Node getPropNode = callNode.getFirstChild();
      checkNode(getPropNode, Token.GETPROP);
      Node stringExprNode = getPropNode.getNext();
      checkStringExprNode(stringExprNode);
      Node objLitNode = stringExprNode.getNext();
  
      // Build the replacement tree.
      Iterator<CharSequence> iterator = message.parts().iterator();
      return iterator.hasNext()
          ? constructStringExprNode(iterator, objLitNode, callNode)
          : IR.string("");
    }
docs: Replaces a CALL node with an inlined message value.
  <p>
  The call tree looks something like:
  <pre>
  call
  |-- getprop
  |   |-- name 'goog'
  |   +-- string 'getMsg'
  |
  |-- string 'Hi {$userName}! Welcome to {$product}.'
  +-- objlit
  |-- string 'userName'
  |-- name 'someUserName'
  |-- string 'product'
  +-- call
  +-- name 'getProductName'
  <pre>
  <p>
  For that example, we'd return:
  <pre>
  add
  |-- string 'Hi '
  +-- add
  |-- name someUserName
  +-- add
  |-- string '! Welcome to '
  +-- add
  |-- call
  |   +-- name 'getProductName'
  +-- string '.'
  </pre>
  @param message  a message
  @param callNode  the message's original CALL value node
  @return a STRING node, or an ADD node that does string concatenation, if
  the message has one or more placeholders
  
  @throws MalformedException if the passed node's subtree structure is
  not as expected