public static String generateUniformRange(String fromStr, String toStr) {
        var content = new StringBuilder();
        int samePrefixIndex = 0;

        while (samePrefixIndex < fromStr.length() && fromStr.charAt(samePrefixIndex) == toStr.charAt(samePrefixIndex)) {
            samePrefixIndex += 1;
        }

        var samePrefix = fromStr.substring(0, samePrefixIndex);

        if (samePrefix.length() == 1) {
            content.append("[").append(samePrefix).append("]");
        } else if (samePrefix.length() > 1) {
            content.append("\"").append(samePrefix).append("\"");
        }

        if (samePrefixIndex < fromStr.length()) {
            if (samePrefixIndex > 0) {
                content.append(" ");
            }

            var subLen = fromStr.length() - samePrefixIndex - 1;

            if (subLen > 0) {
                var fromSub = fromStr.substring(samePrefixIndex + 1);
                var toSub = toStr.substring(samePrefixIndex + 1);
                var subZeros = "0".repeat(subLen);
                var subNines = "9".repeat(subLen);

                var toReached = false;
                content.append("(");

                if (fromSub.equals(subZeros)) {
                    content.append(generateDigitRange(fromStr.charAt(samePrefixIndex), (char) (toStr.charAt(samePrefixIndex) - 1)))
                            .append(" ")
                            .append(generateMoreDigits(subLen, subLen));
                } else {
                    content.append("[")
                            .append(fromStr.charAt(samePrefixIndex))
                            .append("] ")
                            .append("(")
                            .append(generateUniformRange(fromSub, subNines))
                            .append(")");

                    if (fromStr.charAt(samePrefixIndex) < toStr.charAt(samePrefixIndex) - 1) {
                        content.append(" | ");
                        if (toSub.equals(subNines)) {
                            content.append(generateDigitRange((char) (fromStr.charAt(samePrefixIndex) + 1), toStr.charAt(samePrefixIndex)));
                            toReached = true;
                        } else {
                            content.append(generateDigitRange((char) (fromStr.charAt(samePrefixIndex) + 1), (char) (toStr.charAt(samePrefixIndex) - 1)));
                        }
                        content.append(" ");
                        content.append(generateMoreDigits(subLen, subLen));
                    }
                }

                if (!toReached) {
                    content.append(" | ")
                            .append(generateDigitRange(toStr.charAt(samePrefixIndex), toStr.charAt(samePrefixIndex)))
                            .append(" ")
                            .append(generateUniformRange(subZeros, toSub));
                }

                content.append(")");
            } else {
                content.append("[")
                        .append(fromStr.charAt(samePrefixIndex))
                        .append("-")
                        .append(toStr.charAt(samePrefixIndex))
                        .append("]");
            }
        }

        return content.toString();
    }
Converts a JSON Schema to a GBNF grammar to be used for structured output with llama.cpp.
It is a port of Python implementation from llama.cpp repository.
Current implementation doesn't support regex patterns, resolving $ref or fetching schemas from URLs.
The plan is to replace this with C++ implementation from llama.cpp though JNI.
model-integration/src/main/java/ai/vespa/llm/clients/JsonSchemaToGrammar.java