• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 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     MessageFormat(const UnicodeString& pattern,
373                   UErrorCode &status);
374 
375     /**
376      * Constructs a new MessageFormat using the given pattern and locale.
377      * @param pattern   Pattern used to construct object.
378      * @param newLocale The locale to use for formatting dates and numbers.
379      * @param status    Input/output error code.  If the
380      *                  pattern cannot be parsed, set to failure code.
381      * @stable ICU 2.0
382      */
383     MessageFormat(const UnicodeString& pattern,
384                   const Locale& newLocale,
385                         UErrorCode& status);
386     /**
387      * Constructs a new MessageFormat using the given pattern and locale.
388      * @param pattern   Pattern used to construct object.
389      * @param newLocale The locale to use for formatting dates and numbers.
390      * @param parseError Struct to receive information on the position
391      *                   of an error within the pattern.
392      * @param status    Input/output error code.  If the
393      *                  pattern cannot be parsed, set to failure code.
394      * @stable ICU 2.0
395      */
396     MessageFormat(const UnicodeString& pattern,
397                   const Locale& newLocale,
398                   UParseError& parseError,
399                   UErrorCode& status);
400     /**
401      * Constructs a new MessageFormat from an existing one.
402      * @stable ICU 2.0
403      */
404     MessageFormat(const MessageFormat&);
405 
406     /**
407      * Assignment operator.
408      * @stable ICU 2.0
409      */
410     const MessageFormat& operator=(const MessageFormat&);
411 
412     /**
413      * Destructor.
414      * @stable ICU 2.0
415      */
416     virtual ~MessageFormat();
417 
418     /**
419      * Clones this Format object polymorphically.  The caller owns the
420      * result and should delete it when done.
421      * @stable ICU 2.0
422      */
423     virtual MessageFormat* clone() const override;
424 
425     /**
426      * Returns true if the given Format objects are semantically equal.
427      * Objects of different subclasses are considered unequal.
428      * @param other  the object to be compared with.
429      * @return       true if the given Format objects are semantically equal.
430      * @stable ICU 2.0
431      */
432     virtual bool operator==(const Format& other) const override;
433 
434     /**
435      * Sets the locale to be used for creating argument Format objects.
436      * @param theLocale    the new locale value to be set.
437      * @stable ICU 2.0
438      */
439     virtual void setLocale(const Locale& theLocale);
440 
441     /**
442      * Gets the locale used for creating argument Format objects.
443      * format information.
444      * @return    the locale of the object.
445      * @stable ICU 2.0
446      */
447     virtual const Locale& getLocale(void) const;
448 
449     /**
450      * Applies the given pattern string to this message format.
451      *
452      * @param pattern   The pattern to be applied.
453      * @param status    Input/output error code.  If the
454      *                  pattern cannot be parsed, set to failure code.
455      * @stable ICU 2.0
456      */
457     virtual void applyPattern(const UnicodeString& pattern,
458                               UErrorCode& status);
459     /**
460      * Applies the given pattern string to this message format.
461      *
462      * @param pattern    The pattern to be applied.
463      * @param parseError Struct to receive information on the position
464      *                   of an error within the pattern.
465      * @param status    Input/output error code.  If the
466      *                  pattern cannot be parsed, set to failure code.
467      * @stable ICU 2.0
468      */
469     virtual void applyPattern(const UnicodeString& pattern,
470                              UParseError& parseError,
471                              UErrorCode& status);
472 
473     /**
474      * Sets the UMessagePatternApostropheMode and the pattern used by this message format.
475      * Parses the pattern and caches Format objects for simple argument types.
476      * Patterns and their interpretation are specified in the
477      * <a href="#patterns">class description</a>.
478      * <p>
479      * This method is best used only once on a given object to avoid confusion about the mode,
480      * and after constructing the object with an empty pattern string to minimize overhead.
481      *
482      * @param pattern    The pattern to be applied.
483      * @param aposMode   The new apostrophe mode.
484      * @param parseError Struct to receive information on the position
485      *                   of an error within the pattern.
486      *                   Can be nullptr.
487      * @param status    Input/output error code.  If the
488      *                  pattern cannot be parsed, set to failure code.
489      * @stable ICU 4.8
490      */
491     virtual void applyPattern(const UnicodeString& pattern,
492                               UMessagePatternApostropheMode aposMode,
493                               UParseError* parseError,
494                               UErrorCode& status);
495 
496     /**
497      * @return this instance's UMessagePatternApostropheMode.
498      * @stable ICU 4.8
499      */
getApostropheMode()500     UMessagePatternApostropheMode getApostropheMode() const {
501         return msgPattern.getApostropheMode();
502     }
503 
504     /**
505      * Returns a pattern that can be used to recreate this object.
506      *
507      * @param appendTo  Output parameter to receive the pattern.
508      *                  Result is appended to existing contents.
509      * @return          Reference to 'appendTo' parameter.
510      * @stable ICU 2.0
511      */
512     virtual UnicodeString& toPattern(UnicodeString& appendTo) const;
513 
514     /**
515      * Sets subformats.
516      * See the class description about format numbering.
517      * The caller should not delete the Format objects after this call.
518      * <EM>The array formatsToAdopt is not itself adopted.</EM> Its
519      * ownership is retained by the caller. If the call fails because
520      * memory cannot be allocated, then the formats will be deleted
521      * by this method, and this object will remain unchanged.
522      *
523      * <p>If this format uses named arguments, the new formats are discarded
524      * and this format remains unchanged.
525      *
526      * @stable ICU 2.0
527      * @param formatsToAdopt    the format to be adopted.
528      * @param count             the size of the array.
529      */
530     virtual void adoptFormats(Format** formatsToAdopt, int32_t count);
531 
532     /**
533      * Sets subformats.
534      * See the class description about format numbering.
535      * Each item in the array is cloned into the internal array.
536      * If the call fails because memory cannot be allocated, then this
537      * object will remain unchanged.
538      *
539      * <p>If this format uses named arguments, the new formats are discarded
540      * and this format remains unchanged.
541      *
542      * @stable ICU 2.0
543      * @param newFormats the new format to be set.
544      * @param cnt        the size of the array.
545      */
546     virtual void setFormats(const Format** newFormats, int32_t cnt);
547 
548 
549     /**
550      * Sets one subformat.
551      * See the class description about format numbering.
552      * The caller should not delete the Format object after this call.
553      * If the number is over the number of formats already set,
554      * the item will be deleted and ignored.
555      *
556      * <p>If this format uses named arguments, the new format is discarded
557      * and this format remains unchanged.
558      *
559      * @stable ICU 2.0
560      * @param formatNumber     index of the subformat.
561      * @param formatToAdopt    the format to be adopted.
562      */
563     virtual void adoptFormat(int32_t formatNumber, Format* formatToAdopt);
564 
565     /**
566      * Sets one subformat.
567      * See the class description about format numbering.
568      * If the number is over the number of formats already set,
569      * the item will be ignored.
570      * @param formatNumber     index of the subformat.
571      * @param format    the format to be set.
572      * @stable ICU 2.0
573      */
574     virtual void setFormat(int32_t formatNumber, const Format& format);
575 
576     /**
577      * Gets format names. This function returns formatNames in StringEnumerations
578      * which can be used with getFormat() and setFormat() to export formattable
579      * array from current MessageFormat to another.  It is the caller's responsibility
580      * to delete the returned formatNames.
581      * @param status  output param set to success/failure code.
582      * @stable ICU 4.0
583      */
584     virtual StringEnumeration* getFormatNames(UErrorCode& status);
585 
586     /**
587      * Gets subformat pointer for given format name.
588      * This function supports both named and numbered
589      * arguments. If numbered, the formatName is the
590      * corresponding UnicodeStrings (e.g. "0", "1", "2"...).
591      * The returned Format object should not be deleted by the caller,
592      * nor should the pointer of other object .  The pointer and its
593      * contents remain valid only until the next call to any method
594      * of this class is made with this object.
595      * @param formatName the name or number specifying a format
596      * @param status  output param set to success/failure code.
597      * @stable ICU 4.0
598      */
599     virtual Format* getFormat(const UnicodeString& formatName, UErrorCode& status);
600 
601     /**
602      * Sets one subformat for given format name.
603      * See the class description about format name.
604      * This function supports both named and numbered
605      * arguments-- if numbered, the formatName is the
606      * corresponding UnicodeStrings (e.g. "0", "1", "2"...).
607      * If there is no matched formatName or wrong type,
608      * the item will be ignored.
609      * @param formatName  Name of the subformat.
610      * @param format      the format to be set.
611      * @param status  output param set to success/failure code.
612      * @stable ICU 4.0
613      */
614     virtual void setFormat(const UnicodeString& formatName, const Format& format, UErrorCode& status);
615 
616     /**
617      * Sets one subformat for given format name.
618      * See the class description about format name.
619      * This function supports both named and numbered
620      * arguments-- if numbered, the formatName is the
621      * corresponding UnicodeStrings (e.g. "0", "1", "2"...).
622      * If there is no matched formatName or wrong type,
623      * the item will be ignored.
624      * The caller should not delete the Format object after this call.
625      * @param formatName  Name of the subformat.
626      * @param formatToAdopt  Format to be adopted.
627      * @param status      output param set to success/failure code.
628      * @stable ICU 4.0
629      */
630     virtual void adoptFormat(const UnicodeString& formatName, Format* formatToAdopt, UErrorCode& status);
631 
632     /**
633      * Gets an array of subformats of this object.  The returned array
634      * should not be deleted by the caller, nor should the pointers
635      * within the array.  The array and its contents remain valid only
636      * until the next call to this format. See the class description
637      * about format numbering.
638      *
639      * @param count output parameter to receive the size of the array
640      * @return an array of count Format* objects, or nullptr if out of
641      * memory.  Any or all of the array elements may be nullptr.
642      * @stable ICU 2.0
643      */
644     virtual const Format** getFormats(int32_t& count) const;
645 
646 
647     using Format::format;
648 
649     /**
650      * Formats the given array of arguments into a user-readable string.
651      * Does not take ownership of the Formattable* array or its contents.
652      *
653      * <p>If this format uses named arguments, appendTo is unchanged and
654      * status is set to U_ILLEGAL_ARGUMENT_ERROR.
655      *
656      * @param source    An array of objects to be formatted.
657      * @param count     The number of elements of 'source'.
658      * @param appendTo  Output parameter to receive result.
659      *                  Result is appended to existing contents.
660      * @param ignore    Not used; inherited from base class API.
661      * @param status    Input/output error code.  If the
662      *                  pattern cannot be parsed, set to failure code.
663      * @return          Reference to 'appendTo' parameter.
664      * @stable ICU 2.0
665      */
666     UnicodeString& format(const Formattable* source,
667                           int32_t count,
668                           UnicodeString& appendTo,
669                           FieldPosition& ignore,
670                           UErrorCode& status) const;
671 
672     /**
673      * Formats the given array of arguments into a user-readable string
674      * using the given pattern.
675      *
676      * <p>If this format uses named arguments, appendTo is unchanged and
677      * status is set to U_ILLEGAL_ARGUMENT_ERROR.
678      *
679      * @param pattern   The pattern.
680      * @param arguments An array of objects to be formatted.
681      * @param count     The number of elements of 'source'.
682      * @param appendTo  Output parameter to receive result.
683      *                  Result is appended to existing contents.
684      * @param status    Input/output error code.  If the
685      *                  pattern cannot be parsed, set to failure code.
686      * @return          Reference to 'appendTo' parameter.
687      * @stable ICU 2.0
688      */
689     static UnicodeString& format(const UnicodeString& pattern,
690                                  const Formattable* arguments,
691                                  int32_t count,
692                                  UnicodeString& appendTo,
693                                  UErrorCode& status);
694 
695     /**
696      * Formats the given array of arguments into a user-readable
697      * string.  The array must be stored within a single Formattable
698      * object of type kArray. If the Formattable object type is not of
699      * type kArray, then returns a failing UErrorCode.
700      *
701      * <p>If this format uses named arguments, appendTo is unchanged and
702      * status is set to U_ILLEGAL_ARGUMENT_ERROR.
703      *
704      * @param obj       A Formattable of type kArray containing
705      *                  arguments to be formatted.
706      * @param appendTo  Output parameter to receive result.
707      *                  Result is appended to existing contents.
708      * @param pos       On input: an alignment field, if desired.
709      *                  On output: the offsets of the alignment field.
710      * @param status    Input/output error code.  If the
711      *                  pattern cannot be parsed, set to failure code.
712      * @return          Reference to 'appendTo' parameter.
713      * @stable ICU 2.0
714      */
715     virtual UnicodeString& format(const Formattable& obj,
716                                   UnicodeString& appendTo,
717                                   FieldPosition& pos,
718                                   UErrorCode& status) const override;
719 
720     /**
721      * Formats the given array of arguments into a user-defined argument name
722      * array. This function supports both named and numbered
723      * arguments-- if numbered, the formatName is the
724      * corresponding UnicodeStrings (e.g. "0", "1", "2"...).
725      *
726      * @param argumentNames argument name array
727      * @param arguments An array of objects to be formatted.
728      * @param count     The number of elements of 'argumentNames' and
729      *                  arguments.  The number of argumentNames and arguments
730      *                  must be the same.
731      * @param appendTo  Output parameter to receive result.
732      *                  Result is appended to existing contents.
733      * @param status    Input/output error code.  If the
734      *                  pattern cannot be parsed, set to failure code.
735      * @return          Reference to 'appendTo' parameter.
736      * @stable ICU 4.0
737      */
738     UnicodeString& format(const UnicodeString* argumentNames,
739                           const Formattable* arguments,
740                           int32_t count,
741                           UnicodeString& appendTo,
742                           UErrorCode& status) const;
743     /**
744      * Parses the given string into an array of output arguments.
745      *
746      * @param source    String to be parsed.
747      * @param pos       On input, starting position for parse. On output,
748      *                  final position after parse.  Unchanged if parse
749      *                  fails.
750      * @param count     Output parameter to receive the number of arguments
751      *                  parsed.
752      * @return an array of parsed arguments.  The caller owns both
753      * the array and its contents.
754      * @stable ICU 2.0
755      */
756     virtual Formattable* parse(const UnicodeString& source,
757                                ParsePosition& pos,
758                                int32_t& count) const;
759 
760     /**
761      * Parses the given string into an array of output arguments.
762      *
763      * <p>If this format uses named arguments, status is set to
764      * U_ARGUMENT_TYPE_MISMATCH.
765      *
766      * @param source    String to be parsed.
767      * @param count     Output param to receive size of returned array.
768      * @param status    Input/output error code.  If the
769      *                  pattern cannot be parsed, set to failure code.
770      * @return an array of parsed arguments.  The caller owns both
771      * the array and its contents. Returns nullptr if status is not U_ZERO_ERROR.
772      *
773      * @stable ICU 2.0
774      */
775     virtual Formattable* parse(const UnicodeString& source,
776                                int32_t& count,
777                                UErrorCode& status) const;
778 
779     /**
780      * Parses the given string into an array of output arguments
781      * stored within a single Formattable of type kArray.
782      *
783      * @param source    The string to be parsed into an object.
784      * @param result    Formattable to be set to the parse result.
785      *                  If parse fails, return contents are undefined.
786      * @param pos       On input, starting position for parse. On output,
787      *                  final position after parse.  Unchanged if parse
788      *                  fails.
789      * @stable ICU 2.0
790      */
791     virtual void parseObject(const UnicodeString& source,
792                              Formattable& result,
793                              ParsePosition& pos) const override;
794 
795     /**
796      * Convert an 'apostrophe-friendly' pattern into a standard
797      * pattern.  Standard patterns treat all apostrophes as
798      * quotes, which is problematic in some languages, e.g.
799      * French, where apostrophe is commonly used.  This utility
800      * assumes that only an unpaired apostrophe immediately before
801      * a brace is a true quote.  Other unpaired apostrophes are paired,
802      * and the resulting standard pattern string is returned.
803      *
804      * <p><b>Note</b> it is not guaranteed that the returned pattern
805      * is indeed a valid pattern.  The only effect is to convert
806      * between patterns having different quoting semantics.
807      *
808      * @param pattern the 'apostrophe-friendly' patttern to convert
809      * @param status    Input/output error code.  If the pattern
810      *                  cannot be parsed, the failure code is set.
811      * @return the standard equivalent of the original pattern
812      * @stable ICU 3.4
813      */
814     static UnicodeString autoQuoteApostrophe(const UnicodeString& pattern,
815         UErrorCode& status);
816 
817 
818     /**
819      * Returns true if this MessageFormat uses named arguments,
820      * and false otherwise.  See class description.
821      *
822      * @return true if named arguments are used.
823      * @stable ICU 4.0
824      */
825     UBool usesNamedArguments() const;
826 
827 
828 #ifndef U_HIDE_INTERNAL_API
829     /**
830      * This API is for ICU internal use only.
831      * Please do not use it.
832      *
833      * Returns argument types count in the parsed pattern.
834      * Used to distinguish pattern "{0} d" and "d".
835      *
836      * @return           The number of formattable types in the pattern
837      * @internal
838      */
839     int32_t getArgTypeCount() const;
840 #endif  /* U_HIDE_INTERNAL_API */
841 
842     /**
843      * Returns a unique class ID POLYMORPHICALLY.  Pure virtual override.
844      * This method is to implement a simple version of RTTI, since not all
845      * C++ compilers support genuine RTTI.  Polymorphic operator==() and
846      * clone() methods call this method.
847      *
848      * @return          The class ID for this object. All objects of a
849      *                  given class have the same class ID.  Objects of
850      *                  other classes have different class IDs.
851      * @stable ICU 2.0
852      */
853     virtual UClassID getDynamicClassID(void) const override;
854 
855     /**
856      * Return the class ID for this class.  This is useful only for
857      * comparing to a return value from getDynamicClassID().  For example:
858      * <pre>
859      * .   Base* polymorphic_pointer = createPolymorphicObject();
860      * .   if (polymorphic_pointer->getDynamicClassID() ==
861      * .      Derived::getStaticClassID()) ...
862      * </pre>
863      * @return          The class ID for all objects of this class.
864      * @stable ICU 2.0
865      */
866     static UClassID U_EXPORT2 getStaticClassID(void);
867 
868 #ifndef U_HIDE_INTERNAL_API
869     /**
870      * Compares two Format objects. This is used for constructing the hash
871      * tables.
872      *
873      * @param left pointer to a Format object. Must not be nullptr.
874      * @param right pointer to a Format object. Must not be nullptr.
875      *
876      * @return whether the two objects are the same
877      * @internal
878      */
879     static UBool equalFormats(const void* left, const void* right);
880 #endif  /* U_HIDE_INTERNAL_API */
881 
882 private:
883 
884     Locale              fLocale;
885     MessagePattern      msgPattern;
886     Format**            formatAliases; // see getFormats
887     int32_t             formatAliasesCapacity;
888 
889     MessageFormat() = delete; // default constructor not implemented
890 
891      /**
892       * This provider helps defer instantiation of a PluralRules object
893       * until we actually need to select a keyword.
894       * For example, if the number matches an explicit-value selector like "=1"
895       * we do not need any PluralRules.
896       */
897     class U_I18N_API PluralSelectorProvider : public PluralFormat::PluralSelector {
898     public:
899         PluralSelectorProvider(const MessageFormat &mf, UPluralType type);
900         virtual ~PluralSelectorProvider();
901         virtual UnicodeString select(void *ctx, double number, UErrorCode& ec) const override;
902 
903         void reset();
904     private:
905         const MessageFormat &msgFormat;
906         PluralRules* rules;
907         UPluralType type;
908     };
909 
910     /**
911      * A MessageFormat formats an array of arguments.  Each argument
912      * has an expected type, based on the pattern.  For example, if
913      * the pattern contains the subformat "{3,number,integer}", then
914      * we expect argument 3 to have type Formattable::kLong.  This
915      * array needs to grow dynamically if the MessageFormat is
916      * modified.
917      */
918     Formattable::Type* argTypes;
919     int32_t            argTypeCount;
920     int32_t            argTypeCapacity;
921 
922     /**
923      * true if there are different argTypes for the same argument.
924      * This only matters when the MessageFormat is used in the plain C (umsg_xxx) API
925      * where the pattern argTypes determine how the va_arg list is read.
926      */
927     UBool hasArgTypeConflicts;
928 
929     // Variable-size array management
930     UBool allocateArgTypes(int32_t capacity, UErrorCode& status);
931 
932     /**
933      * Default Format objects used when no format is specified and a
934      * numeric or date argument is formatted.  These are volatile
935      * cache objects maintained only for performance.  They do not
936      * participate in operator=(), copy constructor(), nor
937      * operator==().
938      */
939     NumberFormat* defaultNumberFormat;
940     DateFormat*   defaultDateFormat;
941 
942     UHashtable* cachedFormatters;
943     UHashtable* customFormatArgStarts;
944 
945     PluralSelectorProvider pluralProvider;
946     PluralSelectorProvider ordinalProvider;
947 
948     /**
949      * Method to retrieve default formats (or nullptr on failure).
950      * These are semantically const, but may modify *this.
951      */
952     const NumberFormat* getDefaultNumberFormat(UErrorCode&) const;
953     const DateFormat*   getDefaultDateFormat(UErrorCode&) const;
954 
955     /**
956      * Finds the word s, in the keyword list and returns the located index.
957      * @param s the keyword to be searched for.
958      * @param list the list of keywords to be searched with.
959      * @return the index of the list which matches the keyword s.
960      */
961     static int32_t findKeyword( const UnicodeString& s,
962                                 const char16_t * const *list);
963 
964     /**
965      * Thin wrapper around the format(... AppendableWrapper ...) variant.
966      * Wraps the destination UnicodeString into an AppendableWrapper and
967      * supplies default values for some other parameters.
968      */
969     UnicodeString& format(const Formattable* arguments,
970                           const UnicodeString *argumentNames,
971                           int32_t cnt,
972                           UnicodeString& appendTo,
973                           FieldPosition* pos,
974                           UErrorCode& status) const;
975 
976     /**
977      * Formats the arguments and writes the result into the
978      * AppendableWrapper, updates the field position.
979      *
980      * @param msgStart      Index to msgPattern part to start formatting from.
981      * @param plNumber      nullptr except when formatting a plural argument sub-message
982      *                      where a '#' is replaced by the format string for this number.
983      * @param arguments     The formattable objects array. (Must not be nullptr.)
984      * @param argumentNames nullptr if numbered values are used. Otherwise the same
985      *                      length as "arguments", and each entry is the name of the
986      *                      corresponding argument in "arguments".
987      * @param cnt           The length of arguments (and of argumentNames if that is not nullptr).
988      * @param appendTo      Output parameter to receive the result.
989      *                      The result string is appended to existing contents.
990      * @param pos           Field position status.
991      * @param success       The error code status.
992      */
993     void format(int32_t msgStart,
994                 const void *plNumber,
995                 const Formattable* arguments,
996                 const UnicodeString *argumentNames,
997                 int32_t cnt,
998                 AppendableWrapper& appendTo,
999                 FieldPosition* pos,
1000                 UErrorCode& success) const;
1001 
1002     UnicodeString getArgName(int32_t partIndex);
1003 
1004     void setArgStartFormat(int32_t argStart, Format* formatter, UErrorCode& status);
1005 
1006     void setCustomArgStartFormat(int32_t argStart, Format* formatter, UErrorCode& status);
1007 
1008     int32_t nextTopLevelArgStart(int32_t partIndex) const;
1009 
1010     UBool argNameMatches(int32_t partIndex, const UnicodeString& argName, int32_t argNumber);
1011 
1012     void cacheExplicitFormats(UErrorCode& status);
1013 
1014     Format* createAppropriateFormat(UnicodeString& type,
1015                                     UnicodeString& style,
1016                                     Formattable::Type& formattableType,
1017                                     UParseError& parseError,
1018                                     UErrorCode& ec);
1019 
1020     const Formattable* getArgFromListByName(const Formattable* arguments,
1021                                             const UnicodeString *argumentNames,
1022                                             int32_t cnt, UnicodeString& name) const;
1023 
1024     Formattable* parse(int32_t msgStart,
1025                        const UnicodeString& source,
1026                        ParsePosition& pos,
1027                        int32_t& count,
1028                        UErrorCode& ec) const;
1029 
1030     FieldPosition* updateMetaData(AppendableWrapper& dest, int32_t prevLength,
1031                                   FieldPosition* fp, const Formattable* argId) const;
1032 
1033     /**
1034      * Finds the "other" sub-message.
1035      * @param partIndex the index of the first PluralFormat argument style part.
1036      * @return the "other" sub-message start part index.
1037      */
1038     int32_t findOtherSubMessage(int32_t partIndex) const;
1039 
1040     /**
1041      * Returns the ARG_START index of the first occurrence of the plural number in a sub-message.
1042      * Returns -1 if it is a REPLACE_NUMBER.
1043      * Returns 0 if there is neither.
1044      */
1045     int32_t findFirstPluralNumberArg(int32_t msgStart, const UnicodeString &argName) const;
1046 
1047     Format* getCachedFormatter(int32_t argumentNumber) const;
1048 
1049     UnicodeString getLiteralStringUntilNextArgument(int32_t from) const;
1050 
1051     void copyObjects(const MessageFormat& that, UErrorCode& ec);
1052 
1053     void formatComplexSubMessage(int32_t msgStart,
1054                                  const void *plNumber,
1055                                  const Formattable* arguments,
1056                                  const UnicodeString *argumentNames,
1057                                  int32_t cnt,
1058                                  AppendableWrapper& appendTo,
1059                                  UErrorCode& success) const;
1060 
1061     /**
1062      * Convenience method that ought to be in NumberFormat
1063      */
1064     NumberFormat* createIntegerFormat(const Locale& locale, UErrorCode& status) const;
1065 
1066     /**
1067      * Returns array of argument types in the parsed pattern
1068      * for use in C API.  Only for the use of umsg_vformat().  Not
1069      * for public consumption.
1070      * @param listCount  Output parameter to receive the size of array
1071      * @return           The array of formattable types in the pattern
1072      */
getArgTypeList(int32_t & listCount)1073     const Formattable::Type* getArgTypeList(int32_t& listCount) const {
1074         listCount = argTypeCount;
1075         return argTypes;
1076     }
1077 
1078     /**
1079      * Resets the internal MessagePattern, and other associated caches.
1080      */
1081     void resetPattern();
1082 
1083     /**
1084      * A DummyFormatter that we use solely to store a nullptr value. UHash does
1085      * not support storing nullptr values.
1086      */
1087     class U_I18N_API DummyFormat : public Format {
1088     public:
1089         virtual bool operator==(const Format&) const override;
1090         virtual DummyFormat* clone() const override;
1091         virtual UnicodeString& format(const Formattable& obj,
1092                               UnicodeString& appendTo,
1093                               UErrorCode& status) const;
1094         virtual UnicodeString& format(const Formattable&,
1095                                       UnicodeString& appendTo,
1096                                       FieldPosition&,
1097                                       UErrorCode& status) const override;
1098         virtual UnicodeString& format(const Formattable& obj,
1099                                       UnicodeString& appendTo,
1100                                       FieldPositionIterator* posIter,
1101                                       UErrorCode& status) const override;
1102         virtual void parseObject(const UnicodeString&,
1103                                  Formattable&,
1104                                  ParsePosition&) const override;
1105     };
1106 
1107     friend class MessageFormatAdapter; // getFormatTypeList() access
1108 };
1109 
1110 U_NAMESPACE_END
1111 
1112 #endif /* #if !UCONFIG_NO_FORMATTING */
1113 
1114 #endif /* U_SHOW_CPLUSPLUS_API */
1115 
1116 #endif // _MSGFMT
1117 //eof
1118