String (@NotNull String text, @Nullable BiConsumer<? super Integer, ? super Integer> illegalEscapeConsumer) { // JLS 3.3 if (!text.contains("\\u")) return text; StringBuilder result = new StringBuilder(); boolean escape = false; for (int i = 0, length = text.length(); i < length; i++) { char c = text.charAt(i); if (c == '\\') { if (escape) result.append("\\\\"); escape = !escape; } else { if (!escape) { result.append(c); } else if (c != 'u') { result.append('\\').append(c); escape = false; } else { int startOfUnicodeEscape = i - 1; do { i++; if (i == length) { if (illegalEscapeConsumer != null) illegalEscapeConsumer.accept(startOfUnicodeEscape, i); return result.toString(); } c = text.charAt(i); } while (c == 'u'); int value = 0; for (int j = 0; j < 4; j++) { if (i + j >= length) { if (illegalEscapeConsumer != null) illegalEscapeConsumer.accept(startOfUnicodeEscape, i + j); return result.toString(); } value <<= 4; c = text.charAt(i + j); if ('0' <= c && c <= '9') value += c - '0'; else if ('a' <= c && c <= 'f') value += (c - 'a') + 10; else if ('A' <= c && c <= 'F') value += (c - 'A') + 10; else { if (illegalEscapeConsumer != null) illegalEscapeConsumer.accept(startOfUnicodeEscape, i + j); value = -1; break; } } if (value != -1) { i += 3; result.appendCodePoint(value); } escape = false; } } } return result.toString(); }