tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

msgfmt.h (46016B)


      1 // © 2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /*
      4 * Copyright (C) 2007-2013, International Business Machines Corporation and
      5 * others. All Rights Reserved.
      6 ********************************************************************************
      7 *
      8 * File MSGFMT.H
      9 *
     10 * Modification History:
     11 *
     12 *   Date        Name        Description
     13 *   02/19/97    aliu        Converted from java.
     14 *   03/20/97    helena      Finished first cut of implementation.
     15 *   07/22/98    stephen     Removed operator!= (defined in Format)
     16 *   08/19/2002  srl         Removing Javaisms
     17 *******************************************************************************/
     18 
     19 #ifndef MSGFMT_H
     20 #define MSGFMT_H
     21 
     22 #include "unicode/utypes.h"
     23 
     24 #if U_SHOW_CPLUSPLUS_API
     25 
     26 /**
     27 * \file
     28 * \brief C++ API: Formats messages in a language-neutral way.
     29 */
     30 
     31 #if !UCONFIG_NO_FORMATTING
     32 
     33 #include "unicode/format.h"
     34 #include "unicode/locid.h"
     35 #include "unicode/messagepattern.h"
     36 #include "unicode/parseerr.h"
     37 #include "unicode/plurfmt.h"
     38 #include "unicode/plurrule.h"
     39 
     40 U_CDECL_BEGIN
     41 // Forward declaration.
     42 struct UHashtable;
     43 typedef struct UHashtable UHashtable; /**< @internal */
     44 U_CDECL_END
     45 
     46 U_NAMESPACE_BEGIN
     47 
     48 class AppendableWrapper;
     49 class DateFormat;
     50 class NumberFormat;
     51 
     52 /**
     53 * <p>MessageFormat prepares strings for display to users,
     54 * with optional arguments (variables/placeholders).
     55 * The arguments can occur in any order, which is necessary for translation
     56 * into languages with different grammars.
     57 *
     58 * <p>A MessageFormat is constructed from a <em>pattern</em> string
     59 * with arguments in {curly braces} which will be replaced by formatted values.
     60 *
     61 * <p><code>MessageFormat</code> differs from the other <code>Format</code>
     62 * classes in that you create a <code>MessageFormat</code> object with one
     63 * of its constructors (not with a <code>createInstance</code> style factory
     64 * method). Factory methods aren't necessary because <code>MessageFormat</code>
     65 * itself doesn't implement locale-specific behavior. Any locale-specific
     66 * behavior is defined by the pattern that you provide and the
     67 * subformats used for inserted arguments.
     68 *
     69 * <p>Arguments can be named (using identifiers) or numbered (using small ASCII-digit integers).
     70 * Some of the API methods work only with argument numbers and throw an exception
     71 * if the pattern has named arguments (see {@link #usesNamedArguments()}).
     72 *
     73 * <p>An argument might not specify any format type. In this case,
     74 * a numeric value is formatted with a default (for the locale) NumberFormat,
     75 * and a date/time value is formatted with a default (for the locale) DateFormat.
     76 *
     77 * <p>An argument might specify a "simple" type for which the specified
     78 * Format object is created, cached and used.
     79 *
     80 * <p>An argument might have a "complex" type with nested MessageFormat sub-patterns.
     81 * During formatting, one of these sub-messages is selected according to the argument value
     82 * and recursively formatted.
     83 *
     84 * <p>After construction, a custom Format object can be set for
     85 * a top-level argument, overriding the default formatting and parsing behavior
     86 * for that argument.
     87 * However, custom formatting can be achieved more simply by writing
     88 * a typeless argument in the pattern string
     89 * and supplying it with a preformatted string value.
     90 *
     91 * <p>When formatting, MessageFormat takes a collection of argument values
     92 * and writes an output string.
     93 * The argument values may be passed as an array
     94 * (when the pattern contains only numbered arguments)
     95 * or as an array of names and and an array of arguments (which works for both named
     96 * and numbered arguments).
     97 *
     98 * <p>Each argument is matched with one of the input values by array index or argument name
     99 * and formatted according to its pattern specification
    100 * (or using a custom Format object if one was set).
    101 * A numbered pattern argument is matched with an argument name that contains that number
    102 * as an ASCII-decimal-digit string (without leading zero).
    103 *
    104 * <h4><a name="patterns">Patterns and Their Interpretation</a></h4>
    105 *
    106 * <code>MessageFormat</code> uses patterns of the following form:
    107 * <pre>
    108 * message = messageText (argument messageText)*
    109 * argument = noneArg | simpleArg | complexArg
    110 * complexArg = choiceArg | pluralArg | selectArg | selectordinalArg
    111 *
    112 * noneArg = '{' argNameOrNumber '}'
    113 * simpleArg = '{' argNameOrNumber ',' argType [',' argStyle] '}'
    114 * choiceArg = '{' argNameOrNumber ',' "choice" ',' choiceStyle '}'
    115 * pluralArg = '{' argNameOrNumber ',' "plural" ',' pluralStyle '}'
    116 * selectArg = '{' argNameOrNumber ',' "select" ',' selectStyle '}'
    117 * selectordinalArg = '{' argNameOrNumber ',' "selectordinal" ',' pluralStyle '}'
    118 *
    119 * choiceStyle: see {@link ChoiceFormat}
    120 * pluralStyle: see {@link PluralFormat}
    121 * selectStyle: see {@link SelectFormat}
    122 *
    123 * argNameOrNumber = argName | argNumber
    124 * argName = [^[[:Pattern_Syntax:][:Pattern_White_Space:]]]+
    125 * argNumber = '0' | ('1'..'9' ('0'..'9')*)
    126 *
    127 * argType = "number" | "date" | "time" | "spellout" | "ordinal" | "duration"
    128 * argStyle = "short" | "medium" | "long" | "full" | "integer" | "currency" | "percent" | argStyleText | "::" argSkeletonText
    129 * </pre>
    130 *
    131 * <ul>
    132 *   <li>messageText can contain quoted literal strings including syntax characters.
    133 *       A quoted literal string begins with an ASCII apostrophe and a syntax character
    134 *       (usually a {curly brace}) and continues until the next single apostrophe.
    135 *       A double ASCII apostrophe inside or outside of a quoted string represents
    136 *       one literal apostrophe.
    137 *   <li>Quotable syntax characters are the {curly braces} in all messageText parts,
    138 *       plus the '#' sign in a messageText immediately inside a pluralStyle,
    139 *       and the '|' symbol in a messageText immediately inside a choiceStyle.
    140 *   <li>See also {@link #UMessagePatternApostropheMode}
    141 *   <li>In argStyleText, every single ASCII apostrophe begins and ends quoted literal text,
    142 *       and unquoted {curly braces} must occur in matched pairs.
    143 * </ul>
    144 *
    145 * <p>Recommendation: Use the real apostrophe (single quote) character
    146 * \htmlonly&#x2019;\endhtmlonly (U+2019) for
    147 * human-readable text, and use the ASCII apostrophe ' (U+0027)
    148 * only in program syntax, like quoting in MessageFormat.
    149 * See the annotations for U+0027 Apostrophe in The Unicode Standard.
    150 *
    151 * <p>The <code>choice</code> argument type is deprecated.
    152 * Use <code>plural</code> arguments for proper plural selection,
    153 * and <code>select</code> arguments for simple selection among a fixed set of choices.
    154 *
    155 * <p>The <code>argType</code> and <code>argStyle</code> values are used to create
    156 * a <code>Format</code> instance for the format element. The following
    157 * table shows how the values map to Format instances. Combinations not
    158 * shown in the table are illegal. Any <code>argStyleText</code> must
    159 * be a valid pattern string for the Format subclass used.
    160 *
    161 * <p><table border=1>
    162 *    <tr>
    163 *       <th>argType
    164 *       <th>argStyle
    165 *       <th>resulting Format object
    166 *    <tr>
    167 *       <td colspan=2><i>(none)</i>
    168 *       <td><code>null</code>
    169 *    <tr>
    170 *       <td rowspan=6><code>number</code>
    171 *       <td><i>(none)</i>
    172 *       <td><code>NumberFormat.createInstance(getLocale(), status)</code>
    173 *    <tr>
    174 *       <td><code>integer</code>
    175 *       <td><code>NumberFormat.createInstance(getLocale(), kNumberStyle, status)</code>
    176 *    <tr>
    177 *       <td><code>currency</code>
    178 *       <td><code>NumberFormat.createCurrencyInstance(getLocale(), status)</code>
    179 *    <tr>
    180 *       <td><code>percent</code>
    181 *       <td><code>NumberFormat.createPercentInstance(getLocale(), status)</code>
    182 *    <tr>
    183 *       <td><i>argStyleText</i>
    184 *       <td><code>new DecimalFormat(argStyleText, new DecimalFormatSymbols(getLocale(), status), status)</code>
    185 *    <tr>
    186 *       <td><i>argSkeletonText</i>
    187 *       <td><code>NumberFormatter::forSkeleton(argSkeletonText, status).locale(getLocale()).toFormat(status)</code>
    188 *    <tr>
    189 *       <td rowspan=7><code>date</code>
    190 *       <td><i>(none)</i>
    191 *       <td><code>DateFormat.createDateInstance(kDefault, getLocale(), status)</code>
    192 *    <tr>
    193 *       <td><code>short</code>
    194 *       <td><code>DateFormat.createDateInstance(kShort, getLocale(), status)</code>
    195 *    <tr>
    196 *       <td><code>medium</code>
    197 *       <td><code>DateFormat.createDateInstance(kDefault, getLocale(), status)</code>
    198 *    <tr>
    199 *       <td><code>long</code>
    200 *       <td><code>DateFormat.createDateInstance(kLong, getLocale(), status)</code>
    201 *    <tr>
    202 *       <td><code>full</code>
    203 *       <td><code>DateFormat.createDateInstance(kFull, getLocale(), status)</code>
    204 *    <tr>
    205 *       <td><i>argStyleText</i>
    206 *       <td><code>new SimpleDateFormat(argStyleText, getLocale(), status)</code>
    207 *    <tr>
    208 *       <td><i>argSkeletonText</i>
    209 *       <td><code>DateFormat::createInstanceForSkeleton(argSkeletonText, getLocale(), status)</code>
    210 *    <tr>
    211 *       <td rowspan=6><code>time</code>
    212 *       <td><i>(none)</i>
    213 *       <td><code>DateFormat.createTimeInstance(kDefault, getLocale(), status)</code>
    214 *    <tr>
    215 *       <td><code>short</code>
    216 *       <td><code>DateFormat.createTimeInstance(kShort, getLocale(), status)</code>
    217 *    <tr>
    218 *       <td><code>medium</code>
    219 *       <td><code>DateFormat.createTimeInstance(kDefault, getLocale(), status)</code>
    220 *    <tr>
    221 *       <td><code>long</code>
    222 *       <td><code>DateFormat.createTimeInstance(kLong, getLocale(), status)</code>
    223 *    <tr>
    224 *       <td><code>full</code>
    225 *       <td><code>DateFormat.createTimeInstance(kFull, getLocale(), status)</code>
    226 *    <tr>
    227 *       <td><i>argStyleText</i>
    228 *       <td><code>new SimpleDateFormat(argStyleText, getLocale(), status)</code>
    229 *    <tr>
    230 *       <td><code>spellout</code>
    231 *       <td><i>argStyleText (optional)</i>
    232 *       <td><code>new RuleBasedNumberFormat(URBNF_SPELLOUT, getLocale(), status)
    233 *           <br/>&nbsp;&nbsp;&nbsp;&nbsp;.setDefaultRuleset(argStyleText, status);</code>
    234 *    <tr>
    235 *       <td><code>ordinal</code>
    236 *       <td><i>argStyleText (optional)</i>
    237 *       <td><code>new RuleBasedNumberFormat(URBNF_ORDINAL, getLocale(), status)
    238 *           <br/>&nbsp;&nbsp;&nbsp;&nbsp;.setDefaultRuleset(argStyleText, status);</code>
    239 *    <tr>
    240 *       <td><code>duration</code>
    241 *       <td><i>argStyleText (optional)</i>
    242 *       <td><code>new RuleBasedNumberFormat(URBNF_DURATION, getLocale(), status)
    243 *           <br/>&nbsp;&nbsp;&nbsp;&nbsp;.setDefaultRuleset(argStyleText, status);</code>
    244 * </table>
    245 * <p>
    246 *
    247 * <h4>Argument formatting</h4>
    248 *
    249 * <p>Arguments are formatted according to their type, using the default
    250 * ICU formatters for those types, unless otherwise specified.</p>
    251 *
    252 * <p>There are also several ways to control the formatting.</p>
    253 *
    254 * <p>We recommend you use default styles, predefined style values, skeletons,
    255 * or preformatted values, but not pattern strings or custom format objects.</p>
    256 *
    257 * <p>For more details, see the
    258 * <a href="https://unicode-org.github.io/icu/userguide/format_parse/messages">ICU User Guide</a>.</p>
    259 *
    260 * <h4>Usage Information</h4>
    261 *
    262 * <p>Here are some examples of usage:
    263 * Example 1:
    264 *
    265 * <pre>
    266 * \code
    267 *     UErrorCode success = U_ZERO_ERROR;
    268 *     GregorianCalendar cal(success);
    269 *     Formattable arguments[] = {
    270 *         7L,
    271 *         Formattable( (Date) cal.getTime(success), Formattable::kIsDate),
    272 *         "a disturbance in the Force"
    273 *     };
    274 *
    275 *     UnicodeString result;
    276 *     MessageFormat::format(
    277 *          "At {1,time,::jmm} on {1,date,::dMMMM}, there was {2} on planet {0,number}.",
    278 *          arguments, 3, result, success );
    279 *
    280 *     cout << "result: " << result << endl;
    281 *     //<output>: At 4:34 PM on March 23, there was a disturbance
    282 *     //             in the Force on planet 7.
    283 * \endcode
    284 * </pre>
    285 *
    286 * Typically, the message format will come from resources, and the
    287 * arguments will be dynamically set at runtime.
    288 *
    289 * <p>Example 2:
    290 *
    291 * <pre>
    292 *  \code
    293 *     success = U_ZERO_ERROR;
    294 *     Formattable testArgs[] = {3L, "MyDisk"};
    295 *
    296 *     MessageFormat form(
    297 *         "The disk \"{1}\" contains {0} file(s).", success );
    298 *
    299 *     UnicodeString string;
    300 *     FieldPosition fpos = 0;
    301 *     cout << "format: " << form.format(testArgs, 2, string, fpos, success ) << endl;
    302 *
    303 *     // output, with different testArgs:
    304 *     // output: The disk "MyDisk" contains 0 file(s).
    305 *     // output: The disk "MyDisk" contains 1 file(s).
    306 *     // output: The disk "MyDisk" contains 1,273 file(s).
    307 *  \endcode
    308 *  </pre>
    309 *
    310 *
    311 * <p>For messages that include plural forms, you can use a plural argument:
    312 * <pre>
    313 * \code
    314 *  success = U_ZERO_ERROR;
    315 *  MessageFormat msgFmt(
    316 *       "{num_files, plural, "
    317 *       "=0{There are no files on disk \"{disk_name}\".}"
    318 *       "=1{There is one file on disk \"{disk_name}\".}"
    319 *       "other{There are # files on disk \"{disk_name}\".}}",
    320 *      Locale("en"),
    321 *      success);
    322 *  FieldPosition fpos = 0;
    323 *  Formattable testArgs[] = {0L, "MyDisk"};
    324 *  UnicodeString testArgsNames[] = {"num_files", "disk_name"};
    325 *  UnicodeString result;
    326 *  cout << msgFmt.format(testArgs, testArgsNames, 2, result, fpos, 0, success);
    327 *  testArgs[0] = 3L;
    328 *  cout << msgFmt.format(testArgs, testArgsNames, 2, result, fpos, 0, success);
    329 * \endcode
    330 * <em>output</em>:
    331 * There are no files on disk "MyDisk".
    332 * There are 3 files on "MyDisk".
    333 * </pre>
    334 * See {@link PluralFormat} and {@link PluralRules} for details.
    335 *
    336 * <h4><a name="synchronization">Synchronization</a></h4>
    337 *
    338 * <p>MessageFormats are not synchronized.
    339 * It is recommended to create separate format instances for each thread.
    340 * If multiple threads access a format concurrently, it must be synchronized
    341 * externally.
    342 *
    343 * @stable ICU 2.0
    344 */
    345 class U_I18N_API_CLASS MessageFormat : public Format {
    346 public:
    347 #ifndef U_HIDE_OBSOLETE_API
    348    /**
    349     * Enum type for kMaxFormat.
    350     * @obsolete ICU 3.0.  The 10-argument limit was removed as of ICU 2.6,
    351     * rendering this enum type obsolete.
    352     */
    353    enum EFormatNumber {
    354        /**
    355         * The maximum number of arguments.
    356         * @obsolete ICU 3.0.  The 10-argument limit was removed as of ICU 2.6,
    357         * rendering this constant obsolete.
    358         */
    359        kMaxFormat = 10
    360    };
    361 #endif  /* U_HIDE_OBSOLETE_API */
    362 
    363    /**
    364     * Constructs a new MessageFormat using the given pattern and the
    365     * default locale.
    366     *
    367     * @param pattern   Pattern used to construct object.
    368     * @param status    Input/output error code.  If the
    369     *                  pattern cannot be parsed, set to failure code.
    370     * @stable ICU 2.0
    371     */
    372    U_I18N_API MessageFormat(const UnicodeString& pattern, UErrorCode& status);
    373 
    374    /**
    375     * Constructs a new MessageFormat using the given pattern and locale.
    376     * @param pattern   Pattern used to construct object.
    377     * @param newLocale The locale to use for formatting dates and numbers.
    378     * @param status    Input/output error code.  If the
    379     *                  pattern cannot be parsed, set to failure code.
    380     * @stable ICU 2.0
    381     */
    382    U_I18N_API MessageFormat(const UnicodeString& pattern, const Locale& newLocale, UErrorCode& status);
    383    /**
    384     * Constructs a new MessageFormat using the given pattern and locale.
    385     * @param pattern   Pattern used to construct object.
    386     * @param newLocale The locale to use for formatting dates and numbers.
    387     * @param parseError Struct to receive information on the position
    388     *                   of an error within the pattern.
    389     * @param status    Input/output error code.  If the
    390     *                  pattern cannot be parsed, set to failure code.
    391     * @stable ICU 2.0
    392     */
    393    U_I18N_API MessageFormat(const UnicodeString& pattern,
    394                             const Locale& newLocale,
    395                             UParseError& parseError,
    396                             UErrorCode& status);
    397    /**
    398     * Constructs a new MessageFormat from an existing one.
    399     * @stable ICU 2.0
    400     */
    401    U_I18N_API MessageFormat(const MessageFormat&);
    402 
    403    /**
    404     * Assignment operator.
    405     * @stable ICU 2.0
    406     */
    407    U_I18N_API const MessageFormat& operator=(const MessageFormat&);
    408 
    409    /**
    410     * Destructor.
    411     * @stable ICU 2.0
    412     */
    413    U_I18N_API virtual ~MessageFormat();
    414 
    415    /**
    416     * Clones this Format object polymorphically.  The caller owns the
    417     * result and should delete it when done.
    418     * @stable ICU 2.0
    419     */
    420    U_I18N_API virtual MessageFormat* clone() const override;
    421 
    422    /**
    423     * Returns true if the given Format objects are semantically equal.
    424     * Objects of different subclasses are considered unequal.
    425     * @param other  the object to be compared with.
    426     * @return       true if the given Format objects are semantically equal.
    427     * @stable ICU 2.0
    428     */
    429    U_I18N_API virtual bool operator==(const Format& other) const override;
    430 
    431    /**
    432     * Sets the locale to be used for creating argument Format objects.
    433     * @param theLocale    the new locale value to be set.
    434     * @stable ICU 2.0
    435     */
    436    U_I18N_API virtual void setLocale(const Locale& theLocale);
    437 
    438    /**
    439     * Gets the locale used for creating argument Format objects.
    440     * format information.
    441     * @return    the locale of the object.
    442     * @stable ICU 2.0
    443     */
    444    U_I18N_API virtual const Locale& getLocale() const;
    445 
    446    /**
    447     * Applies the given pattern string to this message format.
    448     *
    449     * @param pattern   The pattern to be applied.
    450     * @param status    Input/output error code.  If the
    451     *                  pattern cannot be parsed, set to failure code.
    452     * @stable ICU 2.0
    453     */
    454    U_I18N_API virtual void applyPattern(const UnicodeString& pattern, UErrorCode& status);
    455    /**
    456     * Applies the given pattern string to this message format.
    457     *
    458     * @param pattern    The pattern to be applied.
    459     * @param parseError Struct to receive information on the position
    460     *                   of an error within the pattern.
    461     * @param status    Input/output error code.  If the
    462     *                  pattern cannot be parsed, set to failure code.
    463     * @stable ICU 2.0
    464     */
    465    U_I18N_API virtual void applyPattern(const UnicodeString& pattern,
    466                                         UParseError& parseError,
    467                                         UErrorCode& status);
    468 
    469    /**
    470     * Sets the UMessagePatternApostropheMode and the pattern used by this message format.
    471     * Parses the pattern and caches Format objects for simple argument types.
    472     * Patterns and their interpretation are specified in the
    473     * <a href="#patterns">class description</a>.
    474     * <p>
    475     * This method is best used only once on a given object to avoid confusion about the mode,
    476     * and after constructing the object with an empty pattern string to minimize overhead.
    477     *
    478     * @param pattern    The pattern to be applied.
    479     * @param aposMode   The new apostrophe mode.
    480     * @param parseError Struct to receive information on the position
    481     *                   of an error within the pattern.
    482     *                   Can be nullptr.
    483     * @param status    Input/output error code.  If the
    484     *                  pattern cannot be parsed, set to failure code.
    485     * @stable ICU 4.8
    486     */
    487    U_I18N_API virtual void applyPattern(const UnicodeString& pattern,
    488                                         UMessagePatternApostropheMode aposMode,
    489                                         UParseError* parseError,
    490                                         UErrorCode& status);
    491 
    492    /**
    493     * @return this instance's UMessagePatternApostropheMode.
    494     * @stable ICU 4.8
    495     */
    496    U_I18N_API UMessagePatternApostropheMode getApostropheMode() const {
    497        return msgPattern.getApostropheMode();
    498    }
    499 
    500    /**
    501     * Returns a pattern that can be used to recreate this object.
    502     *
    503     * @param appendTo  Output parameter to receive the pattern.
    504     *                  Result is appended to existing contents.
    505     * @return          Reference to 'appendTo' parameter.
    506     * @stable ICU 2.0
    507     */
    508    U_I18N_API virtual UnicodeString& toPattern(UnicodeString& appendTo) const;
    509 
    510    /**
    511     * Sets subformats.
    512     * See the class description about format numbering.
    513     * The caller should not delete the Format objects after this call.
    514     * <EM>The array formatsToAdopt is not itself adopted.</EM> Its
    515     * ownership is retained by the caller. If the call fails because
    516     * memory cannot be allocated, then the formats will be deleted
    517     * by this method, and this object will remain unchanged.
    518     *
    519     * <p>If this format uses named arguments, the new formats are discarded
    520     * and this format remains unchanged.
    521     *
    522     * @stable ICU 2.0
    523     * @param formatsToAdopt    the format to be adopted.
    524     * @param count             the size of the array.
    525     */
    526    U_I18N_API virtual void adoptFormats(Format** formatsToAdopt, int32_t count);
    527 
    528    /**
    529     * Sets subformats.
    530     * See the class description about format numbering.
    531     * Each item in the array is cloned into the internal array.
    532     * If the call fails because memory cannot be allocated, then this
    533     * object will remain unchanged.
    534     *
    535     * <p>If this format uses named arguments, the new formats are discarded
    536     * and this format remains unchanged.
    537     *
    538     * @stable ICU 2.0
    539     * @param newFormats the new format to be set.
    540     * @param cnt        the size of the array.
    541     */
    542    U_I18N_API virtual void setFormats(const Format** newFormats, int32_t cnt);
    543 
    544    /**
    545     * Sets one subformat.
    546     * See the class description about format numbering.
    547     * The caller should not delete the Format object after this call.
    548     * If the number is over the number of formats already set,
    549     * the item will be deleted and ignored.
    550     *
    551     * <p>If this format uses named arguments, the new format is discarded
    552     * and this format remains unchanged.
    553     *
    554     * @stable ICU 2.0
    555     * @param formatNumber     index of the subformat.
    556     * @param formatToAdopt    the format to be adopted.
    557     */
    558    U_I18N_API virtual void adoptFormat(int32_t formatNumber, Format* formatToAdopt);
    559 
    560    /**
    561     * Sets one subformat.
    562     * See the class description about format numbering.
    563     * If the number is over the number of formats already set,
    564     * the item will be ignored.
    565     * @param formatNumber     index of the subformat.
    566     * @param format    the format to be set.
    567     * @stable ICU 2.0
    568     */
    569    U_I18N_API virtual void setFormat(int32_t formatNumber, const Format& format);
    570 
    571    /**
    572     * Gets format names. This function returns formatNames in StringEnumerations
    573     * which can be used with getFormat() and setFormat() to export formattable
    574     * array from current MessageFormat to another.  It is the caller's responsibility
    575     * to delete the returned formatNames.
    576     * @param status  output param set to success/failure code.
    577     * @stable ICU 4.0
    578     */
    579    U_I18N_API virtual StringEnumeration* getFormatNames(UErrorCode& status);
    580 
    581    /**
    582     * Gets subformat pointer for given format name.
    583     * This function supports both named and numbered
    584     * arguments. If numbered, the formatName is the
    585     * corresponding UnicodeStrings (e.g. "0", "1", "2"...).
    586     * The returned Format object should not be deleted by the caller,
    587     * nor should the pointer of other object .  The pointer and its
    588     * contents remain valid only until the next call to any method
    589     * of this class is made with this object.
    590     * @param formatName the name or number specifying a format
    591     * @param status  output param set to success/failure code.
    592     * @stable ICU 4.0
    593     */
    594    U_I18N_API virtual Format* getFormat(const UnicodeString& formatName, UErrorCode& status);
    595 
    596    /**
    597     * Sets one subformat for given format name.
    598     * See the class description about format name.
    599     * This function supports both named and numbered
    600     * arguments-- if numbered, the formatName is the
    601     * corresponding UnicodeStrings (e.g. "0", "1", "2"...).
    602     * If there is no matched formatName or wrong type,
    603     * the item will be ignored.
    604     * @param formatName  Name of the subformat.
    605     * @param format      the format to be set.
    606     * @param status  output param set to success/failure code.
    607     * @stable ICU 4.0
    608     */
    609    U_I18N_API virtual void setFormat(const UnicodeString& formatName,
    610                                      const Format& format,
    611                                      UErrorCode& status);
    612 
    613    /**
    614     * Sets one subformat for given format name.
    615     * See the class description about format name.
    616     * This function supports both named and numbered
    617     * arguments-- if numbered, the formatName is the
    618     * corresponding UnicodeStrings (e.g. "0", "1", "2"...).
    619     * If there is no matched formatName or wrong type,
    620     * the item will be ignored.
    621     * The caller should not delete the Format object after this call.
    622     * @param formatName  Name of the subformat.
    623     * @param formatToAdopt  Format to be adopted.
    624     * @param status      output param set to success/failure code.
    625     * @stable ICU 4.0
    626     */
    627    U_I18N_API virtual void adoptFormat(const UnicodeString& formatName,
    628                                        Format* formatToAdopt,
    629                                        UErrorCode& status);
    630 
    631    /**
    632     * Gets an array of subformats of this object.  The returned array
    633     * should not be deleted by the caller, nor should the pointers
    634     * within the array.  The array and its contents remain valid only
    635     * until the next call to this format. See the class description
    636     * about format numbering.
    637     *
    638     * @param count output parameter to receive the size of the array
    639     * @return an array of count Format* objects, or nullptr if out of
    640     * memory.  Any or all of the array elements may be nullptr.
    641     * @stable ICU 2.0
    642     */
    643    U_I18N_API virtual const Format** getFormats(int32_t& count) const;
    644 
    645    using Format::format;
    646 
    647    /**
    648     * Formats the given array of arguments into a user-readable string.
    649     * Does not take ownership of the Formattable* array or its contents.
    650     *
    651     * <p>If this format uses named arguments, appendTo is unchanged and
    652     * status is set to U_ILLEGAL_ARGUMENT_ERROR.
    653     *
    654     * @param source    An array of objects to be formatted.
    655     * @param count     The number of elements of 'source'.
    656     * @param appendTo  Output parameter to receive result.
    657     *                  Result is appended to existing contents.
    658     * @param ignore    Not used; inherited from base class API.
    659     * @param status    Input/output error code.  If the
    660     *                  pattern cannot be parsed, set to failure code.
    661     * @return          Reference to 'appendTo' parameter.
    662     * @stable ICU 2.0
    663     */
    664    U_I18N_API UnicodeString& format(const Formattable* source,
    665                                     int32_t count,
    666                                     UnicodeString& appendTo,
    667                                     FieldPosition& ignore,
    668                                     UErrorCode& status) const;
    669 
    670    /**
    671     * Formats the given array of arguments into a user-readable string
    672     * using the given pattern.
    673     *
    674     * <p>If this format uses named arguments, appendTo is unchanged and
    675     * status is set to U_ILLEGAL_ARGUMENT_ERROR.
    676     *
    677     * @param pattern   The pattern.
    678     * @param arguments An array of objects to be formatted.
    679     * @param count     The number of elements of 'source'.
    680     * @param appendTo  Output parameter to receive result.
    681     *                  Result is appended to existing contents.
    682     * @param status    Input/output error code.  If the
    683     *                  pattern cannot be parsed, set to failure code.
    684     * @return          Reference to 'appendTo' parameter.
    685     * @stable ICU 2.0
    686     */
    687    U_I18N_API static UnicodeString& format(const UnicodeString& pattern,
    688                                            const Formattable* arguments,
    689                                            int32_t count,
    690                                            UnicodeString& appendTo,
    691                                            UErrorCode& status);
    692 
    693    /**
    694     * Formats the given array of arguments into a user-readable
    695     * string.  The array must be stored within a single Formattable
    696     * object of type kArray. If the Formattable object type is not of
    697     * type kArray, then returns a failing UErrorCode.
    698     *
    699     * <p>If this format uses named arguments, appendTo is unchanged and
    700     * status is set to U_ILLEGAL_ARGUMENT_ERROR.
    701     *
    702     * @param obj       A Formattable of type kArray containing
    703     *                  arguments to be formatted.
    704     * @param appendTo  Output parameter to receive result.
    705     *                  Result is appended to existing contents.
    706     * @param pos       On input: an alignment field, if desired.
    707     *                  On output: the offsets of the alignment field.
    708     * @param status    Input/output error code.  If the
    709     *                  pattern cannot be parsed, set to failure code.
    710     * @return          Reference to 'appendTo' parameter.
    711     * @stable ICU 2.0
    712     */
    713    U_I18N_API virtual UnicodeString& format(const Formattable& obj,
    714                                             UnicodeString& appendTo,
    715                                             FieldPosition& pos,
    716                                             UErrorCode& status) const override;
    717 
    718    /**
    719     * Formats the given array of arguments into a user-defined argument name
    720     * array. This function supports both named and numbered
    721     * arguments-- if numbered, the formatName is the
    722     * corresponding UnicodeStrings (e.g. "0", "1", "2"...).
    723     *
    724     * @param argumentNames argument name array
    725     * @param arguments An array of objects to be formatted.
    726     * @param count     The number of elements of 'argumentNames' and
    727     *                  arguments.  The number of argumentNames and arguments
    728     *                  must be the same.
    729     * @param appendTo  Output parameter to receive result.
    730     *                  Result is appended to existing contents.
    731     * @param status    Input/output error code.  If the
    732     *                  pattern cannot be parsed, set to failure code.
    733     * @return          Reference to 'appendTo' parameter.
    734     * @stable ICU 4.0
    735     */
    736    U_I18N_API UnicodeString& format(const UnicodeString* argumentNames,
    737                                     const Formattable* arguments,
    738                                     int32_t count,
    739                                     UnicodeString& appendTo,
    740                                     UErrorCode& status) const;
    741    /**
    742     * Parses the given string into an array of output arguments.
    743     *
    744     * @param source    String to be parsed.
    745     * @param pos       On input, starting position for parse. On output,
    746     *                  final position after parse.  Unchanged if parse
    747     *                  fails.
    748     * @param count     Output parameter to receive the number of arguments
    749     *                  parsed.
    750     * @return an array of parsed arguments.  The caller owns both
    751     * the array and its contents.
    752     * @stable ICU 2.0
    753     */
    754    U_I18N_API virtual Formattable* parse(const UnicodeString& source,
    755                                          ParsePosition& pos,
    756                                          int32_t& count) const;
    757 
    758    /**
    759     * Parses the given string into an array of output arguments.
    760     *
    761     * <p>If this format uses named arguments, status is set to
    762     * U_ARGUMENT_TYPE_MISMATCH.
    763     *
    764     * @param source    String to be parsed.
    765     * @param count     Output param to receive size of returned array.
    766     * @param status    Input/output error code.  If the
    767     *                  pattern cannot be parsed, set to failure code.
    768     * @return an array of parsed arguments.  The caller owns both
    769     * the array and its contents. Returns nullptr if status is not U_ZERO_ERROR.
    770     *
    771     * @stable ICU 2.0
    772     */
    773    U_I18N_API virtual Formattable* parse(const UnicodeString& source,
    774                                          int32_t& count,
    775                                          UErrorCode& status) const;
    776 
    777    /**
    778     * Parses the given string into an array of output arguments
    779     * stored within a single Formattable of type kArray.
    780     *
    781     * @param source    The string to be parsed into an object.
    782     * @param result    Formattable to be set to the parse result.
    783     *                  If parse fails, return contents are undefined.
    784     * @param pos       On input, starting position for parse. On output,
    785     *                  final position after parse.  Unchanged if parse
    786     *                  fails.
    787     * @stable ICU 2.0
    788     */
    789    U_I18N_API virtual void parseObject(const UnicodeString& source,
    790                                        Formattable& result,
    791                                        ParsePosition& pos) const override;
    792 
    793    /**
    794     * Convert an 'apostrophe-friendly' pattern into a standard
    795     * pattern.  Standard patterns treat all apostrophes as
    796     * quotes, which is problematic in some languages, e.g.
    797     * French, where apostrophe is commonly used.  This utility
    798     * assumes that only an unpaired apostrophe immediately before
    799     * a brace is a true quote.  Other unpaired apostrophes are paired,
    800     * and the resulting standard pattern string is returned.
    801     *
    802     * <p><b>Note</b> it is not guaranteed that the returned pattern
    803     * is indeed a valid pattern.  The only effect is to convert
    804     * between patterns having different quoting semantics.
    805     *
    806     * @param pattern the 'apostrophe-friendly' patttern to convert
    807     * @param status    Input/output error code.  If the pattern
    808     *                  cannot be parsed, the failure code is set.
    809     * @return the standard equivalent of the original pattern
    810     * @stable ICU 3.4
    811     */
    812    U_I18N_API static UnicodeString autoQuoteApostrophe(const UnicodeString& pattern, UErrorCode& status);
    813 
    814    /**
    815     * Returns true if this MessageFormat uses named arguments,
    816     * and false otherwise.  See class description.
    817     *
    818     * @return true if named arguments are used.
    819     * @stable ICU 4.0
    820     */
    821    U_I18N_API UBool usesNamedArguments() const;
    822 
    823 #ifndef U_HIDE_INTERNAL_API
    824    /**
    825     * This API is for ICU internal use only.
    826     * Please do not use it.
    827     *
    828     * Returns argument types count in the parsed pattern.
    829     * Used to distinguish pattern "{0} d" and "d".
    830     *
    831     * @return           The number of formattable types in the pattern
    832     * @internal
    833     */
    834    U_I18N_API int32_t getArgTypeCount() const;
    835 #endif  /* U_HIDE_INTERNAL_API */
    836 
    837    /**
    838     * Returns a unique class ID POLYMORPHICALLY.  Pure virtual override.
    839     * This method is to implement a simple version of RTTI, since not all
    840     * C++ compilers support genuine RTTI.  Polymorphic operator==() and
    841     * clone() methods call this method.
    842     *
    843     * @return          The class ID for this object. All objects of a
    844     *                  given class have the same class ID.  Objects of
    845     *                  other classes have different class IDs.
    846     * @stable ICU 2.0
    847     */
    848    U_I18N_API virtual UClassID getDynamicClassID() const override;
    849 
    850    /**
    851     * Return the class ID for this class.  This is useful only for
    852     * comparing to a return value from getDynamicClassID().  For example:
    853     * <pre>
    854     * .   Base* polymorphic_pointer = createPolymorphicObject();
    855     * .   if (polymorphic_pointer->getDynamicClassID() ==
    856     * .      Derived::getStaticClassID()) ...
    857     * </pre>
    858     * @return          The class ID for all objects of this class.
    859     * @stable ICU 2.0
    860     */
    861    U_I18N_API static UClassID getStaticClassID();
    862 
    863 #ifndef U_HIDE_INTERNAL_API
    864    /**
    865     * Compares two Format objects. This is used for constructing the hash
    866     * tables.
    867     *
    868     * @param left pointer to a Format object. Must not be nullptr.
    869     * @param right pointer to a Format object. Must not be nullptr.
    870     *
    871     * @return whether the two objects are the same
    872     * @internal
    873     */
    874    U_I18N_API static UBool equalFormats(const void* left, const void* right);
    875 #endif  /* U_HIDE_INTERNAL_API */
    876 
    877 private:
    878 
    879    Locale              fLocale;
    880    MessagePattern      msgPattern;
    881    Format**            formatAliases; // see getFormats
    882    int32_t             formatAliasesCapacity;
    883 
    884    MessageFormat() = delete; // default constructor not implemented
    885 
    886     /**
    887      * This provider helps defer instantiation of a PluralRules object
    888      * until we actually need to select a keyword.
    889      * For example, if the number matches an explicit-value selector like "=1"
    890      * we do not need any PluralRules.
    891      */
    892    class PluralSelectorProvider : public PluralFormat::PluralSelector {
    893    public:
    894        PluralSelectorProvider(const MessageFormat &mf, UPluralType type);
    895        virtual ~PluralSelectorProvider();
    896        virtual UnicodeString select(void *ctx, double number, UErrorCode& ec) const override;
    897 
    898        void reset();
    899    private:
    900        const MessageFormat &msgFormat;
    901        PluralRules* rules;
    902        UPluralType type;
    903    };
    904 
    905    /**
    906     * A MessageFormat formats an array of arguments.  Each argument
    907     * has an expected type, based on the pattern.  For example, if
    908     * the pattern contains the subformat "{3,number,integer}", then
    909     * we expect argument 3 to have type Formattable::kLong.  This
    910     * array needs to grow dynamically if the MessageFormat is
    911     * modified.
    912     */
    913    Formattable::Type* argTypes;
    914    int32_t            argTypeCount;
    915    int32_t            argTypeCapacity;
    916 
    917    /**
    918     * true if there are different argTypes for the same argument.
    919     * This only matters when the MessageFormat is used in the plain C (umsg_xxx) API
    920     * where the pattern argTypes determine how the va_arg list is read.
    921     */
    922    UBool hasArgTypeConflicts;
    923 
    924    // Variable-size array management
    925    UBool allocateArgTypes(int32_t capacity, UErrorCode& status);
    926 
    927    /**
    928     * Default Format objects used when no format is specified and a
    929     * numeric or date argument is formatted.  These are volatile
    930     * cache objects maintained only for performance.  They do not
    931     * participate in operator=(), copy constructor(), nor
    932     * operator==().
    933     */
    934    NumberFormat* defaultNumberFormat;
    935    DateFormat*   defaultDateFormat;
    936 
    937    UHashtable* cachedFormatters;
    938    UHashtable* customFormatArgStarts;
    939 
    940    PluralSelectorProvider pluralProvider;
    941    PluralSelectorProvider ordinalProvider;
    942 
    943    /**
    944     * Method to retrieve default formats (or nullptr on failure).
    945     * These are semantically const, but may modify *this.
    946     */
    947    const NumberFormat* getDefaultNumberFormat(UErrorCode&) const;
    948    const DateFormat*   getDefaultDateFormat(UErrorCode&) const;
    949 
    950    /**
    951     * Finds the word s, in the keyword list and returns the located index.
    952     * @param s the keyword to be searched for.
    953     * @param list the list of keywords to be searched with.
    954     * @return the index of the list which matches the keyword s.
    955     */
    956    static int32_t findKeyword( const UnicodeString& s,
    957                                const char16_t * const *list);
    958 
    959    /**
    960     * Thin wrapper around the format(... AppendableWrapper ...) variant.
    961     * Wraps the destination UnicodeString into an AppendableWrapper and
    962     * supplies default values for some other parameters.
    963     */
    964    UnicodeString& format(const Formattable* arguments,
    965                          const UnicodeString *argumentNames,
    966                          int32_t cnt,
    967                          UnicodeString& appendTo,
    968                          FieldPosition* pos,
    969                          UErrorCode& status) const;
    970 
    971    /**
    972     * Formats the arguments and writes the result into the
    973     * AppendableWrapper, updates the field position.
    974     *
    975     * @param msgStart      Index to msgPattern part to start formatting from.
    976     * @param plNumber      nullptr except when formatting a plural argument sub-message
    977     *                      where a '#' is replaced by the format string for this number.
    978     * @param arguments     The formattable objects array. (Must not be nullptr.)
    979     * @param argumentNames nullptr if numbered values are used. Otherwise the same
    980     *                      length as "arguments", and each entry is the name of the
    981     *                      corresponding argument in "arguments".
    982     * @param cnt           The length of arguments (and of argumentNames if that is not nullptr).
    983     * @param appendTo      Output parameter to receive the result.
    984     *                      The result string is appended to existing contents.
    985     * @param pos           Field position status.
    986     * @param success       The error code status.
    987     */
    988    void format(int32_t msgStart,
    989                const void *plNumber,
    990                const Formattable* arguments,
    991                const UnicodeString *argumentNames,
    992                int32_t cnt,
    993                AppendableWrapper& appendTo,
    994                FieldPosition* pos,
    995                UErrorCode& success) const;
    996 
    997    UnicodeString getArgName(int32_t partIndex);
    998 
    999    void setArgStartFormat(int32_t argStart, Format* formatter, UErrorCode& status);
   1000 
   1001    void setCustomArgStartFormat(int32_t argStart, Format* formatter, UErrorCode& status);
   1002 
   1003    int32_t nextTopLevelArgStart(int32_t partIndex) const;
   1004 
   1005    UBool argNameMatches(int32_t partIndex, const UnicodeString& argName, int32_t argNumber);
   1006 
   1007    void cacheExplicitFormats(UErrorCode& status);
   1008 
   1009    Format* createAppropriateFormat(UnicodeString& type,
   1010                                    UnicodeString& style,
   1011                                    Formattable::Type& formattableType,
   1012                                    UParseError& parseError,
   1013                                    UErrorCode& ec);
   1014 
   1015    const Formattable* getArgFromListByName(const Formattable* arguments,
   1016                                            const UnicodeString *argumentNames,
   1017                                            int32_t cnt, UnicodeString& name) const;
   1018 
   1019    Formattable* parse(int32_t msgStart,
   1020                       const UnicodeString& source,
   1021                       ParsePosition& pos,
   1022                       int32_t& count,
   1023                       UErrorCode& ec) const;
   1024 
   1025    FieldPosition* updateMetaData(AppendableWrapper& dest, int32_t prevLength,
   1026                                  FieldPosition* fp, const Formattable* argId) const;
   1027 
   1028    /**
   1029     * Finds the "other" sub-message.
   1030     * @param partIndex the index of the first PluralFormat argument style part.
   1031     * @return the "other" sub-message start part index.
   1032     */
   1033    int32_t findOtherSubMessage(int32_t partIndex) const;
   1034 
   1035    /**
   1036     * Returns the ARG_START index of the first occurrence of the plural number in a sub-message.
   1037     * Returns -1 if it is a REPLACE_NUMBER.
   1038     * Returns 0 if there is neither.
   1039     */
   1040    int32_t findFirstPluralNumberArg(int32_t msgStart, const UnicodeString &argName) const;
   1041 
   1042    Format* getCachedFormatter(int32_t argumentNumber) const;
   1043 
   1044    UnicodeString getLiteralStringUntilNextArgument(int32_t from) const;
   1045 
   1046    void copyObjects(const MessageFormat& that, UErrorCode& ec);
   1047 
   1048    void formatComplexSubMessage(int32_t msgStart,
   1049                                 const void *plNumber,
   1050                                 const Formattable* arguments,
   1051                                 const UnicodeString *argumentNames,
   1052                                 int32_t cnt,
   1053                                 AppendableWrapper& appendTo,
   1054                                 UErrorCode& success) const;
   1055 
   1056    /**
   1057     * Convenience method that ought to be in NumberFormat
   1058     */
   1059    NumberFormat* createIntegerFormat(const Locale& locale, UErrorCode& status) const;
   1060 
   1061    /**
   1062     * Returns array of argument types in the parsed pattern
   1063     * for use in C API.  Only for the use of umsg_vformat().  Not
   1064     * for public consumption.
   1065     * @param listCount  Output parameter to receive the size of array
   1066     * @return           The array of formattable types in the pattern
   1067     */
   1068    const Formattable::Type* getArgTypeList(int32_t& listCount) const {
   1069        listCount = argTypeCount;
   1070        return argTypes;
   1071    }
   1072 
   1073    /**
   1074     * Resets the internal MessagePattern, and other associated caches.
   1075     */
   1076    void resetPattern();
   1077 
   1078    /**
   1079     * A DummyFormatter that we use solely to store a nullptr value. UHash does
   1080     * not support storing nullptr values.
   1081     */
   1082    class DummyFormat : public Format {
   1083    public:
   1084        virtual bool operator==(const Format&) const override;
   1085        virtual DummyFormat* clone() const override;
   1086        virtual UnicodeString& format(const Formattable& obj,
   1087                              UnicodeString& appendTo,
   1088                              UErrorCode& status) const;
   1089        virtual UnicodeString& format(const Formattable&,
   1090                                      UnicodeString& appendTo,
   1091                                      FieldPosition&,
   1092                                      UErrorCode& status) const override;
   1093        virtual UnicodeString& format(const Formattable& obj,
   1094                                      UnicodeString& appendTo,
   1095                                      FieldPositionIterator* posIter,
   1096                                      UErrorCode& status) const override;
   1097        virtual void parseObject(const UnicodeString&,
   1098                                 Formattable&,
   1099                                 ParsePosition&) const override;
   1100    };
   1101 
   1102    friend class MessageFormatAdapter; // getFormatTypeList() access
   1103 };
   1104 
   1105 U_NAMESPACE_END
   1106 
   1107 #endif /* #if !UCONFIG_NO_FORMATTING */
   1108 
   1109 #endif /* U_SHOW_CPLUSPLUS_API */
   1110 
   1111 #endif // _MSGFMT
   1112 //eof