boolean (@NotNull Nls.Capitalization capitalization) { if (capitalization == Nls.Capitalization.NotSpecified) return true; int parts = myPattern.countParts(); int maxMsgCount = IntStreamEx.range(parts).map(this::getMessagesForPart).append(1).max().orElse(1); String string = myPattern.getPatternString(); // The idea is to replace ordinary parameters with _ (which is not reported in any case) // and choice/plural with one of the possible options in a loop till maximal option number is reached. // If all the artificial strings satisfy the capitalization, we assume that it's satisfied for the pattern as well. for (int curIndex = 0; curIndex < maxMsgCount; curIndex++) { StringBuilder sample = new StringBuilder(); int msgIndex = 0; int nestingLevel = 0; int curMsgCount = 0; boolean inMsg = false; for (int i = 1; i < parts; i++) { MessagePattern.Part part = myPattern.getPart(i); boolean shouldCopyPart = nestingLevel == 0 || inMsg && msgIndex == curIndex % curMsgCount + 1; if (shouldCopyPart) { sample.append(string, myPattern.getPart(i - 1).getLimit(), myPattern.getPatternIndex(i)); } if (part.getType() == MessagePattern.Part.Type.ARG_START) { nestingLevel++; MessagePattern.ArgType argType = part.getArgType(); if ((argType == MessagePattern.ArgType.SIMPLE || argType == MessagePattern.ArgType.NONE) && shouldCopyPart) { sample.append("_"); } msgIndex = 0; curMsgCount = Math.max(1, getMessagesForPart(i)); } else if (part.getType() == MessagePattern.Part.Type.MSG_START) { msgIndex++; inMsg = true; } else if (part.getType() == MessagePattern.Part.Type.MSG_LIMIT) { inMsg = false; } else if (part.getType() == MessagePattern.Part.Type.ARG_LIMIT) { nestingLevel--; } } if (!NlsCapitalizationUtil.isCapitalizationSatisfied(sample.toString(), capitalization)) return false; } return true; }