docs: @Override
    protected Statement visitMsgFallbackGroupNode(MsgFallbackGroupNode node) {
      MsgNode msg = node.getMsg();
      MsgPartsAndIds idAndParts = MsgUtils.buildMsgPartsAndComputeMsgIdForDualFormat(msg);
      ImmutableList<SoyPrintDirective> escapingDirectives = node.getEscapingDirectives();
      Statement renderDefault = getMsgCompiler().compileMessage(idAndParts, msg, escapingDirectives);
      // fallback groups have 1 or 2 children.  if there are 2 then the second is a fallback and we
      // need to check for presence.
      if (node.hasFallbackMsg()) {
        MsgNode fallback = node.getFallbackMsg();
        MsgPartsAndIds fallbackIdAndParts =
            MsgUtils.buildMsgPartsAndComputeMsgIdForDualFormat(fallback);
        // TODO(lukes): consider changing the control flow here by 'inlining' the usePrimaryMsg logic
        // it would save some lookups.  Right now we will do to 2- 3 calls to
        // SoyMsgBundle.getMsgParts (each of which requires a binary search).  We could reduce that
        // to 1-2 in the worse case by inlining and storing the lists in local variables.
        IfBlock ifAvailableRenderDefault =
            IfBlock.create(
                parameterLookup
                    .getRenderContext()
                    .usePrimaryMsg(idAndParts.id, fallbackIdAndParts.id),
                renderDefault);
        return ControlFlow.ifElseChain(
            ImmutableList.of(ifAvailableRenderDefault),
            Optional.of(
                getMsgCompiler().compileMessage(fallbackIdAndParts, fallback, escapingDirectives)));
      } else {
        return renderDefault;
      }
    }