- * A MessageFormat produces concatenated messages in a
- * language-neutral way. It should be used for all string
- * concatenations that are visible to end users.
- * <P>
- * A MessageFormat contains an array of <EM>subformats</EM> arranged
- * within a <EM>template string</EM>. Together, the subformats and
- * template string determine how the MessageFormat will operate during
- * formatting and parsing.
- * <P>
- * Typically, both the subformats and the template string are
- * specified at once in a <EM>pattern</EM>. By using different
- * patterns for different locales, messages may be localized.
- * <P>
- * During formatting, the MessageFormat takes an array of arguments
- * and produces a user-readable string. Each argument is a
- * Formattable object; they may be passed in in an array, or as a
- * single Formattable object which itself contains an array. Each
- * argument is matched up with its corresponding subformat, which then
- * formats it into a string. The resultant strings are then assembled
- * within the string template of the MessageFormat to produce the
- * final output string.
- * <p>
- * <strong>Note:</strong>
- * In ICU 4.0 MessageFormat supports named arguments. If a named argument
- * is used, all arguments must be named. Names start with a character in
- * <code>UCHAR_ID_START</code> and continue with characters in
- * <code>UCHARID_CONTINUE</code>, in particular they do not start with a digit.
- * If named arguments are used, {@link #usesNamedArguments()} will return true.
- * <p>
- * The other new methods supporting named arguments are
- * {@link #getFormatNames(UErrorCode& status)},
- * {@link #getFormat(const UnicodeString& formatName, UErrorCode& status)}
- * {@link #setFormat(const UnicodeString& formatName, const Format& format, UErrorCode& status)},
- * {@link #adoptFormat(const UnicodeString& formatName, Format* formatToAdopt, UErrorCode& status)},
- * {@link #format(const Formattable* arguments, const UnicodeString *argumentNames, int32_t cnt, UnicodeString& appendTo, FieldPosition& status, int32_t recursionProtection, UErrorCode& success)},
- * {@link #format(const UnicodeString* argumentNames, const Formattable* arguments, int32_t count, UnicodeString& appendTo,UErrorCode& status)}.
- * These methods are all compatible with patterns that do not used named arguments--
- * in these cases the keys in the input or output use <code>UnicodeString</code>s
- * that name the argument indices, e.g. "0", "1", "2"... etc.
- * <p>
- * When named arguments are used, certain methods on MessageFormat that take or
- * return arrays do not perform any action, since it is not possible to
- * identify positions in an array using a name. UErrorCode is set to
- * U_ARGUMENT_TYPE_MISMATCH if there is a status/success field in the method.
- * These methods are
- * {@link #adoptFormats(Format** newFormats, int32_t count)},
- * {@link #setFormats(const Format** newFormats,int32_t count)},
- * {@link #adoptFormat(int32_t n, Format *newFormat)},
- * {@link #getFormats(int32_t& cnt)},
- * {@link #format(const Formattable* source,int32_t cnt,UnicodeString& appendTo, FieldPosition& ignore, UErrorCode& success)},
- * {@link #format(const UnicodeString& pattern,const Formattable* arguments,int32_t cnt,UnicodeString& appendTo,UErrorCode& success)},
- * {@link #format(const Formattable& source, UnicodeString& appendTo,FieldPosition& ignore, UErrorCode& success)},
- * {@link #format(const Formattable* arguments, int32_t cnt, UnicodeString& appendTo, FieldPosition& status, int32_t recursionProtection,UErrorCode& success)},
- * {@link #parse(const UnicodeString& source, ParsePosition& pos,int32_t& count)},
- * {@link #parse(const UnicodeString& source, int32_t& cnt, UErrorCode& status)}
+ * <p>A MessageFormat is constructed from a <em>pattern</em> string
+ * with arguments in {curly braces} which will be replaced by formatted values.
+ *
+ * <p><code>MessageFormat</code> differs from the other <code>Format</code>
+ * classes in that you create a <code>MessageFormat</code> object with one
+ * of its constructors (not with a <code>createInstance</code> style factory
+ * method). Factory methods aren't necessary because <code>MessageFormat</code>
+ * itself doesn't implement locale-specific behavior. Any locale-specific
+ * behavior is defined by the pattern that you provide and the
+ * subformats used for inserted arguments.
+ *
+ * <p>Arguments can be named (using identifiers) or numbered (using small ASCII-digit integers).
+ * Some of the API methods work only with argument numbers and throw an exception
+ * if the pattern has named arguments (see {@link #usesNamedArguments()}).
+ *
+ * <p>An argument might not specify any format type. In this case,
+ * a numeric value is formatted with a default (for the locale) NumberFormat,
+ * and a date/time value is formatted with a default (for the locale) DateFormat.
+ *
+ * <p>An argument might specify a "simple" type for which the specified
+ * Format object is created, cached and used.
+ *
+ * <p>An argument might have a "complex" type with nested MessageFormat sub-patterns.
+ * During formatting, one of these sub-messages is selected according to the argument value
+ * and recursively formatted.
+ *
+ * <p>After construction, a custom Format object can be set for
+ * a top-level argument, overriding the default formatting and parsing behavior
+ * for that argument.
+ * However, custom formatting can be achieved more simply by writing
+ * a typeless argument in the pattern string
+ * and supplying it with a preformatted string value.
+ *
+ * <p>When formatting, MessageFormat takes a collection of argument values
+ * and writes an output string.
+ * The argument values may be passed as an array
+ * (when the pattern contains only numbered arguments)
+ * or as an array of names and and an array of arguments (which works for both named
+ * and numbered arguments).
+ *
+ * <p>Each argument is matched with one of the input values by array index or argument name
+ * and formatted according to its pattern specification
+ * (or using a custom Format object if one was set).
+ * A numbered pattern argument is matched with an argument name that contains that number
+ * as an ASCII-decimal-digit string (without leading zero).
+ *
+ * <h4><a name="patterns">Patterns and Their Interpretation</a></h4>
+ *
+ * <code>MessageFormat</code> uses patterns of the following form:
+ * <pre>
+ * message = messageText (argument messageText)*
+ * argument = noneArg | simpleArg | complexArg
+ * complexArg = choiceArg | pluralArg | selectArg | selectordinalArg
+ *
+ * noneArg = '{' argNameOrNumber '}'
+ * simpleArg = '{' argNameOrNumber ',' argType [',' argStyle] '}'
+ * choiceArg = '{' argNameOrNumber ',' "choice" ',' choiceStyle '}'
+ * pluralArg = '{' argNameOrNumber ',' "plural" ',' pluralStyle '}'
+ * selectArg = '{' argNameOrNumber ',' "select" ',' selectStyle '}'
+ * selectordinalArg = '{' argNameOrNumber ',' "selectordinal" ',' pluralStyle '}'
+ *
+ * choiceStyle: see {@link ChoiceFormat}
+ * pluralStyle: see {@link PluralFormat}
+ * selectStyle: see {@link SelectFormat}
+ *
+ * argNameOrNumber = argName | argNumber
+ * argName = [^[[:Pattern_Syntax:][:Pattern_White_Space:]]]+
+ * argNumber = '0' | ('1'..'9' ('0'..'9')*)
+ *
+ * argType = "number" | "date" | "time" | "spellout" | "ordinal" | "duration"
+ * argStyle = "short" | "medium" | "long" | "full" | "integer" | "currency" | "percent" | argStyleText | "::" argSkeletonText
+ * </pre>
+ *
+ * <ul>
+ * <li>messageText can contain quoted literal strings including syntax characters.
+ * A quoted literal string begins with an ASCII apostrophe and a syntax character
+ * (usually a {curly brace}) and continues until the next single apostrophe.
+ * A double ASCII apostrohpe inside or outside of a quoted string represents
+ * one literal apostrophe.
+ * <li>Quotable syntax characters are the {curly braces} in all messageText parts,
+ * plus the '#' sign in a messageText immediately inside a pluralStyle,
+ * and the '|' symbol in a messageText immediately inside a choiceStyle.
+ * <li>See also {@link #UMessagePatternApostropheMode}
+ * <li>In argStyleText, every single ASCII apostrophe begins and ends quoted literal text,
+ * and unquoted {curly braces} must occur in matched pairs.
+ * </ul>
+ *
+ * <p>Recommendation: Use the real apostrophe (single quote) character
+ * \htmlonly’\endhtmlonly (U+2019) for
+ * human-readable text, and use the ASCII apostrophe ' (U+0027)
+ * only in program syntax, like quoting in MessageFormat.
+ * See the annotations for U+0027 Apostrophe in The Unicode Standard.
+ *
+ * <p>The <code>choice</code> argument type is deprecated.
+ * Use <code>plural</code> arguments for proper plural selection,
+ * and <code>select</code> arguments for simple selection among a fixed set of choices.
+ *
+ * <p>The <code>argType</code> and <code>argStyle</code> values are used to create
+ * a <code>Format</code> instance for the format element. The following
+ * table shows how the values map to Format instances. Combinations not
+ * shown in the table are illegal. Any <code>argStyleText</code> must
+ * be a valid pattern string for the Format subclass used.
+ *
+ * <p><table border=1>
+ * <tr>
+ * <th>argType
+ * <th>argStyle
+ * <th>resulting Format object
+ * <tr>
+ * <td colspan=2><i>(none)</i>
+ * <td><code>null</code>
+ * <tr>
+ * <td rowspan=6><code>number</code>
+ * <td><i>(none)</i>
+ * <td><code>NumberFormat.createInstance(getLocale(), status)</code>
+ * <tr>
+ * <td><code>integer</code>
+ * <td><code>NumberFormat.createInstance(getLocale(), kNumberStyle, status)</code>
+ * <tr>
+ * <td><code>currency</code>
+ * <td><code>NumberFormat.createCurrencyInstance(getLocale(), status)</code>
+ * <tr>
+ * <td><code>percent</code>
+ * <td><code>NumberFormat.createPercentInstance(getLocale(), status)</code>
+ * <tr>
+ * <td><i>argStyleText</i>
+ * <td><code>new DecimalFormat(argStyleText, new DecimalFormatSymbols(getLocale(), status), status)</code>
+ * <tr>
+ * <td><i>argSkeletonText</i>
+ * <td><code>NumberFormatter::forSkeleton(argSkeletonText, status).locale(getLocale()).toFormat(status)</code>
+ * <tr>
+ * <td rowspan=6><code>date</code>
+ * <td><i>(none)</i>
+ * <td><code>DateFormat.createDateInstance(kDefault, getLocale(), status)</code>
+ * <tr>
+ * <td><code>short</code>
+ * <td><code>DateFormat.createDateInstance(kShort, getLocale(), status)</code>
+ * <tr>
+ * <td><code>medium</code>
+ * <td><code>DateFormat.createDateInstance(kDefault, getLocale(), status)</code>
+ * <tr>
+ * <td><code>long</code>
+ * <td><code>DateFormat.createDateInstance(kLong, getLocale(), status)</code>
+ * <tr>
+ * <td><code>full</code>
+ * <td><code>DateFormat.createDateInstance(kFull, getLocale(), status)</code>
+ * <tr>
+ * <td><i>argStyleText</i>
+ * <td><code>new SimpleDateFormat(argStyleText, getLocale(), status)</code>
+ * <tr>
+ * <td><i>argSkeletonText</i>
+ * <td><code>DateFormat::createInstanceForSkeleton(argSkeletonText, getLocale(), status)</code>
+ * <tr>
+ * <td rowspan=6><code>time</code>
+ * <td><i>(none)</i>
+ * <td><code>DateFormat.createTimeInstance(kDefault, getLocale(), status)</code>
+ * <tr>
+ * <td><code>short</code>
+ * <td><code>DateFormat.createTimeInstance(kShort, getLocale(), status)</code>
+ * <tr>
+ * <td><code>medium</code>
+ * <td><code>DateFormat.createTimeInstance(kDefault, getLocale(), status)</code>
+ * <tr>
+ * <td><code>long</code>
+ * <td><code>DateFormat.createTimeInstance(kLong, getLocale(), status)</code>
+ * <tr>
+ * <td><code>full</code>
+ * <td><code>DateFormat.createTimeInstance(kFull, getLocale(), status)</code>
+ * <tr>
+ * <td><i>argStyleText</i>
+ * <td><code>new SimpleDateFormat(argStyleText, getLocale(), status)</code>
+ * <tr>
+ * <td><code>spellout</code>
+ * <td><i>argStyleText (optional)</i>
+ * <td><code>new RuleBasedNumberFormat(URBNF_SPELLOUT, getLocale(), status)
+ * <br/> .setDefaultRuleset(argStyleText, status);</code>
+ * <tr>
+ * <td><code>ordinal</code>
+ * <td><i>argStyleText (optional)</i>
+ * <td><code>new RuleBasedNumberFormat(URBNF_ORDINAL, getLocale(), status)
+ * <br/> .setDefaultRuleset(argStyleText, status);</code>
+ * <tr>
+ * <td><code>duration</code>
+ * <td><i>argStyleText (optional)</i>
+ * <td><code>new RuleBasedNumberFormat(URBNF_DURATION, getLocale(), status)
+ * <br/> .setDefaultRuleset(argStyleText, status);</code>
+ * </table>