annotate CSP2/CSP2_env/env-d9b9114564458d9d-741b3de822f2aaca6c6caa4325c4afce/include/unicode/messagepattern.h @ 69:33d812a61356

planemo upload commit 2e9511a184a1ca667c7be0c6321a36dc4e3d116d
author jpayne
date Tue, 18 Mar 2025 17:55:14 -0400
parents
children
rev   line source
jpayne@69 1 // © 2016 and later: Unicode, Inc. and others.
jpayne@69 2 // License & terms of use: http://www.unicode.org/copyright.html
jpayne@69 3 /*
jpayne@69 4 *******************************************************************************
jpayne@69 5 * Copyright (C) 2011-2013, International Business Machines
jpayne@69 6 * Corporation and others. All Rights Reserved.
jpayne@69 7 *******************************************************************************
jpayne@69 8 * file name: messagepattern.h
jpayne@69 9 * encoding: UTF-8
jpayne@69 10 * tab size: 8 (not used)
jpayne@69 11 * indentation:4
jpayne@69 12 *
jpayne@69 13 * created on: 2011mar14
jpayne@69 14 * created by: Markus W. Scherer
jpayne@69 15 */
jpayne@69 16
jpayne@69 17 #ifndef __MESSAGEPATTERN_H__
jpayne@69 18 #define __MESSAGEPATTERN_H__
jpayne@69 19
jpayne@69 20 /**
jpayne@69 21 * \file
jpayne@69 22 * \brief C++ API: MessagePattern class: Parses and represents ICU MessageFormat patterns.
jpayne@69 23 */
jpayne@69 24
jpayne@69 25 #include "unicode/utypes.h"
jpayne@69 26
jpayne@69 27 #if U_SHOW_CPLUSPLUS_API
jpayne@69 28
jpayne@69 29 #if !UCONFIG_NO_FORMATTING
jpayne@69 30
jpayne@69 31 #include "unicode/parseerr.h"
jpayne@69 32 #include "unicode/unistr.h"
jpayne@69 33
jpayne@69 34 /**
jpayne@69 35 * Mode for when an apostrophe starts quoted literal text for MessageFormat output.
jpayne@69 36 * The default is DOUBLE_OPTIONAL unless overridden via uconfig.h
jpayne@69 37 * (UCONFIG_MSGPAT_DEFAULT_APOSTROPHE_MODE).
jpayne@69 38 * <p>
jpayne@69 39 * A pair of adjacent apostrophes always results in a single apostrophe in the output,
jpayne@69 40 * even when the pair is between two single, text-quoting apostrophes.
jpayne@69 41 * <p>
jpayne@69 42 * The following table shows examples of desired MessageFormat.format() output
jpayne@69 43 * with the pattern strings that yield that output.
jpayne@69 44 * <p>
jpayne@69 45 * <table>
jpayne@69 46 * <tr>
jpayne@69 47 * <th>Desired output</th>
jpayne@69 48 * <th>DOUBLE_OPTIONAL</th>
jpayne@69 49 * <th>DOUBLE_REQUIRED</th>
jpayne@69 50 * </tr>
jpayne@69 51 * <tr>
jpayne@69 52 * <td>I see {many}</td>
jpayne@69 53 * <td>I see '{many}'</td>
jpayne@69 54 * <td>(same)</td>
jpayne@69 55 * </tr>
jpayne@69 56 * <tr>
jpayne@69 57 * <td>I said {'Wow!'}</td>
jpayne@69 58 * <td>I said '{''Wow!''}'</td>
jpayne@69 59 * <td>(same)</td>
jpayne@69 60 * </tr>
jpayne@69 61 * <tr>
jpayne@69 62 * <td>I don't know</td>
jpayne@69 63 * <td>I don't know OR<br> I don''t know</td>
jpayne@69 64 * <td>I don''t know</td>
jpayne@69 65 * </tr>
jpayne@69 66 * </table>
jpayne@69 67 * @stable ICU 4.8
jpayne@69 68 * @see UCONFIG_MSGPAT_DEFAULT_APOSTROPHE_MODE
jpayne@69 69 */
jpayne@69 70 enum UMessagePatternApostropheMode {
jpayne@69 71 /**
jpayne@69 72 * A literal apostrophe is represented by
jpayne@69 73 * either a single or a double apostrophe pattern character.
jpayne@69 74 * Within a MessageFormat pattern, a single apostrophe only starts quoted literal text
jpayne@69 75 * if it immediately precedes a curly brace {},
jpayne@69 76 * or a pipe symbol | if inside a choice format,
jpayne@69 77 * or a pound symbol # if inside a plural format.
jpayne@69 78 * <p>
jpayne@69 79 * This is the default behavior starting with ICU 4.8.
jpayne@69 80 * @stable ICU 4.8
jpayne@69 81 */
jpayne@69 82 UMSGPAT_APOS_DOUBLE_OPTIONAL,
jpayne@69 83 /**
jpayne@69 84 * A literal apostrophe must be represented by
jpayne@69 85 * a double apostrophe pattern character.
jpayne@69 86 * A single apostrophe always starts quoted literal text.
jpayne@69 87 * <p>
jpayne@69 88 * This is the behavior of ICU 4.6 and earlier, and of the JDK.
jpayne@69 89 * @stable ICU 4.8
jpayne@69 90 */
jpayne@69 91 UMSGPAT_APOS_DOUBLE_REQUIRED
jpayne@69 92 };
jpayne@69 93 /**
jpayne@69 94 * @stable ICU 4.8
jpayne@69 95 */
jpayne@69 96 typedef enum UMessagePatternApostropheMode UMessagePatternApostropheMode;
jpayne@69 97
jpayne@69 98 /**
jpayne@69 99 * MessagePattern::Part type constants.
jpayne@69 100 * @stable ICU 4.8
jpayne@69 101 */
jpayne@69 102 enum UMessagePatternPartType {
jpayne@69 103 /**
jpayne@69 104 * Start of a message pattern (main or nested).
jpayne@69 105 * The length is 0 for the top-level message
jpayne@69 106 * and for a choice argument sub-message, otherwise 1 for the '{'.
jpayne@69 107 * The value indicates the nesting level, starting with 0 for the main message.
jpayne@69 108 * <p>
jpayne@69 109 * There is always a later MSG_LIMIT part.
jpayne@69 110 * @stable ICU 4.8
jpayne@69 111 */
jpayne@69 112 UMSGPAT_PART_TYPE_MSG_START,
jpayne@69 113 /**
jpayne@69 114 * End of a message pattern (main or nested).
jpayne@69 115 * The length is 0 for the top-level message and
jpayne@69 116 * the last sub-message of a choice argument,
jpayne@69 117 * otherwise 1 for the '}' or (in a choice argument style) the '|'.
jpayne@69 118 * The value indicates the nesting level, starting with 0 for the main message.
jpayne@69 119 * @stable ICU 4.8
jpayne@69 120 */
jpayne@69 121 UMSGPAT_PART_TYPE_MSG_LIMIT,
jpayne@69 122 /**
jpayne@69 123 * Indicates a substring of the pattern string which is to be skipped when formatting.
jpayne@69 124 * For example, an apostrophe that begins or ends quoted text
jpayne@69 125 * would be indicated with such a part.
jpayne@69 126 * The value is undefined and currently always 0.
jpayne@69 127 * @stable ICU 4.8
jpayne@69 128 */
jpayne@69 129 UMSGPAT_PART_TYPE_SKIP_SYNTAX,
jpayne@69 130 /**
jpayne@69 131 * Indicates that a syntax character needs to be inserted for auto-quoting.
jpayne@69 132 * The length is 0.
jpayne@69 133 * The value is the character code of the insertion character. (U+0027=APOSTROPHE)
jpayne@69 134 * @stable ICU 4.8
jpayne@69 135 */
jpayne@69 136 UMSGPAT_PART_TYPE_INSERT_CHAR,
jpayne@69 137 /**
jpayne@69 138 * Indicates a syntactic (non-escaped) # symbol in a plural variant.
jpayne@69 139 * When formatting, replace this part's substring with the
jpayne@69 140 * (value-offset) for the plural argument value.
jpayne@69 141 * The value is undefined and currently always 0.
jpayne@69 142 * @stable ICU 4.8
jpayne@69 143 */
jpayne@69 144 UMSGPAT_PART_TYPE_REPLACE_NUMBER,
jpayne@69 145 /**
jpayne@69 146 * Start of an argument.
jpayne@69 147 * The length is 1 for the '{'.
jpayne@69 148 * The value is the ordinal value of the ArgType. Use getArgType().
jpayne@69 149 * <p>
jpayne@69 150 * This part is followed by either an ARG_NUMBER or ARG_NAME,
jpayne@69 151 * followed by optional argument sub-parts (see UMessagePatternArgType constants)
jpayne@69 152 * and finally an ARG_LIMIT part.
jpayne@69 153 * @stable ICU 4.8
jpayne@69 154 */
jpayne@69 155 UMSGPAT_PART_TYPE_ARG_START,
jpayne@69 156 /**
jpayne@69 157 * End of an argument.
jpayne@69 158 * The length is 1 for the '}'.
jpayne@69 159 * The value is the ordinal value of the ArgType. Use getArgType().
jpayne@69 160 * @stable ICU 4.8
jpayne@69 161 */
jpayne@69 162 UMSGPAT_PART_TYPE_ARG_LIMIT,
jpayne@69 163 /**
jpayne@69 164 * The argument number, provided by the value.
jpayne@69 165 * @stable ICU 4.8
jpayne@69 166 */
jpayne@69 167 UMSGPAT_PART_TYPE_ARG_NUMBER,
jpayne@69 168 /**
jpayne@69 169 * The argument name.
jpayne@69 170 * The value is undefined and currently always 0.
jpayne@69 171 * @stable ICU 4.8
jpayne@69 172 */
jpayne@69 173 UMSGPAT_PART_TYPE_ARG_NAME,
jpayne@69 174 /**
jpayne@69 175 * The argument type.
jpayne@69 176 * The value is undefined and currently always 0.
jpayne@69 177 * @stable ICU 4.8
jpayne@69 178 */
jpayne@69 179 UMSGPAT_PART_TYPE_ARG_TYPE,
jpayne@69 180 /**
jpayne@69 181 * The argument style text.
jpayne@69 182 * The value is undefined and currently always 0.
jpayne@69 183 * @stable ICU 4.8
jpayne@69 184 */
jpayne@69 185 UMSGPAT_PART_TYPE_ARG_STYLE,
jpayne@69 186 /**
jpayne@69 187 * A selector substring in a "complex" argument style.
jpayne@69 188 * The value is undefined and currently always 0.
jpayne@69 189 * @stable ICU 4.8
jpayne@69 190 */
jpayne@69 191 UMSGPAT_PART_TYPE_ARG_SELECTOR,
jpayne@69 192 /**
jpayne@69 193 * An integer value, for example the offset or an explicit selector value
jpayne@69 194 * in a PluralFormat style.
jpayne@69 195 * The part value is the integer value.
jpayne@69 196 * @stable ICU 4.8
jpayne@69 197 */
jpayne@69 198 UMSGPAT_PART_TYPE_ARG_INT,
jpayne@69 199 /**
jpayne@69 200 * A numeric value, for example the offset or an explicit selector value
jpayne@69 201 * in a PluralFormat style.
jpayne@69 202 * The part value is an index into an internal array of numeric values;
jpayne@69 203 * use getNumericValue().
jpayne@69 204 * @stable ICU 4.8
jpayne@69 205 */
jpayne@69 206 UMSGPAT_PART_TYPE_ARG_DOUBLE
jpayne@69 207 };
jpayne@69 208 /**
jpayne@69 209 * @stable ICU 4.8
jpayne@69 210 */
jpayne@69 211 typedef enum UMessagePatternPartType UMessagePatternPartType;
jpayne@69 212
jpayne@69 213 /**
jpayne@69 214 * Argument type constants.
jpayne@69 215 * Returned by Part.getArgType() for ARG_START and ARG_LIMIT parts.
jpayne@69 216 *
jpayne@69 217 * Messages nested inside an argument are each delimited by MSG_START and MSG_LIMIT,
jpayne@69 218 * with a nesting level one greater than the surrounding message.
jpayne@69 219 * @stable ICU 4.8
jpayne@69 220 */
jpayne@69 221 enum UMessagePatternArgType {
jpayne@69 222 /**
jpayne@69 223 * The argument has no specified type.
jpayne@69 224 * @stable ICU 4.8
jpayne@69 225 */
jpayne@69 226 UMSGPAT_ARG_TYPE_NONE,
jpayne@69 227 /**
jpayne@69 228 * The argument has a "simple" type which is provided by the ARG_TYPE part.
jpayne@69 229 * An ARG_STYLE part might follow that.
jpayne@69 230 * @stable ICU 4.8
jpayne@69 231 */
jpayne@69 232 UMSGPAT_ARG_TYPE_SIMPLE,
jpayne@69 233 /**
jpayne@69 234 * The argument is a ChoiceFormat with one or more
jpayne@69 235 * ((ARG_INT | ARG_DOUBLE), ARG_SELECTOR, message) tuples.
jpayne@69 236 * @stable ICU 4.8
jpayne@69 237 */
jpayne@69 238 UMSGPAT_ARG_TYPE_CHOICE,
jpayne@69 239 /**
jpayne@69 240 * The argument is a cardinal-number PluralFormat with an optional ARG_INT or ARG_DOUBLE offset
jpayne@69 241 * (e.g., offset:1)
jpayne@69 242 * and one or more (ARG_SELECTOR [explicit-value] message) tuples.
jpayne@69 243 * If the selector has an explicit value (e.g., =2), then
jpayne@69 244 * that value is provided by the ARG_INT or ARG_DOUBLE part preceding the message.
jpayne@69 245 * Otherwise the message immediately follows the ARG_SELECTOR.
jpayne@69 246 * @stable ICU 4.8
jpayne@69 247 */
jpayne@69 248 UMSGPAT_ARG_TYPE_PLURAL,
jpayne@69 249 /**
jpayne@69 250 * The argument is a SelectFormat with one or more (ARG_SELECTOR, message) pairs.
jpayne@69 251 * @stable ICU 4.8
jpayne@69 252 */
jpayne@69 253 UMSGPAT_ARG_TYPE_SELECT,
jpayne@69 254 /**
jpayne@69 255 * The argument is an ordinal-number PluralFormat
jpayne@69 256 * with the same style parts sequence and semantics as UMSGPAT_ARG_TYPE_PLURAL.
jpayne@69 257 * @stable ICU 50
jpayne@69 258 */
jpayne@69 259 UMSGPAT_ARG_TYPE_SELECTORDINAL
jpayne@69 260 };
jpayne@69 261 /**
jpayne@69 262 * @stable ICU 4.8
jpayne@69 263 */
jpayne@69 264 typedef enum UMessagePatternArgType UMessagePatternArgType;
jpayne@69 265
jpayne@69 266 /**
jpayne@69 267 * \def UMSGPAT_ARG_TYPE_HAS_PLURAL_STYLE
jpayne@69 268 * Returns TRUE if the argument type has a plural style part sequence and semantics,
jpayne@69 269 * for example UMSGPAT_ARG_TYPE_PLURAL and UMSGPAT_ARG_TYPE_SELECTORDINAL.
jpayne@69 270 * @stable ICU 50
jpayne@69 271 */
jpayne@69 272 #define UMSGPAT_ARG_TYPE_HAS_PLURAL_STYLE(argType) \
jpayne@69 273 ((argType)==UMSGPAT_ARG_TYPE_PLURAL || (argType)==UMSGPAT_ARG_TYPE_SELECTORDINAL)
jpayne@69 274
jpayne@69 275 enum {
jpayne@69 276 /**
jpayne@69 277 * Return value from MessagePattern.validateArgumentName() for when
jpayne@69 278 * the string is a valid "pattern identifier" but not a number.
jpayne@69 279 * @stable ICU 4.8
jpayne@69 280 */
jpayne@69 281 UMSGPAT_ARG_NAME_NOT_NUMBER=-1,
jpayne@69 282
jpayne@69 283 /**
jpayne@69 284 * Return value from MessagePattern.validateArgumentName() for when
jpayne@69 285 * the string is invalid.
jpayne@69 286 * It might not be a valid "pattern identifier",
jpayne@69 287 * or it have only ASCII digits but there is a leading zero or the number is too large.
jpayne@69 288 * @stable ICU 4.8
jpayne@69 289 */
jpayne@69 290 UMSGPAT_ARG_NAME_NOT_VALID=-2
jpayne@69 291 };
jpayne@69 292
jpayne@69 293 /**
jpayne@69 294 * Special value that is returned by getNumericValue(Part) when no
jpayne@69 295 * numeric value is defined for a part.
jpayne@69 296 * @see MessagePattern.getNumericValue()
jpayne@69 297 * @stable ICU 4.8
jpayne@69 298 */
jpayne@69 299 #define UMSGPAT_NO_NUMERIC_VALUE ((double)(-123456789))
jpayne@69 300
jpayne@69 301 U_NAMESPACE_BEGIN
jpayne@69 302
jpayne@69 303 class MessagePatternDoubleList;
jpayne@69 304 class MessagePatternPartsList;
jpayne@69 305
jpayne@69 306 /**
jpayne@69 307 * Parses and represents ICU MessageFormat patterns.
jpayne@69 308 * Also handles patterns for ChoiceFormat, PluralFormat and SelectFormat.
jpayne@69 309 * Used in the implementations of those classes as well as in tools
jpayne@69 310 * for message validation, translation and format conversion.
jpayne@69 311 * <p>
jpayne@69 312 * The parser handles all syntax relevant for identifying message arguments.
jpayne@69 313 * This includes "complex" arguments whose style strings contain
jpayne@69 314 * nested MessageFormat pattern substrings.
jpayne@69 315 * For "simple" arguments (with no nested MessageFormat pattern substrings),
jpayne@69 316 * the argument style is not parsed any further.
jpayne@69 317 * <p>
jpayne@69 318 * The parser handles named and numbered message arguments and allows both in one message.
jpayne@69 319 * <p>
jpayne@69 320 * Once a pattern has been parsed successfully, iterate through the parsed data
jpayne@69 321 * with countParts(), getPart() and related methods.
jpayne@69 322 * <p>
jpayne@69 323 * The data logically represents a parse tree, but is stored and accessed
jpayne@69 324 * as a list of "parts" for fast and simple parsing and to minimize object allocations.
jpayne@69 325 * Arguments and nested messages are best handled via recursion.
jpayne@69 326 * For every _START "part", MessagePattern.getLimitPartIndex() efficiently returns
jpayne@69 327 * the index of the corresponding _LIMIT "part".
jpayne@69 328 * <p>
jpayne@69 329 * List of "parts":
jpayne@69 330 * <pre>
jpayne@69 331 * message = MSG_START (SKIP_SYNTAX | INSERT_CHAR | REPLACE_NUMBER | argument)* MSG_LIMIT
jpayne@69 332 * argument = noneArg | simpleArg | complexArg
jpayne@69 333 * complexArg = choiceArg | pluralArg | selectArg
jpayne@69 334 *
jpayne@69 335 * noneArg = ARG_START.NONE (ARG_NAME | ARG_NUMBER) ARG_LIMIT.NONE
jpayne@69 336 * simpleArg = ARG_START.SIMPLE (ARG_NAME | ARG_NUMBER) ARG_TYPE [ARG_STYLE] ARG_LIMIT.SIMPLE
jpayne@69 337 * choiceArg = ARG_START.CHOICE (ARG_NAME | ARG_NUMBER) choiceStyle ARG_LIMIT.CHOICE
jpayne@69 338 * pluralArg = ARG_START.PLURAL (ARG_NAME | ARG_NUMBER) pluralStyle ARG_LIMIT.PLURAL
jpayne@69 339 * selectArg = ARG_START.SELECT (ARG_NAME | ARG_NUMBER) selectStyle ARG_LIMIT.SELECT
jpayne@69 340 *
jpayne@69 341 * choiceStyle = ((ARG_INT | ARG_DOUBLE) ARG_SELECTOR message)+
jpayne@69 342 * pluralStyle = [ARG_INT | ARG_DOUBLE] (ARG_SELECTOR [ARG_INT | ARG_DOUBLE] message)+
jpayne@69 343 * selectStyle = (ARG_SELECTOR message)+
jpayne@69 344 * </pre>
jpayne@69 345 * <ul>
jpayne@69 346 * <li>Literal output text is not represented directly by "parts" but accessed
jpayne@69 347 * between parts of a message, from one part's getLimit() to the next part's getIndex().
jpayne@69 348 * <li><code>ARG_START.CHOICE</code> stands for an ARG_START Part with ArgType CHOICE.
jpayne@69 349 * <li>In the choiceStyle, the ARG_SELECTOR has the '<', the '#' or
jpayne@69 350 * the less-than-or-equal-to sign (U+2264).
jpayne@69 351 * <li>In the pluralStyle, the first, optional numeric Part has the "offset:" value.
jpayne@69 352 * The optional numeric Part between each (ARG_SELECTOR, message) pair
jpayne@69 353 * is the value of an explicit-number selector like "=2",
jpayne@69 354 * otherwise the selector is a non-numeric identifier.
jpayne@69 355 * <li>The REPLACE_NUMBER Part can occur only in an immediate sub-message of the pluralStyle.
jpayne@69 356 * </ul>
jpayne@69 357 * <p>
jpayne@69 358 * This class is not intended for public subclassing.
jpayne@69 359 *
jpayne@69 360 * @stable ICU 4.8
jpayne@69 361 */
jpayne@69 362 class U_COMMON_API MessagePattern : public UObject {
jpayne@69 363 public:
jpayne@69 364 /**
jpayne@69 365 * Constructs an empty MessagePattern with default UMessagePatternApostropheMode.
jpayne@69 366 * @param errorCode Standard ICU error code. Its input value must
jpayne@69 367 * pass the U_SUCCESS() test, or else the function returns
jpayne@69 368 * immediately. Check for U_FAILURE() on output or use with
jpayne@69 369 * function chaining. (See User Guide for details.)
jpayne@69 370 * @stable ICU 4.8
jpayne@69 371 */
jpayne@69 372 MessagePattern(UErrorCode &errorCode);
jpayne@69 373
jpayne@69 374 /**
jpayne@69 375 * Constructs an empty MessagePattern.
jpayne@69 376 * @param mode Explicit UMessagePatternApostropheMode.
jpayne@69 377 * @param errorCode Standard ICU error code. Its input value must
jpayne@69 378 * pass the U_SUCCESS() test, or else the function returns
jpayne@69 379 * immediately. Check for U_FAILURE() on output or use with
jpayne@69 380 * function chaining. (See User Guide for details.)
jpayne@69 381 * @stable ICU 4.8
jpayne@69 382 */
jpayne@69 383 MessagePattern(UMessagePatternApostropheMode mode, UErrorCode &errorCode);
jpayne@69 384
jpayne@69 385 /**
jpayne@69 386 * Constructs a MessagePattern with default UMessagePatternApostropheMode and
jpayne@69 387 * parses the MessageFormat pattern string.
jpayne@69 388 * @param pattern a MessageFormat pattern string
jpayne@69 389 * @param parseError Struct to receive information on the position
jpayne@69 390 * of an error within the pattern.
jpayne@69 391 * Can be NULL.
jpayne@69 392 * @param errorCode Standard ICU error code. Its input value must
jpayne@69 393 * pass the U_SUCCESS() test, or else the function returns
jpayne@69 394 * immediately. Check for U_FAILURE() on output or use with
jpayne@69 395 * function chaining. (See User Guide for details.)
jpayne@69 396 * TODO: turn @throws into UErrorCode specifics?
jpayne@69 397 * @throws IllegalArgumentException for syntax errors in the pattern string
jpayne@69 398 * @throws IndexOutOfBoundsException if certain limits are exceeded
jpayne@69 399 * (e.g., argument number too high, argument name too long, etc.)
jpayne@69 400 * @throws NumberFormatException if a number could not be parsed
jpayne@69 401 * @stable ICU 4.8
jpayne@69 402 */
jpayne@69 403 MessagePattern(const UnicodeString &pattern, UParseError *parseError, UErrorCode &errorCode);
jpayne@69 404
jpayne@69 405 /**
jpayne@69 406 * Copy constructor.
jpayne@69 407 * @param other Object to copy.
jpayne@69 408 * @stable ICU 4.8
jpayne@69 409 */
jpayne@69 410 MessagePattern(const MessagePattern &other);
jpayne@69 411
jpayne@69 412 /**
jpayne@69 413 * Assignment operator.
jpayne@69 414 * @param other Object to copy.
jpayne@69 415 * @return *this=other
jpayne@69 416 * @stable ICU 4.8
jpayne@69 417 */
jpayne@69 418 MessagePattern &operator=(const MessagePattern &other);
jpayne@69 419
jpayne@69 420 /**
jpayne@69 421 * Destructor.
jpayne@69 422 * @stable ICU 4.8
jpayne@69 423 */
jpayne@69 424 virtual ~MessagePattern();
jpayne@69 425
jpayne@69 426 /**
jpayne@69 427 * Parses a MessageFormat pattern string.
jpayne@69 428 * @param pattern a MessageFormat pattern string
jpayne@69 429 * @param parseError Struct to receive information on the position
jpayne@69 430 * of an error within the pattern.
jpayne@69 431 * Can be NULL.
jpayne@69 432 * @param errorCode Standard ICU error code. Its input value must
jpayne@69 433 * pass the U_SUCCESS() test, or else the function returns
jpayne@69 434 * immediately. Check for U_FAILURE() on output or use with
jpayne@69 435 * function chaining. (See User Guide for details.)
jpayne@69 436 * @return *this
jpayne@69 437 * @throws IllegalArgumentException for syntax errors in the pattern string
jpayne@69 438 * @throws IndexOutOfBoundsException if certain limits are exceeded
jpayne@69 439 * (e.g., argument number too high, argument name too long, etc.)
jpayne@69 440 * @throws NumberFormatException if a number could not be parsed
jpayne@69 441 * @stable ICU 4.8
jpayne@69 442 */
jpayne@69 443 MessagePattern &parse(const UnicodeString &pattern,
jpayne@69 444 UParseError *parseError, UErrorCode &errorCode);
jpayne@69 445
jpayne@69 446 /**
jpayne@69 447 * Parses a ChoiceFormat pattern string.
jpayne@69 448 * @param pattern a ChoiceFormat pattern string
jpayne@69 449 * @param parseError Struct to receive information on the position
jpayne@69 450 * of an error within the pattern.
jpayne@69 451 * Can be NULL.
jpayne@69 452 * @param errorCode Standard ICU error code. Its input value must
jpayne@69 453 * pass the U_SUCCESS() test, or else the function returns
jpayne@69 454 * immediately. Check for U_FAILURE() on output or use with
jpayne@69 455 * function chaining. (See User Guide for details.)
jpayne@69 456 * @return *this
jpayne@69 457 * @throws IllegalArgumentException for syntax errors in the pattern string
jpayne@69 458 * @throws IndexOutOfBoundsException if certain limits are exceeded
jpayne@69 459 * (e.g., argument number too high, argument name too long, etc.)
jpayne@69 460 * @throws NumberFormatException if a number could not be parsed
jpayne@69 461 * @stable ICU 4.8
jpayne@69 462 */
jpayne@69 463 MessagePattern &parseChoiceStyle(const UnicodeString &pattern,
jpayne@69 464 UParseError *parseError, UErrorCode &errorCode);
jpayne@69 465
jpayne@69 466 /**
jpayne@69 467 * Parses a PluralFormat pattern string.
jpayne@69 468 * @param pattern a PluralFormat pattern string
jpayne@69 469 * @param parseError Struct to receive information on the position
jpayne@69 470 * of an error within the pattern.
jpayne@69 471 * Can be NULL.
jpayne@69 472 * @param errorCode Standard ICU error code. Its input value must
jpayne@69 473 * pass the U_SUCCESS() test, or else the function returns
jpayne@69 474 * immediately. Check for U_FAILURE() on output or use with
jpayne@69 475 * function chaining. (See User Guide for details.)
jpayne@69 476 * @return *this
jpayne@69 477 * @throws IllegalArgumentException for syntax errors in the pattern string
jpayne@69 478 * @throws IndexOutOfBoundsException if certain limits are exceeded
jpayne@69 479 * (e.g., argument number too high, argument name too long, etc.)
jpayne@69 480 * @throws NumberFormatException if a number could not be parsed
jpayne@69 481 * @stable ICU 4.8
jpayne@69 482 */
jpayne@69 483 MessagePattern &parsePluralStyle(const UnicodeString &pattern,
jpayne@69 484 UParseError *parseError, UErrorCode &errorCode);
jpayne@69 485
jpayne@69 486 /**
jpayne@69 487 * Parses a SelectFormat pattern string.
jpayne@69 488 * @param pattern a SelectFormat pattern string
jpayne@69 489 * @param parseError Struct to receive information on the position
jpayne@69 490 * of an error within the pattern.
jpayne@69 491 * Can be NULL.
jpayne@69 492 * @param errorCode Standard ICU error code. Its input value must
jpayne@69 493 * pass the U_SUCCESS() test, or else the function returns
jpayne@69 494 * immediately. Check for U_FAILURE() on output or use with
jpayne@69 495 * function chaining. (See User Guide for details.)
jpayne@69 496 * @return *this
jpayne@69 497 * @throws IllegalArgumentException for syntax errors in the pattern string
jpayne@69 498 * @throws IndexOutOfBoundsException if certain limits are exceeded
jpayne@69 499 * (e.g., argument number too high, argument name too long, etc.)
jpayne@69 500 * @throws NumberFormatException if a number could not be parsed
jpayne@69 501 * @stable ICU 4.8
jpayne@69 502 */
jpayne@69 503 MessagePattern &parseSelectStyle(const UnicodeString &pattern,
jpayne@69 504 UParseError *parseError, UErrorCode &errorCode);
jpayne@69 505
jpayne@69 506 /**
jpayne@69 507 * Clears this MessagePattern.
jpayne@69 508 * countParts() will return 0.
jpayne@69 509 * @stable ICU 4.8
jpayne@69 510 */
jpayne@69 511 void clear();
jpayne@69 512
jpayne@69 513 /**
jpayne@69 514 * Clears this MessagePattern and sets the UMessagePatternApostropheMode.
jpayne@69 515 * countParts() will return 0.
jpayne@69 516 * @param mode The new UMessagePatternApostropheMode.
jpayne@69 517 * @stable ICU 4.8
jpayne@69 518 */
jpayne@69 519 void clearPatternAndSetApostropheMode(UMessagePatternApostropheMode mode) {
jpayne@69 520 clear();
jpayne@69 521 aposMode=mode;
jpayne@69 522 }
jpayne@69 523
jpayne@69 524 /**
jpayne@69 525 * @param other another object to compare with.
jpayne@69 526 * @return TRUE if this object is equivalent to the other one.
jpayne@69 527 * @stable ICU 4.8
jpayne@69 528 */
jpayne@69 529 UBool operator==(const MessagePattern &other) const;
jpayne@69 530
jpayne@69 531 /**
jpayne@69 532 * @param other another object to compare with.
jpayne@69 533 * @return FALSE if this object is equivalent to the other one.
jpayne@69 534 * @stable ICU 4.8
jpayne@69 535 */
jpayne@69 536 inline UBool operator!=(const MessagePattern &other) const {
jpayne@69 537 return !operator==(other);
jpayne@69 538 }
jpayne@69 539
jpayne@69 540 /**
jpayne@69 541 * @return A hash code for this object.
jpayne@69 542 * @stable ICU 4.8
jpayne@69 543 */
jpayne@69 544 int32_t hashCode() const;
jpayne@69 545
jpayne@69 546 /**
jpayne@69 547 * @return this instance's UMessagePatternApostropheMode.
jpayne@69 548 * @stable ICU 4.8
jpayne@69 549 */
jpayne@69 550 UMessagePatternApostropheMode getApostropheMode() const {
jpayne@69 551 return aposMode;
jpayne@69 552 }
jpayne@69 553
jpayne@69 554 // Java has package-private jdkAposMode() here.
jpayne@69 555 // In C++, this is declared in the MessageImpl class.
jpayne@69 556
jpayne@69 557 /**
jpayne@69 558 * @return the parsed pattern string (null if none was parsed).
jpayne@69 559 * @stable ICU 4.8
jpayne@69 560 */
jpayne@69 561 const UnicodeString &getPatternString() const {
jpayne@69 562 return msg;
jpayne@69 563 }
jpayne@69 564
jpayne@69 565 /**
jpayne@69 566 * Does the parsed pattern have named arguments like {first_name}?
jpayne@69 567 * @return TRUE if the parsed pattern has at least one named argument.
jpayne@69 568 * @stable ICU 4.8
jpayne@69 569 */
jpayne@69 570 UBool hasNamedArguments() const {
jpayne@69 571 return hasArgNames;
jpayne@69 572 }
jpayne@69 573
jpayne@69 574 /**
jpayne@69 575 * Does the parsed pattern have numbered arguments like {2}?
jpayne@69 576 * @return TRUE if the parsed pattern has at least one numbered argument.
jpayne@69 577 * @stable ICU 4.8
jpayne@69 578 */
jpayne@69 579 UBool hasNumberedArguments() const {
jpayne@69 580 return hasArgNumbers;
jpayne@69 581 }
jpayne@69 582
jpayne@69 583 /**
jpayne@69 584 * Validates and parses an argument name or argument number string.
jpayne@69 585 * An argument name must be a "pattern identifier", that is, it must contain
jpayne@69 586 * no Unicode Pattern_Syntax or Pattern_White_Space characters.
jpayne@69 587 * If it only contains ASCII digits, then it must be a small integer with no leading zero.
jpayne@69 588 * @param name Input string.
jpayne@69 589 * @return &gt;=0 if the name is a valid number,
jpayne@69 590 * ARG_NAME_NOT_NUMBER (-1) if it is a "pattern identifier" but not all ASCII digits,
jpayne@69 591 * ARG_NAME_NOT_VALID (-2) if it is neither.
jpayne@69 592 * @stable ICU 4.8
jpayne@69 593 */
jpayne@69 594 static int32_t validateArgumentName(const UnicodeString &name);
jpayne@69 595
jpayne@69 596 /**
jpayne@69 597 * Returns a version of the parsed pattern string where each ASCII apostrophe
jpayne@69 598 * is doubled (escaped) if it is not already, and if it is not interpreted as quoting syntax.
jpayne@69 599 * <p>
jpayne@69 600 * For example, this turns "I don't '{know}' {gender,select,female{h''er}other{h'im}}."
jpayne@69 601 * into "I don''t '{know}' {gender,select,female{h''er}other{h''im}}."
jpayne@69 602 * @return the deep-auto-quoted version of the parsed pattern string.
jpayne@69 603 * @see MessageFormat.autoQuoteApostrophe()
jpayne@69 604 * @stable ICU 4.8
jpayne@69 605 */
jpayne@69 606 UnicodeString autoQuoteApostropheDeep() const;
jpayne@69 607
jpayne@69 608 class Part;
jpayne@69 609
jpayne@69 610 /**
jpayne@69 611 * Returns the number of "parts" created by parsing the pattern string.
jpayne@69 612 * Returns 0 if no pattern has been parsed or clear() was called.
jpayne@69 613 * @return the number of pattern parts.
jpayne@69 614 * @stable ICU 4.8
jpayne@69 615 */
jpayne@69 616 int32_t countParts() const {
jpayne@69 617 return partsLength;
jpayne@69 618 }
jpayne@69 619
jpayne@69 620 /**
jpayne@69 621 * Gets the i-th pattern "part".
jpayne@69 622 * @param i The index of the Part data. (0..countParts()-1)
jpayne@69 623 * @return the i-th pattern "part".
jpayne@69 624 * @stable ICU 4.8
jpayne@69 625 */
jpayne@69 626 const Part &getPart(int32_t i) const {
jpayne@69 627 return parts[i];
jpayne@69 628 }
jpayne@69 629
jpayne@69 630 /**
jpayne@69 631 * Returns the UMessagePatternPartType of the i-th pattern "part".
jpayne@69 632 * Convenience method for getPart(i).getType().
jpayne@69 633 * @param i The index of the Part data. (0..countParts()-1)
jpayne@69 634 * @return The UMessagePatternPartType of the i-th Part.
jpayne@69 635 * @stable ICU 4.8
jpayne@69 636 */
jpayne@69 637 UMessagePatternPartType getPartType(int32_t i) const {
jpayne@69 638 return getPart(i).type;
jpayne@69 639 }
jpayne@69 640
jpayne@69 641 /**
jpayne@69 642 * Returns the pattern index of the specified pattern "part".
jpayne@69 643 * Convenience method for getPart(partIndex).getIndex().
jpayne@69 644 * @param partIndex The index of the Part data. (0..countParts()-1)
jpayne@69 645 * @return The pattern index of this Part.
jpayne@69 646 * @stable ICU 4.8
jpayne@69 647 */
jpayne@69 648 int32_t getPatternIndex(int32_t partIndex) const {
jpayne@69 649 return getPart(partIndex).index;
jpayne@69 650 }
jpayne@69 651
jpayne@69 652 /**
jpayne@69 653 * Returns the substring of the pattern string indicated by the Part.
jpayne@69 654 * Convenience method for getPatternString().substring(part.getIndex(), part.getLimit()).
jpayne@69 655 * @param part a part of this MessagePattern.
jpayne@69 656 * @return the substring associated with part.
jpayne@69 657 * @stable ICU 4.8
jpayne@69 658 */
jpayne@69 659 UnicodeString getSubstring(const Part &part) const {
jpayne@69 660 return msg.tempSubString(part.index, part.length);
jpayne@69 661 }
jpayne@69 662
jpayne@69 663 /**
jpayne@69 664 * Compares the part's substring with the input string s.
jpayne@69 665 * @param part a part of this MessagePattern.
jpayne@69 666 * @param s a string.
jpayne@69 667 * @return TRUE if getSubstring(part).equals(s).
jpayne@69 668 * @stable ICU 4.8
jpayne@69 669 */
jpayne@69 670 UBool partSubstringMatches(const Part &part, const UnicodeString &s) const {
jpayne@69 671 return 0==msg.compare(part.index, part.length, s);
jpayne@69 672 }
jpayne@69 673
jpayne@69 674 /**
jpayne@69 675 * Returns the numeric value associated with an ARG_INT or ARG_DOUBLE.
jpayne@69 676 * @param part a part of this MessagePattern.
jpayne@69 677 * @return the part's numeric value, or UMSGPAT_NO_NUMERIC_VALUE if this is not a numeric part.
jpayne@69 678 * @stable ICU 4.8
jpayne@69 679 */
jpayne@69 680 double getNumericValue(const Part &part) const;
jpayne@69 681
jpayne@69 682 /**
jpayne@69 683 * Returns the "offset:" value of a PluralFormat argument, or 0 if none is specified.
jpayne@69 684 * @param pluralStart the index of the first PluralFormat argument style part. (0..countParts()-1)
jpayne@69 685 * @return the "offset:" value.
jpayne@69 686 * @stable ICU 4.8
jpayne@69 687 */
jpayne@69 688 double getPluralOffset(int32_t pluralStart) const;
jpayne@69 689
jpayne@69 690 /**
jpayne@69 691 * Returns the index of the ARG|MSG_LIMIT part corresponding to the ARG|MSG_START at start.
jpayne@69 692 * @param start The index of some Part data (0..countParts()-1);
jpayne@69 693 * this Part should be of Type ARG_START or MSG_START.
jpayne@69 694 * @return The first i>start where getPart(i).getType()==ARG|MSG_LIMIT at the same nesting level,
jpayne@69 695 * or start itself if getPartType(msgStart)!=ARG|MSG_START.
jpayne@69 696 * @stable ICU 4.8
jpayne@69 697 */
jpayne@69 698 int32_t getLimitPartIndex(int32_t start) const {
jpayne@69 699 int32_t limit=getPart(start).limitPartIndex;
jpayne@69 700 if(limit<start) {
jpayne@69 701 return start;
jpayne@69 702 }
jpayne@69 703 return limit;
jpayne@69 704 }
jpayne@69 705
jpayne@69 706 /**
jpayne@69 707 * A message pattern "part", representing a pattern parsing event.
jpayne@69 708 * There is a part for the start and end of a message or argument,
jpayne@69 709 * for quoting and escaping of and with ASCII apostrophes,
jpayne@69 710 * and for syntax elements of "complex" arguments.
jpayne@69 711 * @stable ICU 4.8
jpayne@69 712 */
jpayne@69 713 class Part : public UMemory {
jpayne@69 714 public:
jpayne@69 715 /**
jpayne@69 716 * Default constructor, do not use.
jpayne@69 717 * @internal
jpayne@69 718 */
jpayne@69 719 Part() {}
jpayne@69 720
jpayne@69 721 /**
jpayne@69 722 * Returns the type of this part.
jpayne@69 723 * @return the part type.
jpayne@69 724 * @stable ICU 4.8
jpayne@69 725 */
jpayne@69 726 UMessagePatternPartType getType() const {
jpayne@69 727 return type;
jpayne@69 728 }
jpayne@69 729
jpayne@69 730 /**
jpayne@69 731 * Returns the pattern string index associated with this Part.
jpayne@69 732 * @return this part's pattern string index.
jpayne@69 733 * @stable ICU 4.8
jpayne@69 734 */
jpayne@69 735 int32_t getIndex() const {
jpayne@69 736 return index;
jpayne@69 737 }
jpayne@69 738
jpayne@69 739 /**
jpayne@69 740 * Returns the length of the pattern substring associated with this Part.
jpayne@69 741 * This is 0 for some parts.
jpayne@69 742 * @return this part's pattern substring length.
jpayne@69 743 * @stable ICU 4.8
jpayne@69 744 */
jpayne@69 745 int32_t getLength() const {
jpayne@69 746 return length;
jpayne@69 747 }
jpayne@69 748
jpayne@69 749 /**
jpayne@69 750 * Returns the pattern string limit (exclusive-end) index associated with this Part.
jpayne@69 751 * Convenience method for getIndex()+getLength().
jpayne@69 752 * @return this part's pattern string limit index, same as getIndex()+getLength().
jpayne@69 753 * @stable ICU 4.8
jpayne@69 754 */
jpayne@69 755 int32_t getLimit() const {
jpayne@69 756 return index+length;
jpayne@69 757 }
jpayne@69 758
jpayne@69 759 /**
jpayne@69 760 * Returns a value associated with this part.
jpayne@69 761 * See the documentation of each part type for details.
jpayne@69 762 * @return the part value.
jpayne@69 763 * @stable ICU 4.8
jpayne@69 764 */
jpayne@69 765 int32_t getValue() const {
jpayne@69 766 return value;
jpayne@69 767 }
jpayne@69 768
jpayne@69 769 /**
jpayne@69 770 * Returns the argument type if this part is of type ARG_START or ARG_LIMIT,
jpayne@69 771 * otherwise UMSGPAT_ARG_TYPE_NONE.
jpayne@69 772 * @return the argument type for this part.
jpayne@69 773 * @stable ICU 4.8
jpayne@69 774 */
jpayne@69 775 UMessagePatternArgType getArgType() const {
jpayne@69 776 UMessagePatternPartType msgType=getType();
jpayne@69 777 if(msgType ==UMSGPAT_PART_TYPE_ARG_START || msgType ==UMSGPAT_PART_TYPE_ARG_LIMIT) {
jpayne@69 778 return (UMessagePatternArgType)value;
jpayne@69 779 } else {
jpayne@69 780 return UMSGPAT_ARG_TYPE_NONE;
jpayne@69 781 }
jpayne@69 782 }
jpayne@69 783
jpayne@69 784 /**
jpayne@69 785 * Indicates whether the Part type has a numeric value.
jpayne@69 786 * If so, then that numeric value can be retrieved via MessagePattern.getNumericValue().
jpayne@69 787 * @param type The Part type to be tested.
jpayne@69 788 * @return TRUE if the Part type has a numeric value.
jpayne@69 789 * @stable ICU 4.8
jpayne@69 790 */
jpayne@69 791 static UBool hasNumericValue(UMessagePatternPartType type) {
jpayne@69 792 return type==UMSGPAT_PART_TYPE_ARG_INT || type==UMSGPAT_PART_TYPE_ARG_DOUBLE;
jpayne@69 793 }
jpayne@69 794
jpayne@69 795 /**
jpayne@69 796 * @param other another object to compare with.
jpayne@69 797 * @return TRUE if this object is equivalent to the other one.
jpayne@69 798 * @stable ICU 4.8
jpayne@69 799 */
jpayne@69 800 UBool operator==(const Part &other) const;
jpayne@69 801
jpayne@69 802 /**
jpayne@69 803 * @param other another object to compare with.
jpayne@69 804 * @return FALSE if this object is equivalent to the other one.
jpayne@69 805 * @stable ICU 4.8
jpayne@69 806 */
jpayne@69 807 inline UBool operator!=(const Part &other) const {
jpayne@69 808 return !operator==(other);
jpayne@69 809 }
jpayne@69 810
jpayne@69 811 /**
jpayne@69 812 * @return A hash code for this object.
jpayne@69 813 * @stable ICU 4.8
jpayne@69 814 */
jpayne@69 815 int32_t hashCode() const {
jpayne@69 816 return ((type*37+index)*37+length)*37+value;
jpayne@69 817 }
jpayne@69 818
jpayne@69 819 private:
jpayne@69 820 friend class MessagePattern;
jpayne@69 821
jpayne@69 822 static const int32_t MAX_LENGTH=0xffff;
jpayne@69 823 static const int32_t MAX_VALUE=0x7fff;
jpayne@69 824
jpayne@69 825 // Some fields are not final because they are modified during pattern parsing.
jpayne@69 826 // After pattern parsing, the parts are effectively immutable.
jpayne@69 827 UMessagePatternPartType type;
jpayne@69 828 int32_t index;
jpayne@69 829 uint16_t length;
jpayne@69 830 int16_t value;
jpayne@69 831 int32_t limitPartIndex;
jpayne@69 832 };
jpayne@69 833
jpayne@69 834 private:
jpayne@69 835 void preParse(const UnicodeString &pattern, UParseError *parseError, UErrorCode &errorCode);
jpayne@69 836
jpayne@69 837 void postParse();
jpayne@69 838
jpayne@69 839 int32_t parseMessage(int32_t index, int32_t msgStartLength,
jpayne@69 840 int32_t nestingLevel, UMessagePatternArgType parentType,
jpayne@69 841 UParseError *parseError, UErrorCode &errorCode);
jpayne@69 842
jpayne@69 843 int32_t parseArg(int32_t index, int32_t argStartLength, int32_t nestingLevel,
jpayne@69 844 UParseError *parseError, UErrorCode &errorCode);
jpayne@69 845
jpayne@69 846 int32_t parseSimpleStyle(int32_t index, UParseError *parseError, UErrorCode &errorCode);
jpayne@69 847
jpayne@69 848 int32_t parseChoiceStyle(int32_t index, int32_t nestingLevel,
jpayne@69 849 UParseError *parseError, UErrorCode &errorCode);
jpayne@69 850
jpayne@69 851 int32_t parsePluralOrSelectStyle(UMessagePatternArgType argType, int32_t index, int32_t nestingLevel,
jpayne@69 852 UParseError *parseError, UErrorCode &errorCode);
jpayne@69 853
jpayne@69 854 /**
jpayne@69 855 * Validates and parses an argument name or argument number string.
jpayne@69 856 * This internal method assumes that the input substring is a "pattern identifier".
jpayne@69 857 * @return &gt;=0 if the name is a valid number,
jpayne@69 858 * ARG_NAME_NOT_NUMBER (-1) if it is a "pattern identifier" but not all ASCII digits,
jpayne@69 859 * ARG_NAME_NOT_VALID (-2) if it is neither.
jpayne@69 860 * @see #validateArgumentName(String)
jpayne@69 861 */
jpayne@69 862 static int32_t parseArgNumber(const UnicodeString &s, int32_t start, int32_t limit);
jpayne@69 863
jpayne@69 864 int32_t parseArgNumber(int32_t start, int32_t limit) {
jpayne@69 865 return parseArgNumber(msg, start, limit);
jpayne@69 866 }
jpayne@69 867
jpayne@69 868 /**
jpayne@69 869 * Parses a number from the specified message substring.
jpayne@69 870 * @param start start index into the message string
jpayne@69 871 * @param limit limit index into the message string, must be start<limit
jpayne@69 872 * @param allowInfinity TRUE if U+221E is allowed (for ChoiceFormat)
jpayne@69 873 * @param parseError
jpayne@69 874 * @param errorCode
jpayne@69 875 */
jpayne@69 876 void parseDouble(int32_t start, int32_t limit, UBool allowInfinity,
jpayne@69 877 UParseError *parseError, UErrorCode &errorCode);
jpayne@69 878
jpayne@69 879 // Java has package-private appendReducedApostrophes() here.
jpayne@69 880 // In C++, this is declared in the MessageImpl class.
jpayne@69 881
jpayne@69 882 int32_t skipWhiteSpace(int32_t index);
jpayne@69 883
jpayne@69 884 int32_t skipIdentifier(int32_t index);
jpayne@69 885
jpayne@69 886 /**
jpayne@69 887 * Skips a sequence of characters that could occur in a double value.
jpayne@69 888 * Does not fully parse or validate the value.
jpayne@69 889 */
jpayne@69 890 int32_t skipDouble(int32_t index);
jpayne@69 891
jpayne@69 892 static UBool isArgTypeChar(UChar32 c);
jpayne@69 893
jpayne@69 894 UBool isChoice(int32_t index);
jpayne@69 895
jpayne@69 896 UBool isPlural(int32_t index);
jpayne@69 897
jpayne@69 898 UBool isSelect(int32_t index);
jpayne@69 899
jpayne@69 900 UBool isOrdinal(int32_t index);
jpayne@69 901
jpayne@69 902 /**
jpayne@69 903 * @return TRUE if we are inside a MessageFormat (sub-)pattern,
jpayne@69 904 * as opposed to inside a top-level choice/plural/select pattern.
jpayne@69 905 */
jpayne@69 906 UBool inMessageFormatPattern(int32_t nestingLevel);
jpayne@69 907
jpayne@69 908 /**
jpayne@69 909 * @return TRUE if we are in a MessageFormat sub-pattern
jpayne@69 910 * of a top-level ChoiceFormat pattern.
jpayne@69 911 */
jpayne@69 912 UBool inTopLevelChoiceMessage(int32_t nestingLevel, UMessagePatternArgType parentType);
jpayne@69 913
jpayne@69 914 void addPart(UMessagePatternPartType type, int32_t index, int32_t length,
jpayne@69 915 int32_t value, UErrorCode &errorCode);
jpayne@69 916
jpayne@69 917 void addLimitPart(int32_t start,
jpayne@69 918 UMessagePatternPartType type, int32_t index, int32_t length,
jpayne@69 919 int32_t value, UErrorCode &errorCode);
jpayne@69 920
jpayne@69 921 void addArgDoublePart(double numericValue, int32_t start, int32_t length, UErrorCode &errorCode);
jpayne@69 922
jpayne@69 923 void setParseError(UParseError *parseError, int32_t index);
jpayne@69 924
jpayne@69 925 UBool init(UErrorCode &errorCode);
jpayne@69 926 UBool copyStorage(const MessagePattern &other, UErrorCode &errorCode);
jpayne@69 927
jpayne@69 928 UMessagePatternApostropheMode aposMode;
jpayne@69 929 UnicodeString msg;
jpayne@69 930 // ArrayList<Part> parts=new ArrayList<Part>();
jpayne@69 931 MessagePatternPartsList *partsList;
jpayne@69 932 Part *parts;
jpayne@69 933 int32_t partsLength;
jpayne@69 934 // ArrayList<Double> numericValues;
jpayne@69 935 MessagePatternDoubleList *numericValuesList;
jpayne@69 936 double *numericValues;
jpayne@69 937 int32_t numericValuesLength;
jpayne@69 938 UBool hasArgNames;
jpayne@69 939 UBool hasArgNumbers;
jpayne@69 940 UBool needsAutoQuoting;
jpayne@69 941 };
jpayne@69 942
jpayne@69 943 U_NAMESPACE_END
jpayne@69 944
jpayne@69 945 #endif // !UCONFIG_NO_FORMATTING
jpayne@69 946
jpayne@69 947 #endif /* U_SHOW_CPLUSPLUS_API */
jpayne@69 948
jpayne@69 949 #endif // __MESSAGEPATTERN_H__