/* */ package com.ibm.icu.text;
/* */
/* */ import com.ibm.icu.impl.ICUConfig;
/* */ import com.ibm.icu.impl.PatternProps;
/* */ import com.ibm.icu.util.Freezable;
/* */ import java.util.ArrayList;
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public final class MessagePattern
/* */ implements Cloneable, Freezable<MessagePattern>
/* */ {
/* */ public static final int ARG_NAME_NOT_NUMBER = -1;
/* */ public static final int ARG_NAME_NOT_VALID = -2;
/* */ public static final double NO_NUMERIC_VALUE = -1.23456789E8D;
/* */ private static final int MAX_PREFIX_LENGTH = 24;
/* */ private ApostropheMode aposMode;
/* */ private String msg;
/* */
/* */ public static enum ApostropheMode
/* */ {
/* 128 */ DOUBLE_OPTIONAL,
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* 138 */ DOUBLE_REQUIRED;
/* */
/* */
/* */ private ApostropheMode() {}
/* */ }
/* */
/* */
/* */ public MessagePattern()
/* */ {
/* 147 */ this.aposMode = defaultAposMode;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public MessagePattern(ApostropheMode mode)
/* */ {
/* 157 */ this.aposMode = mode;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public MessagePattern(String pattern)
/* */ {
/* 172 */ this.aposMode = defaultAposMode;
/* 173 */ parse(pattern);
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public MessagePattern parse(String pattern)
/* */ {
/* 188 */ preParse(pattern);
/* 189 */ parseMessage(0, 0, 0, ArgType.NONE);
/* 190 */ postParse();
/* 191 */ return this;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public MessagePattern parseChoiceStyle(String pattern)
/* */ {
/* 206 */ preParse(pattern);
/* 207 */ parseChoiceStyle(0, 0);
/* 208 */ postParse();
/* 209 */ return this;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public MessagePattern parsePluralStyle(String pattern)
/* */ {
/* 224 */ preParse(pattern);
/* 225 */ parsePluralOrSelectStyle(ArgType.PLURAL, 0, 0);
/* 226 */ postParse();
/* 227 */ return this;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public MessagePattern parseSelectStyle(String pattern)
/* */ {
/* 242 */ preParse(pattern);
/* 243 */ parsePluralOrSelectStyle(ArgType.SELECT, 0, 0);
/* 244 */ postParse();
/* 245 */ return this;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public void clear()
/* */ {
/* 256 */ if (isFrozen()) {
/* 257 */ throw new UnsupportedOperationException("Attempt to clear() a frozen MessagePattern instance.");
/* */ }
/* */
/* 260 */ this.msg = null;
/* 261 */ this.hasArgNames = (this.hasArgNumbers = 0);
/* 262 */ this.needsAutoQuoting = false;
/* 263 */ this.parts.clear();
/* 264 */ if (this.numericValues != null) {
/* 265 */ this.numericValues.clear();
/* */ }
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public void clearPatternAndSetApostropheMode(ApostropheMode mode)
/* */ {
/* 277 */ clear();
/* 278 */ this.aposMode = mode;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public boolean equals(Object other)
/* */ {
/* 289 */ if (this == other) {
/* 290 */ return true;
/* */ }
/* 292 */ if ((other == null) || (getClass() != other.getClass())) {
/* 293 */ return false;
/* */ }
/* 295 */ MessagePattern o = (MessagePattern)other;
/* 296 */ return (this.aposMode.equals(o.aposMode)) && (this.msg == null ? o.msg == null : this.msg.equals(o.msg)) && (this.parts.equals(o.parts));
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public int hashCode()
/* */ {
/* 310 */ return (this.aposMode.hashCode() * 37 + (this.msg != null ? this.msg.hashCode() : 0)) * 37 + this.parts.hashCode();
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */ public ApostropheMode getApostropheMode()
/* */ {
/* 319 */ return this.aposMode;
/* */ }
/* */
/* */
/* */
/* */
/* */ boolean jdkAposMode()
/* */ {
/* 327 */ return this.aposMode == ApostropheMode.DOUBLE_REQUIRED;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */ public String getPatternString()
/* */ {
/* 336 */ return this.msg;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public boolean hasNamedArguments()
/* */ {
/* 346 */ return this.hasArgNames;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public boolean hasNumberedArguments()
/* */ {
/* 356 */ return this.hasArgNumbers;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public String toString()
/* */ {
/* 366 */ return this.msg;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public static int validateArgumentName(String name)
/* */ {
/* 382 */ if (!PatternProps.isIdentifier(name)) {
/* 383 */ return -2;
/* */ }
/* 385 */ return parseArgNumber(name, 0, name.length());
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public String autoQuoteApostropheDeep()
/* */ {
/* 418 */ if (!this.needsAutoQuoting) {
/* 419 */ return this.msg;
/* */ }
/* 421 */ StringBuilder modified = null;
/* */
/* 423 */ int count = countParts();
/* 424 */ for (int i = count; i > 0;) {
/* */ Part part;
/* 426 */ if ((part = getPart(--i)).getType() == MessagePattern.Part.Type.INSERT_CHAR) {
/* 427 */ if (modified == null) {
/* 428 */ modified = new StringBuilder(this.msg.length() + 10).append(this.msg);
/* */ }
/* 430 */ modified.insert(part.index, (char)part.value);
/* */ }
/* */ }
/* 433 */ if (modified == null) {
/* 434 */ return this.msg;
/* */ }
/* 436 */ return modified.toString();
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public int countParts()
/* */ {
/* 448 */ return this.parts.size();
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public Part getPart(int i)
/* */ {
/* 460 */ return (Part)this.parts.get(i);
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public MessagePattern.Part.Type getPartType(int i)
/* */ {
/* 473 */ return ((Part)this.parts.get(i)).type;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public int getPatternIndex(int partIndex)
/* */ {
/* 486 */ return ((Part)this.parts.get(partIndex)).index;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public String getSubstring(Part part)
/* */ {
/* 498 */ int index = part.index;
/* 499 */ return this.msg.substring(index, index + part.length);
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public boolean partSubstringMatches(Part part, String s)
/* */ {
/* 511 */ return this.msg.regionMatches(part.index, s, 0, part.length);
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public double getNumericValue(Part part)
/* */ {
/* 522 */ MessagePattern.Part.Type type = part.type;
/* 523 */ if (type == MessagePattern.Part.Type.ARG_INT)
/* 524 */ return part.value;
/* 525 */ if (type == MessagePattern.Part.Type.ARG_DOUBLE) {
/* 526 */ return ((Double)this.numericValues.get(part.value)).doubleValue();
/* */ }
/* 528 */ return -1.23456789E8D;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public double getPluralOffset(int pluralStart)
/* */ {
/* 550 */ Part part = (Part)this.parts.get(pluralStart);
/* 551 */ if (part.type.hasNumericValue()) {
/* 552 */ return getNumericValue(part);
/* */ }
/* 554 */ return 0.0D;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public int getLimitPartIndex(int start)
/* */ {
/* 569 */ int limit = ((Part)this.parts.get(start)).limitPartIndex;
/* 570 */ if (limit < start) {
/* 571 */ return start;
/* */ }
/* 573 */ return limit;
/* */ }
/* */
/* */ public static final class Part {
/* */ private static final int MAX_LENGTH = 65535;
/* */ private static final int MAX_VALUE = 32767;
/* */ private final Type type;
/* */ private final int index;
/* */ private final char length;
/* */ private short value;
/* */ private int limitPartIndex;
/* */
/* */ private Part(Type t, int i, int l, int v) {
/* 586 */ this.type = t;
/* 587 */ this.index = i;
/* 588 */ this.length = ((char)l);
/* 589 */ this.value = ((short)v);
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public Type getType()
/* */ {
/* 599 */ return this.type;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public int getIndex()
/* */ {
/* 609 */ return this.index;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public int getLength()
/* */ {
/* 620 */ return this.length;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public int getLimit()
/* */ {
/* 631 */ return this.index + this.length;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public int getValue()
/* */ {
/* 642 */ return this.value;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public MessagePattern.ArgType getArgType()
/* */ {
/* 653 */ Type type = getType();
/* 654 */ if ((type == Type.ARG_START) || (type == Type.ARG_LIMIT)) {
/* 655 */ return MessagePattern.argTypes[this.value];
/* */ }
/* 657 */ return MessagePattern.ArgType.NONE;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public static enum Type
/* */ {
/* 677 */ MSG_START,
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* 687 */ MSG_LIMIT,
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* 696 */ SKIP_SYNTAX,
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* 704 */ INSERT_CHAR,
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* 713 */ REPLACE_NUMBER,
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* 721 */ ARG_START,
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* 733 */ ARG_LIMIT,
/* */
/* */
/* */
/* */
/* */
/* 739 */ ARG_NUMBER,
/* */
/* */
/* */
/* */
/* */
/* */
/* 746 */ ARG_NAME,
/* */
/* */
/* */
/* */
/* */
/* */
/* 753 */ ARG_TYPE,
/* */
/* */
/* */
/* */
/* */
/* */
/* 760 */ ARG_STYLE,
/* */
/* */
/* */
/* */
/* */
/* */
/* 767 */ ARG_SELECTOR,
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* 775 */ ARG_INT,
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* 784 */ ARG_DOUBLE;
/* */
/* */
/* */
/* */ private Type() {}
/* */
/* */
/* */
/* */ public boolean hasNumericValue()
/* */ {
/* 794 */ return (this == ARG_INT) || (this == ARG_DOUBLE);
/* */ }
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public String toString()
/* */ {
/* 805 */ String valueString = (this.type == Type.ARG_START) || (this.type == Type.ARG_LIMIT) ? getArgType().name() : Integer.toString(this.value);
/* */
/* 807 */ return this.type.name() + "(" + valueString + ")@" + this.index;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public boolean equals(Object other)
/* */ {
/* 818 */ if (this == other) {
/* 819 */ return true;
/* */ }
/* 821 */ if ((other == null) || (getClass() != other.getClass())) {
/* 822 */ return false;
/* */ }
/* 824 */ Part o = (Part)other;
/* 825 */ return (this.type.equals(o.type)) && (this.index == o.index) && (this.length == o.length) && (this.value == o.value) && (this.limitPartIndex == o.limitPartIndex);
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public int hashCode()
/* */ {
/* 840 */ return ((this.type.hashCode() * 37 + this.index) * 37 + this.length) * 37 + this.value;
/* */ }
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public static enum ArgType
/* */ {
/* 870 */ NONE,
/* */
/* */
/* */
/* */
/* */
/* */
/* 877 */ SIMPLE,
/* */
/* */
/* */
/* */
/* */
/* */
/* 884 */ CHOICE,
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* 895 */ PLURAL,
/* */
/* */
/* */
/* */
/* */
/* 901 */ SELECT;
/* */
/* */
/* */
/* */ private ArgType() {}
/* */ }
/* */
/* */
/* */
/* */ public Object clone()
/* */ {
/* 912 */ if (isFrozen()) {
/* 913 */ return this;
/* */ }
/* 915 */ return cloneAsThawed();
/* */ }
/* */
/* */
/* */
/* */
/* */ public MessagePattern cloneAsThawed()
/* */ {
/* */ MessagePattern newMsg;
/* */
/* */
/* */
/* */ try
/* */ {
/* 929 */ newMsg = (MessagePattern)super.clone();
/* */ } catch (CloneNotSupportedException e) {
/* 931 */ throw new RuntimeException(e);
/* */ }
/* 933 */ newMsg.parts = ((ArrayList)this.parts.clone());
/* 934 */ if (this.numericValues != null) {
/* 935 */ newMsg.numericValues = ((ArrayList)this.numericValues.clone());
/* */ }
/* 937 */ newMsg.frozen = false;
/* 938 */ return newMsg;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public MessagePattern freeze()
/* */ {
/* 948 */ this.frozen = true;
/* 949 */ return this;
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */ public boolean isFrozen()
/* */ {
/* 959 */ return this.frozen;
/* */ }
/* */
/* */ private void preParse(String pattern) {
/* 963 */ if (isFrozen()) {
/* 964 */ throw new UnsupportedOperationException("Attempt to parse(\"" + prefix(pattern) + "\") on frozen MessagePattern instance.");
/* */ }
/* */
/* 967 */ this.msg = pattern;
/* 968 */ this.hasArgNames = (this.hasArgNumbers = 0);
/* 969 */ this.needsAutoQuoting = false;
/* 970 */ this.parts.clear();
/* 971 */ if (this.numericValues != null) {
/* 972 */ this.numericValues.clear();
/* */ }
/* */ }
/* */
/* */
/* */ private void postParse() {}
/* */
/* */ private int parseMessage(int index, int msgStartLength, int nestingLevel, ArgType parentType)
/* */ {
/* 981 */ if (nestingLevel > 32767) {
/* 982 */ throw new IndexOutOfBoundsException();
/* */ }
/* 984 */ int msgStart = this.parts.size();
/* 985 */ addPart(MessagePattern.Part.Type.MSG_START, index, msgStartLength, nestingLevel);
/* 986 */ index += msgStartLength;
/* 987 */ label275: label448: while (index < this.msg.length()) {
/* 988 */ char c = this.msg.charAt(index++);
/* 989 */ if (c == '\'') {
/* 990 */ if (index == this.msg.length())
/* */ {
/* */
/* 993 */ addPart(MessagePattern.Part.Type.INSERT_CHAR, index, 0, 39);
/* 994 */ this.needsAutoQuoting = true;
/* */ } else {
/* 996 */ c = this.msg.charAt(index);
/* 997 */ if (c == '\'')
/* */ {
/* 999 */ addPart(MessagePattern.Part.Type.SKIP_SYNTAX, index++, 1, 0);
/* 1000 */ } else if ((this.aposMode == ApostropheMode.DOUBLE_REQUIRED) || (c == '{') || (c == '}') || ((parentType == ArgType.CHOICE) && (c == '|')) || ((parentType == ArgType.PLURAL) && (c == '#')))
/* */ {
/* */
/* */
/* */
/* */
/* */
/* 1007 */ addPart(MessagePattern.Part.Type.SKIP_SYNTAX, index - 1, 1, 0);
/* */ for (;;)
/* */ {
/* 1010 */ index = this.msg.indexOf('\'', index + 1);
/* 1011 */ if (index < 0) break label275;
/* 1012 */ if ((index + 1 >= this.msg.length()) || (this.msg.charAt(index + 1) != '\'')) {
/* */ break;
/* */ }
/* 1015 */ addPart(MessagePattern.Part.Type.SKIP_SYNTAX, ++index, 1, 0);
/* */ }
/* */
/* 1018 */ addPart(MessagePattern.Part.Type.SKIP_SYNTAX, index++, 1, 0);
/* */
/* */
/* */ break label448;
/* */
/* 1023 */ index = this.msg.length();
/* */
/* 1025 */ addPart(MessagePattern.Part.Type.INSERT_CHAR, index, 0, 39);
/* 1026 */ this.needsAutoQuoting = true;
/* */
/* */
/* */ }
/* */ else
/* */ {
/* */
/* 1033 */ addPart(MessagePattern.Part.Type.INSERT_CHAR, index, 0, 39);
/* 1034 */ this.needsAutoQuoting = true;
/* */ }
/* */ }
/* 1037 */ } else if ((parentType == ArgType.PLURAL) && (c == '#'))
/* */ {
/* */
/* 1040 */ addPart(MessagePattern.Part.Type.REPLACE_NUMBER, index - 1, 1, 0);
/* 1041 */ } else if (c == '{') {
/* 1042 */ index = parseArg(index - 1, 1, nestingLevel);
/* 1043 */ } else if (((nestingLevel > 0) && (c == '}')) || ((parentType == ArgType.CHOICE) && (c == '|')))
/* */ {
/* */
/* */
/* 1047 */ int limitLength = (parentType == ArgType.CHOICE) && (c == '}') ? 0 : 1;
/* 1048 */ addLimitPart(msgStart, MessagePattern.Part.Type.MSG_LIMIT, index - 1, limitLength, nestingLevel);
/* 1049 */ if (parentType == ArgType.CHOICE)
/* */ {
/* 1051 */ return index - 1;
/* */ }
/* */
/* 1054 */ return index;
/* */ }
/* */ }
/* */
/* 1058 */ if ((nestingLevel > 0) && (!inTopLevelChoiceMessage(nestingLevel, parentType))) {
/* 1059 */ throw new IllegalArgumentException("Unmatched '{' braces in message \"" + prefix() + "\"");
/* */ }
/* */
/* 1062 */ addLimitPart(msgStart, MessagePattern.Part.Type.MSG_LIMIT, index, 0, nestingLevel);
/* 1063 */ return index;
/* */ }
/* */
/* */ private int parseArg(int index, int argStartLength, int nestingLevel) {
/* 1067 */ int argStart = this.parts.size();
/* 1068 */ ArgType argType = ArgType.NONE;
/* 1069 */ addPart(MessagePattern.Part.Type.ARG_START, index, argStartLength, argType.ordinal());
/* 1070 */ int nameIndex = index = skipWhiteSpace(index + argStartLength);
/* 1071 */ if (index == this.msg.length()) {
/* 1072 */ throw new IllegalArgumentException("Unmatched '{' braces in message \"" + prefix() + "\"");
/* */ }
/* */
/* */
/* 1076 */ index = skipIdentifier(index);
/* 1077 */ int number = parseArgNumber(nameIndex, index);
/* 1078 */ if (number >= 0) {
/* 1079 */ int length = index - nameIndex;
/* 1080 */ if ((length > 65535) || (number > 32767)) {
/* 1081 */ throw new IndexOutOfBoundsException("Argument number too large: " + prefix(nameIndex));
/* */ }
/* */
/* 1084 */ this.hasArgNumbers = true;
/* 1085 */ addPart(MessagePattern.Part.Type.ARG_NUMBER, nameIndex, length, number);
/* 1086 */ } else if (number == -1) {
/* 1087 */ int length = index - nameIndex;
/* 1088 */ if (length > 65535) {
/* 1089 */ throw new IndexOutOfBoundsException("Argument name too long: " + prefix(nameIndex));
/* */ }
/* */
/* 1092 */ this.hasArgNames = true;
/* 1093 */ addPart(MessagePattern.Part.Type.ARG_NAME, nameIndex, length, 0);
/* */ } else {
/* 1095 */ throw new IllegalArgumentException("Bad argument syntax: " + prefix(nameIndex));
/* */ }
/* 1097 */ index = skipWhiteSpace(index);
/* 1098 */ if (index == this.msg.length()) {
/* 1099 */ throw new IllegalArgumentException("Unmatched '{' braces in message \"" + prefix() + "\"");
/* */ }
/* */
/* 1102 */ char c = this.msg.charAt(index);
/* 1103 */ if (c != '}')
/* */ {
/* 1105 */ if (c != ',') {
/* 1106 */ throw new IllegalArgumentException("Bad argument syntax: " + prefix(nameIndex));
/* */ }
/* */
/* 1109 */ int typeIndex = index = skipWhiteSpace(index + 1);
/* 1110 */ while ((index < this.msg.length()) && (isArgTypeChar(this.msg.charAt(index)))) {
/* 1111 */ index++;
/* */ }
/* 1113 */ int length = index - typeIndex;
/* 1114 */ index = skipWhiteSpace(index);
/* 1115 */ if (index == this.msg.length()) {
/* 1116 */ throw new IllegalArgumentException("Unmatched '{' braces in message \"" + prefix() + "\"");
/* */ }
/* */
/* 1119 */ if ((length == 0) || (((c = this.msg.charAt(index)) != ',') && (c != '}'))) {
/* 1120 */ throw new IllegalArgumentException("Bad argument syntax: " + prefix(nameIndex));
/* */ }
/* 1122 */ if (length > 65535) {
/* 1123 */ throw new IndexOutOfBoundsException("Argument type name too long: " + prefix(nameIndex));
/* */ }
/* */
/* 1126 */ argType = ArgType.SIMPLE;
/* 1127 */ if (length == 6)
/* */ {
/* 1129 */ if (isChoice(typeIndex)) {
/* 1130 */ argType = ArgType.CHOICE;
/* 1131 */ } else if (isPlural(typeIndex)) {
/* 1132 */ argType = ArgType.PLURAL;
/* 1133 */ } else if (isSelect(typeIndex)) {
/* 1134 */ argType = ArgType.SELECT;
/* */ }
/* */ }
/* */
/* 1138 */ ((Part)this.parts.get(argStart)).value = ((short)argType.ordinal());
/* 1139 */ if (argType == ArgType.SIMPLE) {
/* 1140 */ addPart(MessagePattern.Part.Type.ARG_TYPE, typeIndex, length, 0);
/* */ }
/* */
/* 1143 */ if (c == '}') {
/* 1144 */ if (argType != ArgType.SIMPLE) {
/* 1145 */ throw new IllegalArgumentException("No style field for complex argument: " + prefix(nameIndex));
/* */ }
/* */ }
/* */ else {
/* 1149 */ index++;
/* 1150 */ if (argType == ArgType.SIMPLE) {
/* 1151 */ index = parseSimpleStyle(index);
/* 1152 */ } else if (argType == ArgType.CHOICE) {
/* 1153 */ index = parseChoiceStyle(index, nestingLevel);
/* */ } else {
/* 1155 */ index = parsePluralOrSelectStyle(argType, index, nestingLevel);
/* */ }
/* */ }
/* */ }
/* */
/* 1160 */ addLimitPart(argStart, MessagePattern.Part.Type.ARG_LIMIT, index, 1, argType.ordinal());
/* 1161 */ return index + 1;
/* */ }
/* */
/* */ private int parseSimpleStyle(int index) {
/* 1165 */ int start = index;
/* 1166 */ int nestedBraces = 0;
/* 1167 */ while (index < this.msg.length()) {
/* 1168 */ char c = this.msg.charAt(index++);
/* 1169 */ if (c == '\'')
/* */ {
/* */
/* 1172 */ index = this.msg.indexOf('\'', index);
/* 1173 */ if (index < 0) {
/* 1174 */ throw new IllegalArgumentException("Quoted literal argument style text reaches to the end of the message: \"" + prefix(start) + "\"");
/* */ }
/* */
/* */
/* */
/* 1179 */ index++;
/* 1180 */ } else if (c == '{') {
/* 1181 */ nestedBraces++;
/* 1182 */ } else if (c == '}') {
/* 1183 */ if (nestedBraces > 0) {
/* 1184 */ nestedBraces--;
/* */ } else {
/* 1186 */ index--;int length = index - start;
/* 1187 */ if (length > 65535) {
/* 1188 */ throw new IndexOutOfBoundsException("Argument style text too long: " + prefix(start));
/* */ }
/* */
/* 1191 */ addPart(MessagePattern.Part.Type.ARG_STYLE, start, length, 0);
/* 1192 */ return index;
/* */ }
/* */ }
/* */ }
/* 1196 */ throw new IllegalArgumentException("Unmatched '{' braces in message \"" + prefix() + "\"");
/* */ }
/* */
/* */ private int parseChoiceStyle(int index, int nestingLevel)
/* */ {
/* 1201 */ int start = index;
/* 1202 */ index = skipWhiteSpace(index);
/* 1203 */ if ((index == this.msg.length()) || (this.msg.charAt(index) == '}')) {
/* 1204 */ throw new IllegalArgumentException("Missing choice argument pattern in \"" + prefix() + "\"");
/* */ }
/* */
/* */
/* */ for (;;)
/* */ {
/* 1210 */ int numberIndex = index;
/* 1211 */ index = skipDouble(index);
/* 1212 */ int length = index - numberIndex;
/* 1213 */ if (length == 0) {
/* 1214 */ throw new IllegalArgumentException("Bad choice pattern syntax: " + prefix(start));
/* */ }
/* 1216 */ if (length > 65535) {
/* 1217 */ throw new IndexOutOfBoundsException("Choice number too long: " + prefix(numberIndex));
/* */ }
/* */
/* 1220 */ parseDouble(numberIndex, index, true);
/* */
/* 1222 */ index = skipWhiteSpace(index);
/* 1223 */ if (index == this.msg.length()) {
/* 1224 */ throw new IllegalArgumentException("Bad choice pattern syntax: " + prefix(start));
/* */ }
/* 1226 */ char c = this.msg.charAt(index);
/* 1227 */ if ((c != '#') && (c != '<') && (c != '≤')) {
/* 1228 */ throw new IllegalArgumentException("Expected choice separator (#<≤) instead of '" + c + "' in choice pattern " + prefix(start));
/* */ }
/* */
/* */
/* 1232 */ addPart(MessagePattern.Part.Type.ARG_SELECTOR, index, 1, 0);
/* */
/* 1234 */ index = parseMessage(++index, 0, nestingLevel + 1, ArgType.CHOICE);
/* */
/* 1236 */ if (index == this.msg.length()) {
/* 1237 */ return index;
/* */ }
/* 1239 */ if (this.msg.charAt(index) == '}') {
/* 1240 */ if (!inMessageFormatPattern(nestingLevel)) {
/* 1241 */ throw new IllegalArgumentException("Bad choice pattern syntax: " + prefix(start));
/* */ }
/* */
/* 1244 */ return index;
/* */ }
/* 1246 */ index = skipWhiteSpace(index + 1);
/* */ }
/* */ }
/* */
/* */ private int parsePluralOrSelectStyle(ArgType argType, int index, int nestingLevel) {
/* 1251 */ int start = index;
/* 1252 */ boolean isEmpty = true;
/* 1253 */ boolean hasOther = false;
/* */
/* */
/* */ for (;;)
/* */ {
/* 1258 */ index = skipWhiteSpace(index);
/* 1259 */ boolean eos = index == this.msg.length();
/* 1260 */ if ((eos) || (this.msg.charAt(index) == '}')) {
/* 1261 */ if (eos == inMessageFormatPattern(nestingLevel)) {
/* 1262 */ throw new IllegalArgumentException("Bad " + (argType == ArgType.PLURAL ? "plural" : "select") + " pattern syntax: " + prefix(start));
/* */ }
/* */
/* */
/* */
/* 1267 */ if (!hasOther) {
/* 1268 */ throw new IllegalArgumentException("Missing 'other' keyword in " + (argType == ArgType.PLURAL ? "plural" : "select") + " pattern in \"" + prefix() + "\"");
/* */ }
/* */
/* */
/* */
/* 1273 */ return index;
/* */ }
/* 1275 */ int selectorIndex = index;
/* 1276 */ if ((argType == ArgType.PLURAL) && (this.msg.charAt(selectorIndex) == '='))
/* */ {
/* 1278 */ index = skipDouble(index + 1);
/* 1279 */ int length = index - selectorIndex;
/* 1280 */ if (length == 1) {
/* 1281 */ throw new IllegalArgumentException("Bad " + (argType == ArgType.PLURAL ? "plural" : "select") + " pattern syntax: " + prefix(start));
/* */ }
/* */
/* */
/* */
/* 1286 */ if (length > 65535) {
/* 1287 */ throw new IndexOutOfBoundsException("Argument selector too long: " + prefix(selectorIndex));
/* */ }
/* */
/* 1290 */ addPart(MessagePattern.Part.Type.ARG_SELECTOR, selectorIndex, length, 0);
/* 1291 */ parseDouble(selectorIndex + 1, index, false);
/* */ } else {
/* 1293 */ index = skipIdentifier(index);
/* 1294 */ int length = index - selectorIndex;
/* 1295 */ if (length == 0) {
/* 1296 */ throw new IllegalArgumentException("Bad " + (argType == ArgType.PLURAL ? "plural" : "select") + " pattern syntax: " + prefix(start));
/* */ }
/* */
/* */
/* */
/* */
/* 1302 */ if ((argType == ArgType.PLURAL) && (length == 6) && (index < this.msg.length()) && (this.msg.regionMatches(selectorIndex, "offset:", 0, 7)))
/* */ {
/* */
/* */
/* 1306 */ if (!isEmpty) {
/* 1307 */ throw new IllegalArgumentException("Plural argument 'offset:' (if present) must precede key-message pairs: " + prefix(start));
/* */ }
/* */
/* */
/* */
/* 1312 */ int valueIndex = skipWhiteSpace(index + 1);
/* 1313 */ index = skipDouble(valueIndex);
/* 1314 */ if (index == valueIndex) {
/* 1315 */ throw new IllegalArgumentException("Missing value for plural 'offset:' at " + prefix(start));
/* */ }
/* */
/* 1318 */ if (index - valueIndex > 65535) {
/* 1319 */ throw new IndexOutOfBoundsException("Plural offset value too long: " + prefix(valueIndex));
/* */ }
/* */
/* 1322 */ parseDouble(valueIndex, index, false);
/* 1323 */ isEmpty = false;
/* 1324 */ continue;
/* */ }
/* */
/* 1327 */ if (length > 65535) {
/* 1328 */ throw new IndexOutOfBoundsException("Argument selector too long: " + prefix(selectorIndex));
/* */ }
/* */
/* 1331 */ addPart(MessagePattern.Part.Type.ARG_SELECTOR, selectorIndex, length, 0);
/* 1332 */ if (this.msg.regionMatches(selectorIndex, "other", 0, length)) {
/* 1333 */ hasOther = true;
/* */ }
/* */ }
/* */
/* */
/* */
/* 1339 */ index = skipWhiteSpace(index);
/* 1340 */ if ((index == this.msg.length()) || (this.msg.charAt(index) != '{')) {
/* 1341 */ throw new IllegalArgumentException("No message fragment after " + (argType == ArgType.PLURAL ? "plural" : "select") + " selector: " + prefix(selectorIndex));
/* */ }
/* */
/* */
/* */
/* 1346 */ index = parseMessage(index, 1, nestingLevel + 1, argType);
/* 1347 */ isEmpty = false;
/* */ }
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ private static int parseArgNumber(CharSequence s, int start, int limit)
/* */ {
/* 1363 */ if (start >= limit) {
/* 1364 */ return -2;
/* */ }
/* */
/* */
/* */
/* 1369 */ char c = s.charAt(start++);
/* 1370 */ boolean badNumber; if (c == '0') {
/* 1371 */ if (start == limit) {
/* 1372 */ return 0;
/* */ }
/* 1374 */ int number = 0;
/* 1375 */ badNumber = true;
/* */ } else { boolean badNumber;
/* 1377 */ if (('1' <= c) && (c <= '9')) {
/* 1378 */ int number = c - '0';
/* 1379 */ badNumber = false;
/* */ } else {
/* 1381 */ return -1; } }
/* */ boolean badNumber;
/* 1383 */ int number; while (start < limit) {
/* 1384 */ c = s.charAt(start++);
/* 1385 */ if (('0' <= c) && (c <= '9')) {
/* 1386 */ if (number >= 214748364) {
/* 1387 */ badNumber = true;
/* */ }
/* 1389 */ number = number * 10 + (c - '0');
/* */ } else {
/* 1391 */ return -1;
/* */ }
/* */ }
/* */
/* 1395 */ if (badNumber) {
/* 1396 */ return -2;
/* */ }
/* 1398 */ return number;
/* */ }
/* */
/* */ private int parseArgNumber(int start, int limit)
/* */ {
/* 1403 */ return parseArgNumber(this.msg, start, limit);
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */ private void parseDouble(int start, int limit, boolean allowInfinity)
/* */ {
/* 1413 */ assert (start < limit);
/* */
/* */
/* */
/* 1417 */ int value = 0;
/* 1418 */ int isNegative = 0;
/* 1419 */ int index = start;
/* 1420 */ char c = this.msg.charAt(index++);
/* 1421 */ if (c == '-') {
/* 1422 */ isNegative = 1;
/* 1423 */ if (index == limit) {
/* */ break label263;
/* */ }
/* 1426 */ c = this.msg.charAt(index++);
/* 1427 */ } else if (c == '+') {
/* 1428 */ if (index == limit) {
/* */ break label263;
/* */ }
/* 1431 */ c = this.msg.charAt(index++);
/* */ }
/* 1433 */ if (c == '∞') {
/* 1434 */ if ((allowInfinity) && (index == limit)) {
/* 1435 */ addArgDoublePart(isNegative != 0 ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY, start, limit - start);
/* */
/* */ }
/* */
/* */
/* */ }
/* */ else
/* */ {
/* */
/* 1444 */ while (('0' <= c) && (c <= '9')) {
/* 1445 */ value = value * 10 + (c - '0');
/* 1446 */ if (value > 32767 + isNegative) {
/* */ break;
/* */ }
/* 1449 */ if (index == limit) {
/* 1450 */ addPart(MessagePattern.Part.Type.ARG_INT, start, limit - start, isNegative != 0 ? -value : value);
/* 1451 */ return;
/* */ }
/* 1453 */ c = this.msg.charAt(index++);
/* */ }
/* */
/* 1456 */ double numericValue = Double.parseDouble(this.msg.substring(start, limit));
/* 1457 */ addArgDoublePart(numericValue, start, limit - start);
/* 1458 */ return; }
/* */ label263:
/* 1460 */ throw new NumberFormatException("Bad syntax for numeric value: " + this.msg.substring(start, limit));
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ static void appendReducedApostrophes(String s, int start, int limit, StringBuilder sb)
/* */ {
/* 1471 */ int doubleApos = -1;
/* */ for (;;) {
/* 1473 */ int i = s.indexOf('\'', start);
/* 1474 */ if ((i < 0) || (i >= limit)) {
/* 1475 */ sb.append(s, start, limit);
/* 1476 */ break;
/* */ }
/* 1478 */ if (i == doubleApos)
/* */ {
/* 1480 */ sb.append('\'');
/* 1481 */ start++;
/* 1482 */ doubleApos = -1;
/* */ }
/* */ else {
/* 1485 */ sb.append(s, start, i);
/* 1486 */ doubleApos = start = i + 1;
/* */ }
/* */ }
/* */ }
/* */
/* */ private int skipWhiteSpace(int index) {
/* 1492 */ return PatternProps.skipWhiteSpace(this.msg, index);
/* */ }
/* */
/* */ private int skipIdentifier(int index) {
/* 1496 */ return PatternProps.skipIdentifier(this.msg, index);
/* */ }
/* */
/* */
/* */
/* */
/* */ private int skipDouble(int index)
/* */ {
/* 1504 */ while (index < this.msg.length()) {
/* 1505 */ char c = this.msg.charAt(index);
/* */
/* 1507 */ if (((c < '0') && ("+-.".indexOf(c) < 0)) || ((c > '9') && (c != 'e') && (c != 'E') && (c != '∞'))) {
/* */ break;
/* */ }
/* 1510 */ index++;
/* */ }
/* 1512 */ return index;
/* */ }
/* */
/* */ private static boolean isArgTypeChar(int c) {
/* 1516 */ return ((97 <= c) && (c <= 122)) || ((65 <= c) && (c <= 90));
/* */ }
/* */
/* */ private boolean isChoice(int index) {
/* */ char c;
/* 1521 */ return (((c = this.msg.charAt(index++)) == 'c') || (c == 'C')) && (((c = this.msg.charAt(index++)) == 'h') || (c == 'H')) && (((c = this.msg.charAt(index++)) == 'o') || (c == 'O')) && (((c = this.msg.charAt(index++)) == 'i') || (c == 'I')) && (((c = this.msg.charAt(index++)) == 'c') || (c == 'C')) && (((c = this.msg.charAt(index)) == 'e') || (c == 'E'));
/* */ }
/* */
/* */
/* */
/* */
/* */ private boolean isPlural(int index)
/* */ {
/* */ char c;
/* */
/* */
/* 1532 */ return (((c = this.msg.charAt(index++)) == 'p') || (c == 'P')) && (((c = this.msg.charAt(index++)) == 'l') || (c == 'L')) && (((c = this.msg.charAt(index++)) == 'u') || (c == 'U')) && (((c = this.msg.charAt(index++)) == 'r') || (c == 'R')) && (((c = this.msg.charAt(index++)) == 'a') || (c == 'A')) && (((c = this.msg.charAt(index)) == 'l') || (c == 'L'));
/* */ }
/* */
/* */
/* */
/* */
/* */ private boolean isSelect(int index)
/* */ {
/* */ char c;
/* */
/* */
/* 1543 */ return (((c = this.msg.charAt(index++)) == 's') || (c == 'S')) && (((c = this.msg.charAt(index++)) == 'e') || (c == 'E')) && (((c = this.msg.charAt(index++)) == 'l') || (c == 'L')) && (((c = this.msg.charAt(index++)) == 'e') || (c == 'E')) && (((c = this.msg.charAt(index++)) == 'c') || (c == 'C')) && (((c = this.msg.charAt(index)) == 't') || (c == 'T'));
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ private boolean inMessageFormatPattern(int nestingLevel)
/* */ {
/* 1557 */ return (nestingLevel > 0) || (((Part)this.parts.get(0)).type == MessagePattern.Part.Type.MSG_START);
/* */ }
/* */
/* */
/* */
/* */
/* */ private boolean inTopLevelChoiceMessage(int nestingLevel, ArgType parentType)
/* */ {
/* 1565 */ return (nestingLevel == 1) && (parentType == ArgType.CHOICE) && (((Part)this.parts.get(0)).type != MessagePattern.Part.Type.MSG_START);
/* */ }
/* */
/* */
/* */
/* */ private void addPart(MessagePattern.Part.Type type, int index, int length, int value)
/* */ {
/* 1572 */ this.parts.add(new Part(type, index, length, value, null));
/* */ }
/* */
/* */ private void addLimitPart(int start, MessagePattern.Part.Type type, int index, int length, int value) {
/* 1576 */ ((Part)this.parts.get(start)).limitPartIndex = this.parts.size();
/* 1577 */ addPart(type, index, length, value);
/* */ }
/* */
/* */ private void addArgDoublePart(double numericValue, int start, int length) { int numericIndex;
/* */ int numericIndex;
/* 1582 */ if (this.numericValues == null) {
/* 1583 */ this.numericValues = new ArrayList();
/* 1584 */ numericIndex = 0;
/* */ } else {
/* 1586 */ numericIndex = this.numericValues.size();
/* 1587 */ if (numericIndex > 32767) {
/* 1588 */ throw new IndexOutOfBoundsException("Too many numeric values");
/* */ }
/* */ }
/* 1591 */ this.numericValues.add(Double.valueOf(numericValue));
/* 1592 */ addPart(MessagePattern.Part.Type.ARG_DOUBLE, start, length, numericIndex);
/* */ }
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */
/* */ private static String prefix(String s, int start)
/* */ {
/* 1604 */ int substringLength = s.length() - start;
/* 1605 */ if (substringLength <= 24) {
/* 1606 */ return start == 0 ? s : s.substring(start);
/* */ }
/* 1608 */ StringBuilder prefix = new StringBuilder(24);
/* 1609 */ prefix.append(s, start, start + 24 - 4);
/* 1610 */ if (Character.isHighSurrogate(prefix.charAt(19)))
/* */ {
/* 1612 */ prefix.setLength(19);
/* */ }
/* 1614 */ return " ...";
/* */ }
/* */
/* */ private static String prefix(String s)
/* */ {
/* 1619 */ return prefix(s, 0);
/* */ }
/* */
/* */ private String prefix(int start) {
/* 1623 */ return prefix(this.msg, start);
/* */ }
/* */
/* */ private String prefix() {
/* 1627 */ return prefix(this.msg, 0);
/* */ }
/* */
/* */
/* */
/* 1632 */ private ArrayList<Part> parts = new ArrayList();
/* */
/* */ private ArrayList<Double> numericValues;
/* */ private boolean hasArgNames;
/* */ private boolean hasArgNumbers;
/* */ private boolean needsAutoQuoting;
/* */ private boolean frozen;
/* 1639 */ private static final ApostropheMode defaultAposMode = ApostropheMode.valueOf(ICUConfig.get("com.ibm.icu.text.MessagePattern.ApostropheMode", "DOUBLE_OPTIONAL"));
/* */
/* */
/* */
/* 1643 */ private static final ArgType[] argTypes = ArgType.values();
/* */ }
/* Location: C:\Users\Ethan\Desktop\FontZip\FontTool\sfnttool.jar!\com\ibm\icu\text\MessagePattern.class
* Java compiler version: 5 (49.0)
* JD-Core Version: 0.7.1
*/