List<MessageFormatError> (@NotNull List<MessageFormatError> errors, @NotNull String fullPattern, @NotNull String string, int start) { if (errors.isEmpty()) { return errors; } TreeMap<Integer, Integer> stringTranslation = new TreeMap<>(); stringTranslation.put(0, 0); TreeMap<Integer, Pair<Integer, Integer>> fullPatternTranslation = new TreeMap<>(); int indexWithoutQuotes = 0; for (int i = 0; i < string.length(); i++) { if (string.charAt(i) != '\'') { if (i - 1 >= 0 && string.charAt(i - 1) == '\'') { stringTranslation.put(i, indexWithoutQuotes); } indexWithoutQuotes++; } else { if (i - 1 < 0 || string.charAt(i - 1) != '\'') { stringTranslation.put(i, indexWithoutQuotes); } } } stringTranslation.put(string.length(), indexWithoutQuotes + 1); indexWithoutQuotes = 0; fullPatternTranslation.put(0, Pair.pair(start, start)); for (int i = start; i < fullPattern.length(); i++) { if (fullPattern.charAt(i) != '\'') { indexWithoutQuotes++; } else if (i - 1 < 0 || fullPattern.charAt(i - 1) != '\'') { int to = i; while (to < fullPattern.length() && fullPattern.charAt(to) == '\'') { to++; } fullPatternTranslation.put(indexWithoutQuotes, Pair.pair(i, to)); } } if (!fullPatternTranslation.containsKey(indexWithoutQuotes)) { fullPatternTranslation.put(indexWithoutQuotes + 1, Pair.pair(fullPattern.length(), fullPattern.length())); } List<MessageFormatError> rearrangedErrors = new ArrayList<>(); for (MessageFormatError error : errors) { Integer fromIndex = error.fromIndex(); Integer toIndex = error.toIndex(); Integer floorFromIndex = stringTranslation.floorKey(fromIndex); Integer ceilToIndex = stringTranslation.ceilingKey(toIndex); if (floorFromIndex == null || ceilToIndex == null) continue; Integer convertedShiftedIndex = stringTranslation.get(floorFromIndex); fromIndex = convertedShiftedIndex + (fromIndex - floorFromIndex); convertedShiftedIndex = stringTranslation.get(ceilToIndex); toIndex = convertedShiftedIndex + (toIndex - ceilToIndex); //quotes if (toIndex.equals(fromIndex)) { Pair<Integer, Integer> pair = fullPatternTranslation.get(fromIndex); if (pair == null) continue; rearrangedErrors.add(new MessageFormatError(error.errorType(), pair.first, pair.second)); } else { floorFromIndex = fullPatternTranslation.floorKey(fromIndex); ceilToIndex = fullPatternTranslation.ceilingKey(toIndex); if (floorFromIndex == null || ceilToIndex == null) { continue; } Pair<Integer, Integer> shifterPair = fullPatternTranslation.get(floorFromIndex); fromIndex = shifterPair.second + (fromIndex - floorFromIndex); shifterPair = fullPatternTranslation.get(ceilToIndex); toIndex = shifterPair.first + (toIndex - ceilToIndex); rearrangedErrors.add(new MessageFormatError(error.errorType(), fromIndex, toIndex)); } } return rearrangedErrors; }