private String printNode(PatternToken node, int depth) {
        StringBuilder sb = new StringBuilder();

        sb.append("  ".repeat(Math.max(0, depth)));

        sb.append(node.toString()).append("\n");

        // Append expression if not null
        if (node.expression() != null) {
            sb.append("  ").append(node.expression()).append("\n");
        }

        if (node instanceof StringToken) {
            StringToken stringToken = (StringToken) node;
            for (PatternToken child : stringToken.children()) {
                sb.append(printNode(child, depth + 1));
            }
        } else if (node instanceof VarToken) {
            VarToken varToken = (VarToken) node;
            for (PatternToken child : varToken.children()) {
                sb.append(printNode(child, depth + 1));
            }
        }

        return sb.toString();
    }
The pattern is split by /, and each token is a node in the tree. Each node either a literal string or "{var}"
representing a variable.

@param pattern of URIs
oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/config/group/uri/quickmatch/PatternTree.java