// © 2016 and later: Unicode, Inc. and others.
// License & terms of use: http://www.unicode.org/copyright.html
/*
* Copyright (C) 2007-2013, International Business Machines Corporation and
* others. All Rights Reserved.
********************************************************************************
*
* File MSGFMT.H
*
* Modification History:
*
*   Date        Name        Description
*   02/19/97    aliu        Converted from java.
*   03/20/97    helena      Finished first cut of implementation.
*   07/22/98    stephen     Removed operator!= (defined in Format)
*   08/19/2002  srl         Removing Javaisms
*******************************************************************************/

#ifndef MSGFMT_H
#define MSGFMT_H

#include "unicode/utypes.h"

/**
 * \file
 * \brief C++ API: Formats messages in a language-neutral way.
 */

#if !UCONFIG_NO_FORMATTING

#include "unicode/format.h"
#include "unicode/locid.h"
#include "unicode/messagepattern.h"
#include "unicode/parseerr.h"
#include "unicode/plurfmt.h"
#include "unicode/plurrule.h"

U_CDECL_BEGIN
// Forward declaration.
struct UHashtable;
typedef struct UHashtable UHashtable; /**< @internal */
U_CDECL_END

U_NAMESPACE_BEGIN

class AppendableWrapper;
class DateFormat;
class NumberFormat;

/**
 * <p>MessageFormat prepares strings for display to users,
 * with optional arguments (variables/placeholders).
 * The arguments can occur in any order, which is necessary for translation
 * into languages with different grammars.
 *
 * <p>A MessageFormat is constructed from a <em>pattern</em> string
 * with arguments in {curly braces} which will be replaced by formatted values.
 *
 * <p><code>MessageFormat</code> differs from the other <code>Format</code>
 * classes in that you create a <code>MessageFormat</code> object with one
 * of its constructors (not with a <code>createInstance</code> style factory
 * method). Factory methods aren't necessary because <code>MessageFormat</code>
 * itself doesn't implement locale-specific behavior. Any locale-specific
 * behavior is defined by the pattern that you provide and the
 * subformats used for inserted arguments.
 *
 * <p>Arguments can be named (using identifiers) or numbered (using small ASCII-digit integers).
 * Some of the API methods work only with argument numbers and throw an exception
 * if the pattern has named arguments (see {@link #usesNamedArguments()}).
 *
 * <p>An argument might not specify any format type. In this case,
 * a numeric value is formatted with a default (for the locale) NumberFormat,
 * and a date/time value is formatted with a default (for the locale) DateFormat.
 *
 * <p>An argument might specify a "simple" type for which the specified
 * Format object is created, cached and used.
 *
 * <p>An argument might have a "complex" type with nested MessageFormat sub-patterns.
 * During formatting, one of these sub-messages is selected according to the argument value
 * and recursively formatted.
 *
 * <p>After construction, a custom Format object can be set for
 * a top-level argument, overriding the default formatting and parsing behavior
 * for that argument.
 * However, custom formatting can be achieved more simply by writing
 * a typeless argument in the pattern string
 * and supplying it with a preformatted string value.
 *
 * <p>When formatting, MessageFormat takes a collection of argument values
 * and writes an output string.
 * The argument values may be passed as an array
 * (when the pattern contains only numbered arguments)
 * or as an array of names and and an array of arguments (which works for both named
 * and numbered arguments).
 *
 * <p>Each argument is matched with one of the input values by array index or argument name
 * and formatted according to its pattern specification
 * (or using a custom Format object if one was set).
 * A numbered pattern argument is matched with an argument name that contains that number
 * as an ASCII-decimal-digit string (without leading zero).
 *
 * <h4><a name="patterns">Patterns and Their Interpretation</a></h4>
 *
 * <code>MessageFormat</code> uses patterns of the following form:
 * <pre>
 * message = messageText (argument messageText)*
 * argument = noneArg | simpleArg | complexArg
 * complexArg = choiceArg | pluralArg | selectArg | selectordinalArg
 *
 * noneArg = '{' argNameOrNumber '}'
 * simpleArg = '{' argNameOrNumber ',' argType [',' argStyle] '}'
 * choiceArg = '{' argNameOrNumber ',' "choice" ',' choiceStyle '}'
 * pluralArg = '{' argNameOrNumber ',' "plural" ',' pluralStyle '}'
 * selectArg = '{' argNameOrNumber ',' "select" ',' selectStyle '}'
 * selectordinalArg = '{' argNameOrNumber ',' "selectordinal" ',' pluralStyle '}'
 *
 * choiceStyle: see {@link ChoiceFormat}
 * pluralStyle: see {@link PluralFormat}
 * selectStyle: see {@link SelectFormat}
 *
 * argNameOrNumber = argName | argNumber
 * argName = [^[[:Pattern_Syntax:][:Pattern_White_Space:]]]+
 * argNumber = '0' | ('1'..'9' ('0'..'9')*)
 *
 * argType = "number" | "date" | "time" | "spellout" | "ordinal" | "duration"
 * argStyle = "short" | "medium" | "long" | "full" | "integer" | "currency" | "percent" | argStyleText | "::" argSkeletonText
 * </pre>
 *
 * <ul>
 *   <li>messageText can contain quoted literal strings including syntax characters.
 *       A quoted literal string begins with an ASCII apostrophe and a syntax character
 *       (usually a {curly brace}) and continues until the next single apostrophe.
 *       A double ASCII apostrohpe inside or outside of a quoted string represents
 *       one literal apostrophe.
 *   <li>Quotable syntax characters are the {curly braces} in all messageText parts,
 *       plus the '#' sign in a messageText immediately inside a pluralStyle,
 *       and the '|' symbol in a messageText immediately inside a choiceStyle.
 *   <li>See also {@link #UMessagePatternApostropheMode}
 *   <li>In argStyleText, every single ASCII apostrophe begins and ends quoted literal text,
 *       and unquoted {curly braces} must occur in matched pairs.
 * </ul>
 *
 * <p>Recommendation: Use the real apostrophe (single quote) character
 * \htmlonly&#x2019;\endhtmlonly (U+2019) for
 * human-readable text, and use the ASCII apostrophe ' (U+0027)
 * only in program syntax, like quoting in MessageFormat.
 * See the annotations for U+0027 Apostrophe in The Unicode Standard.
 *
 * <p>The <code>choice</code> argument type is deprecated.
 * Use <code>plural</code> arguments for proper plural selection,
 * and <code>select</code> arguments for simple selection among a fixed set of choices.
 *
 * <p>The <code>argType</code> and <code>argStyle</code> values are used to create
 * a <code>Format</code> instance for the format element. The following
 * table shows how the values map to Format instances. Combinations not
 * shown in the table are illegal. Any <code>argStyleText</code> must
 * be a valid pattern string for the Format subclass used.
 *
 * <p><table border=1>
 *    <tr>
 *       <th>argType
 *       <th>argStyle
 *       <th>resulting Format object
 *    <tr>
 *       <td colspan=2><i>(none)</i>
 *       <td><code>null</code>
 *    <tr>
 *       <td rowspan=6><code>number</code>
 *       <td><i>(none)</i>
 *       <td><code>NumberFormat.createInstance(getLocale(), status)</code>
 *    <tr>
 *       <td><code>integer</code>
 *       <td><code>NumberFormat.createInstance(getLocale(), kNumberStyle, status)</code>
 *    <tr>
 *       <td><code>currency</code>
 *       <td><code>NumberFormat.createCurrencyInstance(getLocale(), status)</code>
 *    <tr>
 *       <td><code>percent</code>
 *       <td><code>NumberFormat.createPercentInstance(getLocale(), status)</code>
 *    <tr>
 *       <td><i>argStyleText</i>
 *       <td><code>new DecimalFormat(argStyleText, new DecimalFormatSymbols(getLocale(), status), status)</code>
 *    <tr>
 *       <td><i>argSkeletonText</i>
 *       <td><code>NumberFormatter::forSkeleton(argSkeletonText, status).locale(getLocale()).toFormat(status)</code>
 *    <tr>
 *       <td rowspan=7><code>date</code>
 *       <td><i>(none)</i>
 *       <td><code>DateFormat.createDateInstance(kDefault, getLocale(), status)</code>
 *    <tr>
 *       <td><code>short</code>
 *       <td><code>DateFormat.createDateInstance(kShort, getLocale(), status)</code>
 *    <tr>
 *       <td><code>medium</code>
 *       <td><code>DateFormat.createDateInstance(kDefault, getLocale(), status)</code>
 *    <tr>
 *       <td><code>long</code>
 *       <td><code>DateFormat.createDateInstance(kLong, getLocale(), status)</code>
 *    <tr>
 *       <td><code>full</code>
 *       <td><code>DateFormat.createDateInstance(kFull, getLocale(), status)</code>
 *    <tr>
 *       <td><i>argStyleText</i>
 *       <td><code>new SimpleDateFormat(argStyleText, getLocale(), status)</code>
 *    <tr>
 *       <td><i>argSkeletonText</i>
 *       <td><code>DateFormat::createInstanceForSkeleton(argSkeletonText, getLocale(), status)</code>
 *    <tr>
 *       <td rowspan=6><code>time</code>
 *       <td><i>(none)</i>
 *       <td><code>DateFormat.createTimeInstance(kDefault, getLocale(), status)</code>
 *    <tr>
 *       <td><code>short</code>
 *       <td><code>DateFormat.createTimeInstance(kShort, getLocale(), status)</code>
 *    <tr>
 *       <td><code>medium</code>
 *       <td><code>DateFormat.createTimeInstance(kDefault, getLocale(), status)</code>
 *    <tr>
 *       <td><code>long</code>
 *       <td><code>DateFormat.createTimeInstance(kLong, getLocale(), status)</code>
 *    <tr>
 *       <td><code>full</code>
 *       <td><code>DateFormat.createTimeInstance(kFull, getLocale(), status)</code>
 *    <tr>
 *       <td><i>argStyleText</i>
 *       <td><code>new SimpleDateFormat(argStyleText, getLocale(), status)</code>
 *    <tr>
 *       <td><code>spellout</code>
 *       <td><i>argStyleText (optional)</i>
 *       <td><code>new RuleBasedNumberFormat(URBNF_SPELLOUT, getLocale(), status)
 *           <br/>&nbsp;&nbsp;&nbsp;&nbsp;.setDefaultRuleset(argStyleText, status);</code>
 *    <tr>
 *       <td><code>ordinal</code>
 *       <td><i>argStyleText (optional)</i>
 *       <td><code>new RuleBasedNumberFormat(URBNF_ORDINAL, getLocale(), status)
 *           <br/>&nbsp;&nbsp;&nbsp;&nbsp;.setDefaultRuleset(argStyleText, status);</code>
 *    <tr>
 *       <td><code>duration</code>
 *       <td><i>argStyleText (optional)</i>
 *       <td><code>new RuleBasedNumberFormat(URBNF_DURATION, getLocale(), status)
 *           <br/>&nbsp;&nbsp;&nbsp;&nbsp;.setDefaultRuleset(argStyleText, status);</code>
 * </table>
 * <p>
 *
 * <h4>Argument formatting</h4>
 *
 * <p>Arguments are formatted according to their type, using the default
 * ICU formatters for those types, unless otherwise specified.</p>
 *
 * <p>There are also several ways to control the formatting.</p>
 *
 * <p>We recommend you use default styles, predefined style values, skeletons,
 * or preformatted values, but not pattern strings or custom format objects.</p>
 *
 * <p>For more details, see the
 * <a href="http://userguide.icu-project.org/formatparse/messages">ICU User Guide</a>.</p>
 *
 * <h4>Usage Information</h4>
 *
 * <p>Here are some examples of usage:
 * Example 1:
 *
 * <pre>
 * \code
 *     UErrorCode success = U_ZERO_ERROR;
 *     GregorianCalendar cal(success);
 *     Formattable arguments[] = {
 *         7L,
 *         Formattable( (Date) cal.getTime(success), Formattable::kIsDate),
 *         "a disturbance in the Force"
 *     };
 *
 *     UnicodeString result;
 *     MessageFormat::format(
 *          "At {1,time,::jmm} on {1,date,::dMMMM}, there was {2} on planet {0,number}.",
 *          arguments, 3, result, success );
 *
 *     cout << "result: " << result << endl;
 *     //<output>: At 4:34 PM on March 23, there was a disturbance
 *     //             in the Force on planet 7.
 * \endcode
 * </pre>
 *
 * Typically, the message format will come from resources, and the
 * arguments will be dynamically set at runtime.
 *
 * <p>Example 2:
 *
 * <pre>
 *  \code
 *     success = U_ZERO_ERROR;
 *     Formattable testArgs[] = {3L, "MyDisk"};
 *
 *     MessageFormat form(
 *         "The disk \"{1}\" contains {0} file(s).", success );
 *
 *     UnicodeString string;
 *     FieldPosition fpos = 0;
 *     cout << "format: " << form.format(testArgs, 2, string, fpos, success ) << endl;
 *
 *     // output, with different testArgs:
 *     // output: The disk "MyDisk" contains 0 file(s).
 *     // output: The disk "MyDisk" contains 1 file(s).
 *     // output: The disk "MyDisk" contains 1,273 file(s).
 *  \endcode
 *  </pre>
 *
 *
 * <p>For messages that include plural forms, you can use a plural argument:
 * <pre>
 * \code
 *  success = U_ZERO_ERROR;
 *  MessageFormat msgFmt(
 *       "{num_files, plural, "
 *       "=0{There are no files on disk \"{disk_name}\".}"
 *       "=1{There is one file on disk \"{disk_name}\".}"
 *       "other{There are # files on disk \"{disk_name}\".}}",
 *      Locale("en"),
 *      success);
 *  FieldPosition fpos = 0;
 *  Formattable testArgs[] = {0L, "MyDisk"};
 *  UnicodeString testArgsNames[] = {"num_files", "disk_name"};
 *  UnicodeString result;
 *  cout << msgFmt.format(testArgs, testArgsNames, 2, result, fpos, 0, success);
 *  testArgs[0] = 3L;
 *  cout << msgFmt.format(testArgs, testArgsNames, 2, result, fpos, 0, success);
 * \endcode
 * <em>output</em>:
 * There are no files on disk "MyDisk".
 * There are 3 files on "MyDisk".
 * </pre>
 * See {@link PluralFormat} and {@link PluralRules} for details.
 *
 * <h4><a name="synchronization">Synchronization</a></h4>
 *
 * <p>MessageFormats are not synchronized.
 * It is recommended to create separate format instances for each thread.
 * If multiple threads access a format concurrently, it must be synchronized
 * externally.
 *
 * @stable ICU 2.0
 */
class U_I18N_API MessageFormat : public Format {
public:
#ifndef U_HIDE_OBSOLETE_API
    /**
     * Enum type for kMaxFormat.
     * @obsolete ICU 3.0.  The 10-argument limit was removed as of ICU 2.6,
     * rendering this enum type obsolete.
     */
    enum EFormatNumber {
        /**
         * The maximum number of arguments.
         * @obsolete ICU 3.0.  The 10-argument limit was removed as of ICU 2.6,
         * rendering this constant obsolete.
         */
        kMaxFormat = 10
    };
#endif  /* U_HIDE_OBSOLETE_API */

    /**
     * Constructs a new MessageFormat using the given pattern and the
     * default locale.
     *
     * @param pattern   Pattern used to construct object.
     * @param status    Input/output error code.  If the
     *                  pattern cannot be parsed, set to failure code.
     * @stable ICU 2.0
     */
    MessageFormat(const UnicodeString& pattern,
                  UErrorCode &status);

    /**
     * Constructs a new MessageFormat using the given pattern and locale.
     * @param pattern   Pattern used to construct object.
     * @param newLocale The locale to use for formatting dates and numbers.
     * @param status    Input/output error code.  If the
     *                  pattern cannot be parsed, set to failure code.
     * @stable ICU 2.0
     */
    MessageFormat(const UnicodeString& pattern,
                  const Locale& newLocale,
                        UErrorCode& status);
    /**
     * Constructs a new MessageFormat using the given pattern and locale.
     * @param pattern   Pattern used to construct object.
     * @param newLocale The locale to use for formatting dates and numbers.
     * @param parseError Struct to receive information on the position
     *                   of an error within the pattern.
     * @param status    Input/output error code.  If the
     *                  pattern cannot be parsed, set to failure code.
     * @stable ICU 2.0
     */
    MessageFormat(const UnicodeString& pattern,
                  const Locale& newLocale,
                  UParseError& parseError,
                  UErrorCode& status);
    /**
     * Constructs a new MessageFormat from an existing one.
     * @stable ICU 2.0
     */
    MessageFormat(const MessageFormat&);

    /**
     * Assignment operator.
     * @stable ICU 2.0
     */
    const MessageFormat& operator=(const MessageFormat&);

    /**
     * Destructor.
     * @stable ICU 2.0
     */
    virtual ~MessageFormat();

    /**
     * Clones this Format object polymorphically.  The caller owns the
     * result and should delete it when done.
     * @stable ICU 2.0
     */
    virtual Format* clone(void) const;

    /**
     * Returns true if the given Format objects are semantically equal.
     * Objects of different subclasses are considered unequal.
     * @param other  the object to be compared with.
     * @return       true if the given Format objects are semantically equal.
     * @stable ICU 2.0
     */
    virtual UBool operator==(const Format& other) const;

    /**
     * Sets the locale to be used for creating argument Format objects.
     * @param theLocale    the new locale value to be set.
     * @stable ICU 2.0
     */
    virtual void setLocale(const Locale& theLocale);

    /**
     * Gets the locale used for creating argument Format objects.
     * format information.
     * @return    the locale of the object.
     * @stable ICU 2.0
     */
    virtual const Locale& getLocale(void) const;

    /**
     * Applies the given pattern string to this message format.
     *
     * @param pattern   The pattern to be applied.
     * @param status    Input/output error code.  If the
     *                  pattern cannot be parsed, set to failure code.
     * @stable ICU 2.0
     */
    virtual void applyPattern(const UnicodeString& pattern,
                              UErrorCode& status);
    /**
     * Applies the given pattern string to this message format.
     *
     * @param pattern    The pattern to be applied.
     * @param parseError Struct to receive information on the position
     *                   of an error within the pattern.
     * @param status    Input/output error code.  If the
     *                  pattern cannot be parsed, set to failure code.
     * @stable ICU 2.0
     */
    virtual void applyPattern(const UnicodeString& pattern,
                             UParseError& parseError,
                             UErrorCode& status);

    /**
     * Sets the UMessagePatternApostropheMode and the pattern used by this message format.
     * Parses the pattern and caches Format objects for simple argument types.
     * Patterns and their interpretation are specified in the
     * <a href="#patterns">class description</a>.
     * <p>
     * This method is best used only once on a given object to avoid confusion about the mode,
     * and after constructing the object with an empty pattern string to minimize overhead.
     *
     * @param pattern    The pattern to be applied.
     * @param aposMode   The new apostrophe mode.
     * @param parseError Struct to receive information on the position
     *                   of an error within the pattern.
     *                   Can be NULL.
     * @param status    Input/output error code.  If the
     *                  pattern cannot be parsed, set to failure code.
     * @stable ICU 4.8
     */
    virtual void applyPattern(const UnicodeString& pattern,
                              UMessagePatternApostropheMode aposMode,
                              UParseError* parseError,
                              UErrorCode& status);

    /**
     * @return this instance's UMessagePatternApostropheMode.
     * @stable ICU 4.8
     */
    UMessagePatternApostropheMode getApostropheMode() const {
        return msgPattern.getApostropheMode();
    }

    /**
     * Returns a pattern that can be used to recreate this object.
     *
     * @param appendTo  Output parameter to receive the pattern.
     *                  Result is appended to existing contents.
     * @return          Reference to 'appendTo' parameter.
     * @stable ICU 2.0
     */
    virtual UnicodeString& toPattern(UnicodeString& appendTo) const;

    /**
     * Sets subformats.
     * See the class description about format numbering.
     * The caller should not delete the Format objects after this call.
     * <EM>The array formatsToAdopt is not itself adopted.</EM> Its
     * ownership is retained by the caller. If the call fails because
     * memory cannot be allocated, then the formats will be deleted
     * by this method, and this object will remain unchanged.
     *
     * <p>If this format uses named arguments, the new formats are discarded
     * and this format remains unchanged.
     *
     * @stable ICU 2.0
     * @param formatsToAdopt    the format to be adopted.
     * @param count             the size of the array.
     */
    virtual void adoptFormats(Format** formatsToAdopt, int32_t count);

    /**
     * Sets subformats.
     * See the class description about format numbering.
     * Each item in the array is cloned into the internal array.
     * If the call fails because memory cannot be allocated, then this
     * object will remain unchanged.
     *
     * <p>If this format uses named arguments, the new formats are discarded
     * and this format remains unchanged.
     *
     * @stable ICU 2.0
     * @param newFormats the new format to be set.
     * @param cnt        the size of the array.
     */
    virtual void setFormats(const Format** newFormats, int32_t cnt);


    /**
     * Sets one subformat.
     * See the class description about format numbering.
     * The caller should not delete the Format object after this call.
     * If the number is over the number of formats already set,
     * the item will be deleted and ignored.
     *
     * <p>If this format uses named arguments, the new format is discarded
     * and this format remains unchanged.
     *
     * @stable ICU 2.0
     * @param formatNumber     index of the subformat.
     * @param formatToAdopt    the format to be adopted.
     */
    virtual void adoptFormat(int32_t formatNumber, Format* formatToAdopt);

    /**
     * Sets one subformat.
     * See the class description about format numbering.
     * If the number is over the number of formats already set,
     * the item will be ignored.
     * @param formatNumber     index of the subformat.
     * @param format    the format to be set.
     * @stable ICU 2.0
     */
    virtual void setFormat(int32_t formatNumber, const Format& format);

    /**
     * Gets format names. This function returns formatNames in StringEnumerations
     * which can be used with getFormat() and setFormat() to export formattable
     * array from current MessageFormat to another.  It is the caller's responsibility
     * to delete the returned formatNames.
     * @param status  output param set to success/failure code.
     * @stable ICU 4.0
     */
    virtual StringEnumeration* getFormatNames(UErrorCode& status);

    /**
     * Gets subformat pointer for given format name.
     * This function supports both named and numbered
     * arguments. If numbered, the formatName is the
     * corresponding UnicodeStrings (e.g. "0", "1", "2"...).
     * The returned Format object should not be deleted by the caller,
     * nor should the ponter of other object .  The pointer and its
     * contents remain valid only until the next call to any method
     * of this class is made with this object.
     * @param formatName the name or number specifying a format
     * @param status  output param set to success/failure code.
     * @stable ICU 4.0
     */
    virtual Format* getFormat(const UnicodeString& formatName, UErrorCode& status);

    /**
     * Sets one subformat for given format name.
     * See the class description about format name.
     * This function supports both named and numbered
     * arguments-- if numbered, the formatName is the
     * corresponding UnicodeStrings (e.g. "0", "1", "2"...).
     * If there is no matched formatName or wrong type,
     * the item will be ignored.
     * @param formatName  Name of the subformat.
     * @param format      the format to be set.
     * @param status  output param set to success/failure code.
     * @stable ICU 4.0
     */
    virtual void setFormat(const UnicodeString& formatName, const Format& format, UErrorCode& status);

    /**
     * Sets one subformat for given format name.
     * See the class description about format name.
     * This function supports both named and numbered
     * arguments-- if numbered, the formatName is the
     * corresponding UnicodeStrings (e.g. "0", "1", "2"...).
     * If there is no matched formatName or wrong type,
     * the item will be ignored.
     * The caller should not delete the Format object after this call.
     * @param formatName  Name of the subformat.
     * @param formatToAdopt  Format to be adopted.
     * @param status      output param set to success/failure code.
     * @stable ICU 4.0
     */
    virtual void adoptFormat(const UnicodeString& formatName, Format* formatToAdopt, UErrorCode& status);

    /**
     * Gets an array of subformats of this object.  The returned array
     * should not be deleted by the caller, nor should the pointers
     * within the array.  The array and its contents remain valid only
     * until the next call to this format. See the class description
     * about format numbering.
     *
     * @param count output parameter to receive the size of the array
     * @return an array of count Format* objects, or NULL if out of
     * memory.  Any or all of the array elements may be NULL.
     * @stable ICU 2.0
     */
    virtual const Format** getFormats(int32_t& count) const;


    using Format::format;

    /**
     * Formats the given array of arguments into a user-readable string.
     * Does not take ownership of the Formattable* array or its contents.
     *
     * <p>If this format uses named arguments, appendTo is unchanged and
     * status is set to U_ILLEGAL_ARGUMENT_ERROR.
     *
     * @param source    An array of objects to be formatted.
     * @param count     The number of elements of 'source'.
     * @param appendTo  Output parameter to receive result.
     *                  Result is appended to existing contents.
     * @param ignore    Not used; inherited from base class API.
     * @param status    Input/output error code.  If the
     *                  pattern cannot be parsed, set to failure code.
     * @return          Reference to 'appendTo' parameter.
     * @stable ICU 2.0
     */
    UnicodeString& format(const Formattable* source,
                          int32_t count,
                          UnicodeString& appendTo,
                          FieldPosition& ignore,
                          UErrorCode& status) const;

    /**
     * Formats the given array of arguments into a user-readable string
     * using the given pattern.
     *
     * <p>If this format uses named arguments, appendTo is unchanged and
     * status is set to U_ILLEGAL_ARGUMENT_ERROR.
     *
     * @param pattern   The pattern.
     * @param arguments An array of objects to be formatted.
     * @param count     The number of elements of 'source'.
     * @param appendTo  Output parameter to receive result.
     *                  Result is appended to existing contents.
     * @param status    Input/output error code.  If the
     *                  pattern cannot be parsed, set to failure code.
     * @return          Reference to 'appendTo' parameter.
     * @stable ICU 2.0
     */
    static UnicodeString& format(const UnicodeString& pattern,
                                 const Formattable* arguments,
                                 int32_t count,
                                 UnicodeString& appendTo,
                                 UErrorCode& status);

    /**
     * Formats the given array of arguments into a user-readable
     * string.  The array must be stored within a single Formattable
     * object of type kArray. If the Formattable object type is not of
     * type kArray, then returns a failing UErrorCode.
     *
     * <p>If this format uses named arguments, appendTo is unchanged and
     * status is set to U_ILLEGAL_ARGUMENT_ERROR.
     *
     * @param obj       A Formattable of type kArray containing
     *                  arguments to be formatted.
     * @param appendTo  Output parameter to receive result.
     *                  Result is appended to existing contents.
     * @param pos       On input: an alignment field, if desired.
     *                  On output: the offsets of the alignment field.
     * @param status    Input/output error code.  If the
     *                  pattern cannot be parsed, set to failure code.
     * @return          Reference to 'appendTo' parameter.
     * @stable ICU 2.0
     */
    virtual UnicodeString& format(const Formattable& obj,
                                  UnicodeString& appendTo,
                                  FieldPosition& pos,
                                  UErrorCode& status) const;

    /**
     * Formats the given array of arguments into a user-defined argument name
     * array. This function supports both named and numbered
     * arguments-- if numbered, the formatName is the
     * corresponding UnicodeStrings (e.g. "0", "1", "2"...).
     *
     * @param argumentNames argument name array
     * @param arguments An array of objects to be formatted.
     * @param count     The number of elements of 'argumentNames' and
     *                  arguments.  The number of argumentNames and arguments
     *                  must be the same.
     * @param appendTo  Output parameter to receive result.
     *                  Result is appended to existing contents.
     * @param status    Input/output error code.  If the
     *                  pattern cannot be parsed, set to failure code.
     * @return          Reference to 'appendTo' parameter.
     * @stable ICU 4.0
     */
    UnicodeString& format(const UnicodeString* argumentNames,
                          const Formattable* arguments,
                          int32_t count,
                          UnicodeString& appendTo,
                          UErrorCode& status) const;
    /**
     * Parses the given string into an array of output arguments.
     *
     * @param source    String to be parsed.
     * @param pos       On input, starting position for parse. On output,
     *                  final position after parse.  Unchanged if parse
     *                  fails.
     * @param count     Output parameter to receive the number of arguments
     *                  parsed.
     * @return an array of parsed arguments.  The caller owns both
     * the array and its contents.
     * @stable ICU 2.0
     */
    virtual Formattable* parse(const UnicodeString& source,
                               ParsePosition& pos,
                               int32_t& count) const;

    /**
     * Parses the given string into an array of output arguments.
     *
     * <p>If this format uses named arguments, status is set to
     * U_ARGUMENT_TYPE_MISMATCH.
     *
     * @param source    String to be parsed.
     * @param count     Output param to receive size of returned array.
     * @param status    Input/output error code.  If the
     *                  pattern cannot be parsed, set to failure code.
     * @return an array of parsed arguments.  The caller owns both
     * the array and its contents. Returns NULL if status is not U_ZERO_ERROR.
     *
     * @stable ICU 2.0
     */
    virtual Formattable* parse(const UnicodeString& source,
                               int32_t& count,
                               UErrorCode& status) const;

    /**
     * Parses the given string into an array of output arguments
     * stored within a single Formattable of type kArray.
     *
     * @param source    The string to be parsed into an object.
     * @param result    Formattable to be set to the parse result.
     *                  If parse fails, return contents are undefined.
     * @param pos       On input, starting position for parse. On output,
     *                  final position after parse.  Unchanged if parse
     *                  fails.
     * @stable ICU 2.0
     */
    virtual void parseObject(const UnicodeString& source,
                             Formattable& result,
                             ParsePosition& pos) const;

    /**
     * Convert an 'apostrophe-friendly' pattern into a standard
     * pattern.  Standard patterns treat all apostrophes as
     * quotes, which is problematic in some languages, e.g.
     * French, where apostrophe is commonly used.  This utility
     * assumes that only an unpaired apostrophe immediately before
     * a brace is a true quote.  Other unpaired apostrophes are paired,
     * and the resulting standard pattern string is returned.
     *
     * <p><b>Note</b> it is not guaranteed that the returned pattern
     * is indeed a valid pattern.  The only effect is to convert
     * between patterns having different quoting semantics.
     *
     * @param pattern the 'apostrophe-friendly' patttern to convert
     * @param status    Input/output error code.  If the pattern
     *                  cannot be parsed, the failure code is set.
     * @return the standard equivalent of the original pattern
     * @stable ICU 3.4
     */
    static UnicodeString autoQuoteApostrophe(const UnicodeString& pattern,
        UErrorCode& status);


    /**
     * Returns true if this MessageFormat uses named arguments,
     * and false otherwise.  See class description.
     *
     * @return true if named arguments are used.
     * @stable ICU 4.0
     */
    UBool usesNamedArguments() const;


#ifndef U_HIDE_INTERNAL_API
    /**
     * This API is for ICU internal use only.
     * Please do not use it.
     *
     * Returns argument types count in the parsed pattern.
     * Used to distinguish pattern "{0} d" and "d".
     *
     * @return           The number of formattable types in the pattern
     * @internal
     */
    int32_t getArgTypeCount() const;
#endif  /* U_HIDE_INTERNAL_API */

    /**
     * Returns a unique class ID POLYMORPHICALLY.  Pure virtual override.
     * This method is to implement a simple version of RTTI, since not all
     * C++ compilers support genuine RTTI.  Polymorphic operator==() and
     * clone() methods call this method.
     *
     * @return          The class ID for this object. All objects of a
     *                  given class have the same class ID.  Objects of
     *                  other classes have different class IDs.
     * @stable ICU 2.0
     */
    virtual UClassID getDynamicClassID(void) const;

    /**
     * Return the class ID for this class.  This is useful only for
     * comparing to a return value from getDynamicClassID().  For example:
     * <pre>
     * .   Base* polymorphic_pointer = createPolymorphicObject();
     * .   if (polymorphic_pointer->getDynamicClassID() ==
     * .      Derived::getStaticClassID()) ...
     * </pre>
     * @return          The class ID for all objects of this class.
     * @stable ICU 2.0
     */
    static UClassID U_EXPORT2 getStaticClassID(void);

#ifndef U_HIDE_INTERNAL_API
    /**
     * Compares two Format objects. This is used for constructing the hash
     * tables.
     *
     * @param left pointer to a Format object. Must not be NULL.
     * @param right pointer to a Format object. Must not be NULL.
     *
     * @return whether the two objects are the same
     * @internal
     */
    static UBool equalFormats(const void* left, const void* right);
#endif  /* U_HIDE_INTERNAL_API */

private:

    Locale              fLocale;
    MessagePattern      msgPattern;
    Format**            formatAliases; // see getFormats
    int32_t             formatAliasesCapacity;

    MessageFormat(); // default constructor not implemented

     /**
      * This provider helps defer instantiation of a PluralRules object
      * until we actually need to select a keyword.
      * For example, if the number matches an explicit-value selector like "=1"
      * we do not need any PluralRules.
      */
    class U_I18N_API PluralSelectorProvider : public PluralFormat::PluralSelector {
    public:
        PluralSelectorProvider(const MessageFormat &mf, UPluralType type);
        virtual ~PluralSelectorProvider();
        virtual UnicodeString select(void *ctx, double number, UErrorCode& ec) const;

        void reset();
    private:
        const MessageFormat &msgFormat;
        PluralRules* rules;
        UPluralType type;
    };

    /**
     * A MessageFormat formats an array of arguments.  Each argument
     * has an expected type, based on the pattern.  For example, if
     * the pattern contains the subformat "{3,number,integer}", then
     * we expect argument 3 to have type Formattable::kLong.  This
     * array needs to grow dynamically if the MessageFormat is
     * modified.
     */
    Formattable::Type* argTypes;
    int32_t            argTypeCount;
    int32_t            argTypeCapacity;

    /**
     * TRUE if there are different argTypes for the same argument.
     * This only matters when the MessageFormat is used in the plain C (umsg_xxx) API
     * where the pattern argTypes determine how the va_arg list is read.
     */
    UBool hasArgTypeConflicts;

    // Variable-size array management
    UBool allocateArgTypes(int32_t capacity, UErrorCode& status);

    /**
     * Default Format objects used when no format is specified and a
     * numeric or date argument is formatted.  These are volatile
     * cache objects maintained only for performance.  They do not
     * participate in operator=(), copy constructor(), nor
     * operator==().
     */
    NumberFormat* defaultNumberFormat;
    DateFormat*   defaultDateFormat;

    UHashtable* cachedFormatters;
    UHashtable* customFormatArgStarts;

    PluralSelectorProvider pluralProvider;
    PluralSelectorProvider ordinalProvider;

    /**
     * Method to retrieve default formats (or NULL on failure).
     * These are semantically const, but may modify *this.
     */
    const NumberFormat* getDefaultNumberFormat(UErrorCode&) const;
    const DateFormat*   getDefaultDateFormat(UErrorCode&) const;

    /**
     * Finds the word s, in the keyword list and returns the located index.
     * @param s the keyword to be searched for.
     * @param list the list of keywords to be searched with.
     * @return the index of the list which matches the keyword s.
     */
    static int32_t findKeyword( const UnicodeString& s,
                                const char16_t * const *list);

    /**
     * Thin wrapper around the format(... AppendableWrapper ...) variant.
     * Wraps the destination UnicodeString into an AppendableWrapper and
     * supplies default values for some other parameters.
     */
    UnicodeString& format(const Formattable* arguments,
                          const UnicodeString *argumentNames,
                          int32_t cnt,
                          UnicodeString& appendTo,
                          FieldPosition* pos,
                          UErrorCode& status) const;

    /**
     * Formats the arguments and writes the result into the
     * AppendableWrapper, updates the field position.
     *
     * @param msgStart      Index to msgPattern part to start formatting from.
     * @param plNumber      NULL except when formatting a plural argument sub-message
     *                      where a '#' is replaced by the format string for this number.
     * @param arguments     The formattable objects array. (Must not be NULL.)
     * @param argumentNames NULL if numbered values are used. Otherwise the same
     *                      length as "arguments", and each entry is the name of the
     *                      corresponding argument in "arguments".
     * @param cnt           The length of arguments (and of argumentNames if that is not NULL).
     * @param appendTo      Output parameter to receive the result.
     *                      The result string is appended to existing contents.
     * @param pos           Field position status.
     * @param success       The error code status.
     */
    void format(int32_t msgStart,
                const void *plNumber,
                const Formattable* arguments,
                const UnicodeString *argumentNames,
                int32_t cnt,
                AppendableWrapper& appendTo,
                FieldPosition* pos,
                UErrorCode& success) const;

    UnicodeString getArgName(int32_t partIndex);

    void setArgStartFormat(int32_t argStart, Format* formatter, UErrorCode& status);

    void setCustomArgStartFormat(int32_t argStart, Format* formatter, UErrorCode& status);

    int32_t nextTopLevelArgStart(int32_t partIndex) const;

    UBool argNameMatches(int32_t partIndex, const UnicodeString& argName, int32_t argNumber);

    void cacheExplicitFormats(UErrorCode& status);

    int32_t skipLeadingSpaces(UnicodeString& style);

    Format* createAppropriateFormat(UnicodeString& type,
                                    UnicodeString& style,
                                    Formattable::Type& formattableType,
                                    UParseError& parseError,
                                    UErrorCode& ec);

    const Formattable* getArgFromListByName(const Formattable* arguments,
                                            const UnicodeString *argumentNames,
                                            int32_t cnt, UnicodeString& name) const;

    Formattable* parse(int32_t msgStart,
                       const UnicodeString& source,
                       ParsePosition& pos,
                       int32_t& count,
                       UErrorCode& ec) const;

    FieldPosition* updateMetaData(AppendableWrapper& dest, int32_t prevLength,
                                  FieldPosition* fp, const Formattable* argId) const;

    /**
     * Finds the "other" sub-message.
     * @param partIndex the index of the first PluralFormat argument style part.
     * @return the "other" sub-message start part index.
     */
    int32_t findOtherSubMessage(int32_t partIndex) const;

    /**
     * Returns the ARG_START index of the first occurrence of the plural number in a sub-message.
     * Returns -1 if it is a REPLACE_NUMBER.
     * Returns 0 if there is neither.
     */
    int32_t findFirstPluralNumberArg(int32_t msgStart, const UnicodeString &argName) const;

    Format* getCachedFormatter(int32_t argumentNumber) const;

    UnicodeString getLiteralStringUntilNextArgument(int32_t from) const;

    void copyObjects(const MessageFormat& that, UErrorCode& ec);

    void formatComplexSubMessage(int32_t msgStart,
                                 const void *plNumber,
                                 const Formattable* arguments,
                                 const UnicodeString *argumentNames,
                                 int32_t cnt,
                                 AppendableWrapper& appendTo,
                                 UErrorCode& success) const;

    /**
     * Convenience method that ought to be in NumberFormat
     */
    NumberFormat* createIntegerFormat(const Locale& locale, UErrorCode& status) const;

    /**
     * Returns array of argument types in the parsed pattern
     * for use in C API.  Only for the use of umsg_vformat().  Not
     * for public consumption.
     * @param listCount  Output parameter to receive the size of array
     * @return           The array of formattable types in the pattern
     */
    const Formattable::Type* getArgTypeList(int32_t& listCount) const {
        listCount = argTypeCount;
        return argTypes;
    }

    /**
     * Resets the internal MessagePattern, and other associated caches.
     */
    void resetPattern();

    /**
     * A DummyFormatter that we use solely to store a NULL value. UHash does
     * not support storing NULL values.
     */
    class U_I18N_API DummyFormat : public Format {
    public:
        virtual UBool operator==(const Format&) const;
        virtual Format* clone() const;
        virtual UnicodeString& format(const Formattable& obj,
                              UnicodeString& appendTo,
                              UErrorCode& status) const;
        virtual UnicodeString& format(const Formattable&,
                                      UnicodeString& appendTo,
                                      FieldPosition&,
                                      UErrorCode& status) const;
        virtual UnicodeString& format(const Formattable& obj,
                                      UnicodeString& appendTo,
                                      FieldPositionIterator* posIter,
                                      UErrorCode& status) const;
        virtual void parseObject(const UnicodeString&,
                                 Formattable&,
                                 ParsePosition&) const;
    };

    friend class MessageFormatAdapter; // getFormatTypeList() access
};

U_NAMESPACE_END

#endif /* #if !UCONFIG_NO_FORMATTING */

#endif // _MSGFMT
//eof
