MessagePattern

public final class MessagePattern
extends Object implements Cloneable, Freezable<MessagePattern>

java.lang.Object
   ↳ android.icu.text.MessagePattern


Parses and represents ICU MessageFormat patterns. Also handles patterns for ChoiceFormat, PluralFormat and SelectFormat. Used in the implementations of those classes as well as in tools for message validation, translation and format conversion.

The parser handles all syntax relevant for identifying message arguments. This includes "complex" arguments whose style strings contain nested MessageFormat pattern substrings. For "simple" arguments (with no nested MessageFormat pattern substrings), the argument style is not parsed any further.

The parser handles named and numbered message arguments and allows both in one message.

Once a pattern has been parsed successfully, iterate through the parsed data with countParts(), getPart() and related methods.

The data logically represents a parse tree, but is stored and accessed as a list of "parts" for fast and simple parsing and to minimize object allocations. Arguments and nested messages are best handled via recursion. For every _START "part", getLimitPartIndex(int) efficiently returns the index of the corresponding _LIMIT "part".

List of "parts":

 message = MSG_START (SKIP_SYNTAX | INSERT_CHAR | REPLACE_NUMBER | argument)* MSG_LIMIT
 argument = noneArg | simpleArg | complexArg
 complexArg = choiceArg | pluralArg | selectArg

 noneArg = ARG_START.NONE (ARG_NAME | ARG_NUMBER) ARG_LIMIT.NONE
 simpleArg = ARG_START.SIMPLE (ARG_NAME | ARG_NUMBER) ARG_TYPE [ARG_STYLE] ARG_LIMIT.SIMPLE
 choiceArg = ARG_START.CHOICE (ARG_NAME | ARG_NUMBER) choiceStyle ARG_LIMIT.CHOICE
 pluralArg = ARG_START.PLURAL (ARG_NAME | ARG_NUMBER) pluralStyle ARG_LIMIT.PLURAL
 selectArg = ARG_START.SELECT (ARG_NAME | ARG_NUMBER) selectStyle ARG_LIMIT.SELECT

 choiceStyle = ((ARG_INT | ARG_DOUBLE) ARG_SELECTOR message)+
 pluralStyle = [ARG_INT | ARG_DOUBLE] (ARG_SELECTOR [ARG_INT | ARG_DOUBLE] message)+
 selectStyle = (ARG_SELECTOR message)+
 
  • Literal output text is not represented directly by "parts" but accessed between parts of a message, from one part's getLimit() to the next part's getIndex().
  • ARG_START.CHOICE stands for an ARG_START Part with ArgType CHOICE.
  • In the choiceStyle, the ARG_SELECTOR has the '<', the '#' or the less-than-or-equal-to sign (U+2264).
  • In the pluralStyle, the first, optional numeric Part has the "offset:" value. The optional numeric Part between each (ARG_SELECTOR, message) pair is the value of an explicit-number selector like "=2", otherwise the selector is a non-numeric identifier.
  • The REPLACE_NUMBER Part can occur only in an immediate sub-message of the pluralStyle.

This class is not intended for public subclassing.

Summary

Nested classes

class MessagePattern.Part

A message pattern "part", representing a pattern parsing event. 

Constants

int ARG_NAME_NOT_NUMBER

Return value from validateArgumentName(java.lang.String) for when the string is a valid "pattern identifier" but not a number.

int ARG_NAME_NOT_VALID

Return value from validateArgumentName(java.lang.String) for when the string is invalid.

double NO_NUMERIC_VALUE

Special value that is returned by getNumericValue(Part) when no numeric value is defined for a part.

Public constructors

MessagePattern()

Constructs an empty MessagePattern with default ApostropheMode.

MessagePattern(MessagePattern.ApostropheMode mode)

Constructs an empty MessagePattern.

MessagePattern(String pattern)

Constructs a MessagePattern with default ApostropheMode and parses the MessageFormat pattern string.

Public methods

String autoQuoteApostropheDeep()

Returns a version of the parsed pattern string where each ASCII apostrophe is doubled (escaped) if it is not already, and if it is not interpreted as quoting syntax.

void clear()

Clears this MessagePattern.

void clearPatternAndSetApostropheMode(MessagePattern.ApostropheMode mode)

Clears this MessagePattern and sets the ApostropheMode.

Object clone()

Creates and returns a copy of this object.

MessagePattern cloneAsThawed()

Creates and returns an unfrozen copy of this object.

int countParts()

Returns the number of "parts" created by parsing the pattern string.

boolean equals(Object other)

Indicates whether some other object is "equal to" this one.

MessagePattern freeze()

Freezes this object, making it immutable and thread-safe.

MessagePattern.ApostropheMode getApostropheMode()
int getLimitPartIndex(int start)

Returns the index of the ARG|MSG_LIMIT part corresponding to the ARG|MSG_START at start.

double getNumericValue(MessagePattern.Part part)

Returns the numeric value associated with an ARG_INT or ARG_DOUBLE.

MessagePattern.Part getPart(int i)

Gets the i-th pattern "part".

MessagePattern.Part.Type getPartType(int i)

Returns the Part.Type of the i-th pattern "part".

int getPatternIndex(int partIndex)

Returns the pattern index of the specified pattern "part".

String getPatternString()
double getPluralOffset(int pluralStart)

Returns the "offset:" value of a PluralFormat argument, or 0 if none is specified.

String getSubstring(MessagePattern.Part part)

Returns the substring of the pattern string indicated by the Part.

boolean hasNamedArguments()

Does the parsed pattern have named arguments like {first_name}?

boolean hasNumberedArguments()

Does the parsed pattern have numbered arguments like {2}?

int hashCode()

Returns a hash code value for the object.

boolean isFrozen()

Determines whether this object is frozen (immutable) or not.

MessagePattern parse(String pattern)

Parses a MessageFormat pattern string.

MessagePattern parseChoiceStyle(String pattern)

Parses a ChoiceFormat pattern string.

MessagePattern parsePluralStyle(String pattern)

Parses a PluralFormat pattern string.

MessagePattern parseSelectStyle(String pattern)

Parses a SelectFormat pattern string.

boolean partSubstringMatches(MessagePattern.Part part, String s)

Compares the part's substring with the input string s.

String toString()

Returns a string representation of the object.

static int validateArgumentName(String name)

Validates and parses an argument name or argument number string.

Inherited methods

Constants

ARG_NAME_NOT_NUMBER

Added in API level 24
public static final int ARG_NAME_NOT_NUMBER

Return value from validateArgumentName(java.lang.String) for when the string is a valid "pattern identifier" but not a number.

Constant Value: -1 (0xffffffff)

ARG_NAME_NOT_VALID

Added in API level 24
public static final int ARG_NAME_NOT_VALID

Return value from validateArgumentName(java.lang.String) for when the string is invalid. It might not be a valid "pattern identifier", or it have only ASCII digits but there is a leading zero or the number is too large.

Constant Value: -2 (0xfffffffe)

NO_NUMERIC_VALUE

Added in API level 24
public static final double NO_NUMERIC_VALUE

Special value that is returned by getNumericValue(Part) when no numeric value is defined for a part.

Constant Value: -1.23456789E8

Public constructors

MessagePattern

Added in API level 24
public MessagePattern ()

Constructs an empty MessagePattern with default ApostropheMode.

MessagePattern

Added in API level 24
public MessagePattern (MessagePattern.ApostropheMode mode)

Constructs an empty MessagePattern.

Parameters
mode MessagePattern.ApostropheMode: Explicit ApostropheMode.

MessagePattern

Added in API level 24
public MessagePattern (String pattern)

Constructs a MessagePattern with default ApostropheMode and parses the MessageFormat pattern string.

Parameters
pattern String: a MessageFormat pattern string

Throws
IllegalArgumentException for syntax errors in the pattern string
IndexOutOfBoundsException if certain limits are exceeded (e.g., argument number too high, argument name too long, etc.)
NumberFormatException if a number could not be parsed

Public methods

autoQuoteApostropheDeep

Added in API level 24
public String autoQuoteApostropheDeep ()

Returns a version of the parsed pattern string where each ASCII apostrophe is doubled (escaped) if it is not already, and if it is not interpreted as quoting syntax.

For example, this turns "I don't '{know}' {gender,select,female{h''er}other{h'im}}." into "I don''t '{know}' {gender,select,female{h''er}other{h''im}}."

Returns
String the deep-auto-quoted version of the parsed pattern string.

clear

Added in API level 24
public void clear ()

Clears this MessagePattern. countParts() will return 0.

clearPatternAndSetApostropheMode

Added in API level 24
public void clearPatternAndSetApostropheMode (MessagePattern.ApostropheMode mode)

Clears this MessagePattern and sets the ApostropheMode. countParts() will return 0.

Parameters
mode MessagePattern.ApostropheMode: The new ApostropheMode.

clone

Added in API level 24
public Object clone ()

Creates and returns a copy of this object.

Returns
Object a copy of this object (or itself if frozen).

cloneAsThawed

Added in API level 24
public MessagePattern cloneAsThawed ()

Creates and returns an unfrozen copy of this object.

Returns
MessagePattern a copy of this object.

countParts

Added in API level 24
public int countParts ()

Returns the number of "parts" created by parsing the pattern string. Returns 0 if no pattern has been parsed or clear() was called.

Returns
int the number of pattern parts.

equals

Added in API level 24
public boolean equals (Object other)

Indicates whether some other object is "equal to" this one.

The equals method implements an equivalence relation on non-null object references:

  • It is reflexive: for any non-null reference value x, x.equals(x) should return true.
  • It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
  • It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
  • It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
  • For any non-null reference value x, x.equals(null) should return false.

An equivalence relation partitions the elements it operates on into equivalence classes; all the members of an equivalence class are equal to each other. Members of an equivalence class are substitutable for each other, at least for some purposes.

Parameters
other Object: another object to compare with.

Returns
boolean true if this object is equivalent to the other one.

freeze

Added in API level 24
public MessagePattern freeze ()

Freezes this object, making it immutable and thread-safe.

Returns
MessagePattern this

getApostropheMode

Added in API level 24
public MessagePattern.ApostropheMode getApostropheMode ()

Returns
MessagePattern.ApostropheMode this instance's ApostropheMode.

getLimitPartIndex

Added in API level 24
public int getLimitPartIndex (int start)

Returns the index of the ARG|MSG_LIMIT part corresponding to the ARG|MSG_START at start.

Parameters
start int: The index of some Part data (0..countParts()-1); this Part should be of Type ARG_START or MSG_START.

Returns
int The first i>start where getPart(i).getType()==ARG|MSG_LIMIT at the same nesting level, or start itself if getPartType(msgStart)!=ARG|MSG_START.

Throws
IndexOutOfBoundsException if start is outside the (0..countParts()-1) range

getNumericValue

Added in API level 24
public double getNumericValue (MessagePattern.Part part)

Returns the numeric value associated with an ARG_INT or ARG_DOUBLE.

Parameters
part MessagePattern.Part: a part of this MessagePattern.

Returns
double the part's numeric value, or NO_NUMERIC_VALUE if this is not a numeric part.

getPart

Added in API level 24
public MessagePattern.Part getPart (int i)

Gets the i-th pattern "part".

Parameters
i int: The index of the Part data. (0..countParts()-1)

Returns
MessagePattern.Part the i-th pattern "part".

Throws
IndexOutOfBoundsException if i is outside the (0..countParts()-1) range

getPartType

Added in API level 24
public MessagePattern.Part.Type getPartType (int i)

Returns the Part.Type of the i-th pattern "part". Convenience method for getPart(i).getType().

Parameters
i int: The index of the Part data. (0..countParts()-1)

Returns
MessagePattern.Part.Type The Part.Type of the i-th Part.

Throws
IndexOutOfBoundsException if i is outside the (0..countParts()-1) range

getPatternIndex

Added in API level 24
public int getPatternIndex (int partIndex)

Returns the pattern index of the specified pattern "part". Convenience method for getPart(partIndex).getIndex().

Parameters
partIndex int: The index of the Part data. (0..countParts()-1)

Returns
int The pattern index of this Part.

Throws
IndexOutOfBoundsException if partIndex is outside the (0..countParts()-1) range

getPatternString

Added in API level 24
public String getPatternString ()

Returns
String the parsed pattern string (null if none was parsed).

getPluralOffset

Added in API level 24
public double getPluralOffset (int pluralStart)

Returns the "offset:" value of a PluralFormat argument, or 0 if none is specified.

Parameters
pluralStart int: the index of the first PluralFormat argument style part. (0..countParts()-1)

Returns
double the "offset:" value.

Throws
IndexOutOfBoundsException if pluralStart is outside the (0..countParts()-1) range

getSubstring

Added in API level 24
public String getSubstring (MessagePattern.Part part)

Returns the substring of the pattern string indicated by the Part. Convenience method for getPatternString().substring(part.getIndex(), part.getLimit()).

Parameters
part MessagePattern.Part: a part of this MessagePattern.

Returns
String the substring associated with part.

hasNamedArguments

Added in API level 24
public boolean hasNamedArguments ()

Does the parsed pattern have named arguments like {first_name}?

Returns
boolean true if the parsed pattern has at least one named argument.

hasNumberedArguments

Added in API level 24
public boolean hasNumberedArguments ()

Does the parsed pattern have numbered arguments like {2}?

Returns
boolean true if the parsed pattern has at least one numbered argument.

hashCode

Added in API level 24
public int hashCode ()

Returns a hash code value for the object. This method is supported for the benefit of hash tables such as those provided by HashMap.

The general contract of hashCode is:

  • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
  • If two objects are equal according to the equals method, then calling the hashCode method on each of the two objects must produce the same integer result.
  • It is not required that if two objects are unequal according to the equals method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.

Returns
int a hash code value for this object.

isFrozen

Added in API level 24
public boolean isFrozen ()

Determines whether this object is frozen (immutable) or not.

Returns
boolean true if this object is frozen.

parse

Added in API level 24
public MessagePattern parse (String pattern)

Parses a MessageFormat pattern string.

Parameters
pattern String: a MessageFormat pattern string

Returns
MessagePattern this

Throws
IllegalArgumentException for syntax errors in the pattern string
IndexOutOfBoundsException if certain limits are exceeded (e.g., argument number too high, argument name too long, etc.)
NumberFormatException if a number could not be parsed

parseChoiceStyle

Added in API level 24
public MessagePattern parseChoiceStyle (String pattern)

Parses a ChoiceFormat pattern string.

Parameters
pattern String: a ChoiceFormat pattern string

Returns
MessagePattern this

Throws
IllegalArgumentException for syntax errors in the pattern string
IndexOutOfBoundsException if certain limits are exceeded (e.g., argument number too high, argument name too long, etc.)
NumberFormatException if a number could not be parsed

parsePluralStyle

Added in API level 24
public MessagePattern parsePluralStyle (String pattern)

Parses a PluralFormat pattern string.

Parameters
pattern String: a PluralFormat pattern string

Returns
MessagePattern this

Throws
IllegalArgumentException for syntax errors in the pattern string
IndexOutOfBoundsException if certain limits are exceeded (e.g., argument number too high, argument name too long, etc.)
NumberFormatException if a number could not be parsed

parseSelectStyle

Added in API level 24
public MessagePattern parseSelectStyle (String pattern)

Parses a SelectFormat pattern string.

Parameters
pattern String: a SelectFormat pattern string

Returns
MessagePattern this

Throws
IllegalArgumentException for syntax errors in the pattern string
IndexOutOfBoundsException if certain limits are exceeded (e.g., argument number too high, argument name too long, etc.)
NumberFormatException if a number could not be parsed

partSubstringMatches

Added in API level 24
public boolean partSubstringMatches (MessagePattern.Part part, 
                String s)

Compares the part's substring with the input string s.

Parameters
part MessagePattern.Part: a part of this MessagePattern.

s String: a string.

Returns
boolean true if getSubstring(part).equals(s).

toString

Added in API level 24
public String toString ()

Returns a string representation of the object.

Returns
String a string representation of the object.

validateArgumentName

Added in API level 24
public static int validateArgumentName (String name)

Validates and parses an argument name or argument number string. An argument name must be a "pattern identifier", that is, it must contain no Unicode Pattern_Syntax or Pattern_White_Space characters. If it only contains ASCII digits, then it must be a small integer with no leading zero.

Parameters
name String: Input string.

Returns
int >=0 if the name is a valid number, ARG_NAME_NOT_NUMBER (-1) if it is a "pattern identifier" but not all ASCII digits, ARG_NAME_NOT_VALID (-2) if it is neither.