function fits(
  next,
  restCommands,
  width,
  hasLineSuffix,
  groupModeMap,
  mustBeFlat,
) {
  if (width === Number.POSITIVE_INFINITY) {
    return true;
  }

  let restIdx = restCommands.length;
  /** @type {Array<Omit<Command, 'ind'>>} */
  const cmds = [next];
  // `out` is only used for width counting because `trim` requires to look
  // backwards for space characters.
  const out = [];
  while (width >= 0) {
    if (cmds.length === 0) {
      if (restIdx === 0) {
        return true;
      }
      cmds.push(restCommands[--restIdx]);

      continue;
    }

    const { mode, doc } = cmds.pop();
    const docType = getDocType(doc);
    switch (docType) {
      case DOC_TYPE_STRING:
        out.push(doc);
        width -= getStringWidth(doc);
        break;

      case DOC_TYPE_ARRAY:
      case DOC_TYPE_FILL: {
        const parts = docType === DOC_TYPE_ARRAY ? doc : doc.parts;
        const end = doc[DOC_FILL_PRINTED_LENGTH] ?? 0;
        for (let i = parts.length - 1; i >= end; i--) {
          cmds.push({ mode, doc: parts[i] });
        }
        break;
      }

      case DOC_TYPE_INDENT:
      case DOC_TYPE_ALIGN:
      case DOC_TYPE_INDENT_IF_BREAK:
      case DOC_TYPE_LABEL:
        cmds.push({ mode, doc: doc.contents });
        break;

      case DOC_TYPE_TRIM:
        width += trim(out);
        break;

      case DOC_TYPE_GROUP: {
        if (mustBeFlat && doc.break) {
          return false;
        }
        const groupMode = doc.break ? MODE_BREAK : mode;
        // The most expanded state takes up the least space on the current line.
        const contents =
          doc.expandedStates && groupMode === MODE_BREAK
            ? doc.expandedStates.at(-1)
            : doc.contents;
        cmds.push({ mode: groupMode, doc: contents });
        break;
      }

      case DOC_TYPE_IF_BREAK: {
        const groupMode = doc.groupId
          ? groupModeMap[doc.groupId] || MODE_FLAT
          : mode;
        const contents =
          groupMode === MODE_BREAK ? doc.breakContents : doc.flatContents;
        if (contents) {
          cmds.push({ mode, doc: contents });
        }
        break;
      }

      case DOC_TYPE_LINE:
        if (mode === MODE_BREAK || doc.hard) {
          return true;
        }
        if (!doc.soft) {
          out.push(" ");
          width--;
        }
        break;

      case DOC_TYPE_LINE_SUFFIX:
        hasLineSuffix = true;
        break;

      case DOC_TYPE_LINE_SUFFIX_BOUNDARY:
        if (hasLineSuffix) {
          return false;
        }
        break;
    }
  }
  return false;
}
@param {Command} next
@param {Command[]} restCommands
@param {number} width
@param {boolean} hasLineSuffix
@param {GroupModeMap} groupModeMap
@param {boolean} [mustBeFlat]
@returns {boolean}